AI Agents in PHP — the 12-Pattern Cheatsheet
Every pattern from the NanoAgent series, one page: what it does, the core snippet, the full article. Bookmark it, forward it to your team.
Basic Agent
Your first AI agent in PHP — one agent, one tool, one task.
$agent = new Agent(
llm: $llmConfig,
systemPrompt: "You are a helpful PHP technical assistant.",
tools: [$secretTool]
);
Stateful Chat
Conversation history that survives requests, via PHP sessions.
if (!isset($_SESSION['history'])) {
$_SESSION['history'] = [];
}
$agent->setMemory(new FileMemory(__DIR__ . '/memory'), "user-$userId");
Persistent Memory
Chat history that survives restarts — file or database-backed.
use NanoAgent\Memory\PdoMemory;
// SQLite file, created on first use (keep it outside your public web root):
$agent->setMemory(PdoMemory::sqlite(__DIR__ . '/memory/chat.sqlite'), "user-$userId");
Streaming SSE
Stream LLM tokens to the browser with Server-Sent Events.
$agent->stream($userMessage, function ($token) {
echo "data: " . json_encode(['token' => $token]) . "\n\n";
ob_flush();
flush();
});
Structured Output
Extract clean JSON from unstructured model text via a forced tool call.
callable: function (array $args) use (&$extractedData) {
$extractedData = $args;
return "Internal: Profile for {$args['full_name']} captured.";
}
);
Multi-Provider
Switch between Groq, OpenAI, and a Mock provider — same agent code.
$agent = new Agent(
llm: $cfg['llm'], // <-- the ONLY thing that changes
systemPrompt: "You are testing the $name provider. Reply briefly identifying yourself."
);
API Integration
Call a real API (live weather) from an agent in four functions.
$agent = new Agent(
llm: $llmConfig,
systemPrompt: "You are a meteorological assistant. You can retrieve real-time "
. "weather information for any city.",
tools: [$weatherTool]
);
MCP Tools
Connect an agent to a remote MCP tool server in four lines — allowlist the tools to keep the payload small, and listTools() to find the names.
$discovered = $agent->registerMcpServer($mcpClient);
$agent->enableActivityLogging();
$answer = $agent->chat("Repository: facebook/react\nQuestion: What does this repo do?");
// Not sure which names? Ask the server — registers nothing:
foreach ($mcpClient->listTools() as $tool) { echo $tool['name'], "\n"; }
// Register only the tools you need — each one costs a schema on every turn:
$discovered = $agent->registerMcpServer($mcpClient, allowlist: ['ask_question']);
Multi-Agent Chain
Chain a researcher agent into a writer agent — no shared tools.
$research = $researcher->chat("Research the topic: $topic");
// e.g. "1. Created by Rasmus Lerdorf in 1994. 2. Powers over 75% of websites..."
$post = $writer->chat("Write a post based on these facts:\n\n" . $research);
RAG Knowledge Base
Answer from your own docs, not the model's memory.
$agent = new Agent(
llm: $llmConfig,
tools: [$searchTool]
);
$response = $agent->chat("Can I work from Hawaii for two months?");
Stateful Tools
An agent that reads and mutates an inventory — a tool with state.
public function order(string $id, int $qty): string {
if ($this->products[$id]['stock'] < $qty) return "Error: Insufficient stock.";
$this->products[$id]['stock'] -= $qty; // <-- the mutation
return "Success: Ordered $qty of {$this->products[$id]['name']}.";
}
Multi-Tool Orchestration
One agent, many tools, one answer — the model builds the pipeline.
$agent = new Agent(
llm: $llmConfig,
tools: [$locationTool, $weatherTool, $eventTool]
);
$response = $agent->chat(
"Check where I am, get the weather there, and see if there are any jazz events tonight."
);
Ready to ship an agent?
composer require hammrouni/nanoagent
MIT, zero dependencies. Read the full series — each article covers one pattern in depth.