[KongchangAI]
· 3 min read· 1,606 words

Zero-Dependency PHP AI Agent Library NanoAgent: Say Goodbye to Python Microservices

Zero-Dependency PHP AI Agent Library NanoAgent: Say Goodbye to Python Microservices

NanoAgent is a zero-dependency PHP-native AI agent library that lets PHP apps integrate LLM agents without a Python microservice.

The article introduces NanoAgent, a zero-dependency PHP-native library created by developer hammrouni that embeds LLM agent capabilities directly into the PHP process via a single composer install. It supports multiple providers including OpenAI, Groq, Anthropic, and any OpenAI-compatible local endpoint, and its philosophy is to turn existing PHP functions into agent tools. It also supports MCP servers and pluggable memory drivers. The author deliberately keeps the library minimal—no prompt generation, no magic abstractions, no redundant dependencies—arguing that for PHP systems full of legacy business logic, this in-process, auditable approach is often more practical than adding a second runtime.

Why do PHP developers always have to spin up a Python microservice before building an AI Agent?

If you've ever tried to integrate an LLM agent into a PHP application, you've probably hit the same wall: nearly every mature agent library is written in Python. The "obvious" solution then becomes hanging a Python microservice next to your PHP app—it calls your agent, the agent calls your API, and you end up maintaining two runtimes, two deployments, plus an extra network hop for good measure.

Developer hammrouni grew tired of this pattern, so he built NanoAgent—an agent library that runs natively in PHP. A single composer require installs it, with zero runtime dependencies—no Python, no framework, no DSL required.

Screenshot of NanoAgent project release

composer require hammrouni/nanoagent

The sidecar pattern is the general name for the architecture described here: running a separate helper process or service alongside the original application process, with the two communicating over HTTP, gRPC, or a message queue. The concept originates from microservices and the Kubernetes ecosystem (such as Envoy serving as a sidecar in a service mesh), and was later widely adopted for scenarios where "the main app's language isn't great at something, so you bolt on a service that is."

In the AI agent context, the sidecar impulse comes from an ecosystem mismatch: mature frameworks like LangChain, LlamaIndex, and CrewAI are all Python implementations. Hanging a Python agent as a sidecar next to a PHP app can get features off the ground quickly, but the costs are concrete and real—maintaining an extra Python runtime and dependency locks, larger container images, doubled deployment pipelines, an extra cross-process network round-trip on every tool call (adding typically tens of milliseconds of latency), and harder cross-language debugging. NanoAgent's entire design motivation is to eliminate that sidecar link.

What are NanoAgent's core capabilities?

The library's design philosophy can be summed up in one sentence: turn your existing PHP code directly into agent tools.

  • One config, any model provider. Supports OpenAI, Groq, Anthropic, DeepSeekAd, OpenRouter, and any self-hosted endpoint compatible with the OpenAI protocol (Ollama, llama.cpp server). Switching providers is a one-line config change.
  • Tool-first. You can map ordinary PHP functions directly to tools, letting the agent query databases, call internal APIs, and read device telemetry—using code you already wrote long ago.
  • MCP support. You can register any Model Context Protocol server (Streamable HTTP); its tools behave exactly like local tools, with an allowlist controlling which tools get registered.
  • Persistent memory. Conversations can survive across requests via pluggable drivers: JSON files, SQLite, MySQL, PostgreSQL, or a driver you implement yourself.
  • Tiny footprint. One package, no hidden magic, and the official claim that you can audit the entire codebase in under an hour—small by design.

A 30-second getting started example

The code below shows NanoAgent's most basic usage: define an ordinary PHP function as a tool, and the agent decides on its own when to call it.

<?php
use NanoAgent\Agent;

$agent = new Agent(llm: [
    'provider' => 'groq',
    'model'    => 'llama-3.3-70b-versatile',
    'api_key'  => getenv('GROQ_API_KEY'),
    // 'base_url' => 'http://localhost:8080/v1',  // …or a local model server
]);

// Your ordinary PHP function, now a tool:
$agent->tool('weather', fn (string $city) => "It is 22°C in {$city}.");

echo $agent->chat('How warm is it in Marrakech?');

That's it. The agent decides to call the weather tool on its own, your function executes in-process, and once the result comes back the reply is generated. No sidecar, no message queue, no second language.

MCP (Model Context Protocol) is a protocol proposed and open-sourced by Anthropic in late 2024 to let LLM applications connect to external tools and data sources in a unified way. It decouples the "tool provider" (MCP Server) from the "tool consumer" (MCP Client, i.e., the agent host): the Server declares which tools, resources, and prompt templates it exposes, and the Client is responsible for discovering and invoking them.

Common MCP transports include stdio (local subprocess) and Streamable HTTP (remote services). NanoAgent supports the latter, meaning you can plug in any MCP-compliant remote service directly without hand-writing an adapter layer for each integration. The allowlist mechanism serves as a safety valve: a remote Server might expose dozens of tools, so registering only the ones you've vetted prevents the agent from accidentally invoking dangerous operations.

Why PHP? An overlooked reality

The author's argument deserves serious consideration: a great deal of production AI demand isn't greenfield projects. They're Laravel services interfacing with legacy databases, internal HTTP APIs, and a decade's worth of accumulated business logic. In these scenarios, the genuinely useful agent isn't a flashy framework—it's a boring, local library running inside the very process you're already running.

NanoAgent deliberately chooses "boring." In the author's words—"boring is a feature."

This judgment has merit. PHP remains one of the primary languages of web backends, and the WordPress, Laravel, and Symfony ecosystems have accumulated enormous amounts of business code. Asking these teams to introduce a Python stack just to integrate an LLM agent is genuinely a significant engineering decision, not a simple technology choice.

Tool Calling is the underlying mechanism by which this class of agent libraries operates. Mainstream LLM APIs let you attach a list of tools (name, parameter JSON Schema, description of purpose) to a request; the model doesn't actually execute the function but returns a structured call intent, such as {"name": "weather", "arguments": {"city": "Marrakech"}}. The host application parses that intent, executes the corresponding function locally, and sends the result back to the model as a message, from which the model generates its final natural-language reply—a loop that may repeat for multiple rounds.

Precisely because of this, an agent framework is essentially just a "request—parse—execute—return" loop plus a tool registry. It doesn't require special runtime capabilities, and PHP can handle it perfectly well. Understanding this makes clear why NanoAgent dares to make its library so small: what's truly complex is the model itself, while the host-side logic is actually quite straightforward.

Design tradeoffs: what it doesn't do matters more than what it does

NanoAgent draws its boundaries explicitly:

  • No automatic prompt generation. Control over prompt construction stays with the developer.
  • No "magic" abstractions. No hidden call chains, no layer-upon-layer AgentExecutor wrappers.
  • No 14 dependencies. The library's entire dependency tree is empty.

If what you want is a feature-complete framework, there are plenty of excellent choices in the community. But if what you want is a library you can read from cover to cover, that can point at a hosted API or at a model on your own hardware, and that you can ship in an afternoon—that's where NanoAgent positions itself.

What does this tradeoff mean in engineering terms? It means giving up out-of-the-box multi-agent orchestration, sophisticated memory strategies, and a built-in RAG pipeline. In exchange, you get code you fully control and the simplicity of not maintaining an additional runtime in your architecture.

RAG (Retrieval-Augmented Generation) refers to retrieving relevant snippets from a knowledge base first, then stitching them into the prompt for the model to generate an answer, typically requiring the trio of an embedding model, a vector database, and a chunking strategy. Multi-agent orchestration means having multiple specialized agents (planner, executor, reviewer, etc.) collaborate on a task via message passing—frameworks like LangGraph and AutoGen mainly address this class of problem.

Both capabilities are deliberately excluded from NanoAgent—not as capability gaps, but as a scope statement. If your scenario is "look up tickets, call internal APIs, read device data, then answer," a single agent plus a handful of local tools is already sufficient; only when tasks require multi-step planning, self-reflection, or parallel subtasks does it become worth introducing an orchestration layer. Drawing this line clearly can keep teams from burdening themselves with the maintenance overhead of a complex framework for a simple need.

How to get it and get involved

The project is under the MIT license, and issues and PRs are welcome. The author also mentioned that his personal homepage links to a 12-part series on "building agents with PHP," of which this article is just the condensed version.

For teams maintaining a PHP stack who want to add agent capabilities to their applications without introducing a second runtime, NanoAgent offers an option worth evaluating. It won't suit every scenario—especially projects requiring complex multi-agent collaboration—but its three characteristics of "zero dependencies, in-process execution, and full auditability" are very real advantages under certain engineering constraints.

One-line Summary

NanoAgent is a zero-dependency, PHP-native AI agent library that lets PHP apps integrate LLM agents without a Python microservice.

Paragraph Summary

The article introduces NanoAgent, a library built by PHP developer hammrouni that tackles the pain point of being forced to bolt on a Python microservice when integrating LLM agents into PHP. NanoAgent installs with a single composer command and zero runtime dependencies, embedding agent capabilities directly inside the PHP process. It supports OpenAI, Groq, Anthropic, and other providers plus any local endpoint compatible with the OpenAI protocol. Its design philosophy is to "turn your existing PHP code directly into agent tools"—ordinary PHP functions can be registered as tools—and it supports MCP server integration and pluggable memory drivers like JSON, SQLite, and MySQL. The author deliberately keeps the library "boring": no prompt generation, no magic abstractions, no redundant dependencies. The article argues that for Laravel, WordPress, and other systems laden with legacy business logic, this in-process, fully auditable lightweight approach is more engineering-sound than introducing a second runtime—though it's not suited to scenarios requiring complex multi-agent collaboration.

#NanoAgent#PHP AI Agent#zero-dependency PHP library#LLM agent PHP#MCP protocol#Anthropic#OpenAI
Share:

Related articles