{"slug": "00-nanoagent-your-first-ai-agent-in-php", "title": "00 - NanoAgent: Your First AI Agent in PHP", "summary": "A developer published NanoAgent, a minimal PHP library for building AI agents without leaving the PHP ecosystem. The example shows an agent assembled from four objects — Agent, FunctionTool, Task and a config array — where a JSON Schema-described PHP closure is exposed as a tool and Task::execute() handles the model's tool-call round-trip automatically, defaulting to Groq's free tier with llama-3.3-70b-versatile.", "body_md": "PHP developers get a lot of AI examples - but almost all of them start in Python. If your app is already in PHP (and it usually is), the \"add an agent\" path looks like bolting on a sidecar or learning a framework. It doesn't have to.\n\nThis is the smallest working agent in [NanoAgent](https://hammrouni.github.io/nanoagentphp/): one agent, one custom tool, one task.\n\nAn agent in NanoAgent is just four objects:\n\n`Agent`` FunctionTool``Task`\nLet's build it piece by piece. First, the boilerplate: pull in the autoloader and the three classes you need.\n\n``` php\nrequire_once __DIR__ . '/../NanoAgent/autoloader.php';\n\nuse NanoAgent\\Agent;\nuse NanoAgent\\Task;\nuse NanoAgent\\Tools\\FunctionTool;\n```\n\nRather than hard-code a provider and API key, read them from a `config.php` file if one exists, and fall back to sane defaults (Groq's free tier) if it doesn't. This means the same script runs out of the box for a first-time reader, and switches provider for anyone with their own config.\n\n``` php\n$configFile = __DIR__ . '/../NanoAgent/config.php';\n$config = file_exists($configFile) ? require $configFile : [];\n\n$llmConfig = [\n    'provider' => $config['provider'] ?? 'groq',\n    'model'    => $config['model']    ?? 'llama-3.3-70b-versatile',\n    'api_key'  => $config['api_key']  ?? ''\n];\n```\n\nA `FunctionTool` wraps three things: a **name** the model refers to, a **description** it reads to decide when to use the tool, and a **JSON Schema** describing the arguments. The `callable` is just a normal PHP closure - here it fabricates a \"secret token\" from the input string.\n\n``` php\n$secretTool = new FunctionTool(\n    name: 'generate_secret_token',\n    description: 'Generates a secure token based on input string.',\n    parameters: [\n        'type' => 'object',\n        'properties' => [\n            'input' => ['type' => 'string', 'description' => 'The string to obfuscate']\n        ],\n        'required' => ['input']\n    ],\n    callable: fn(array $args) => \"TOKEN_\" . strtoupper(strrev($args['input'])) . \"_SECURE\"\n);\n```\n\nThe `Agent` ties the LLM config to a system prompt and the list of tools it's allowed to use. Nothing runs yet - this just assembles the pieces.\n\n``` php\n$agent = new Agent(\n    llm: $llmConfig,\n    systemPrompt: \"You are a helpful PHP technical assistant.\",\n    tools: [$secretTool]\n);\n```\n\nA `Task` bundles a goal with any background context you want the model to have (here, just the project name). Calling `execute()` is what actually sends the prompt, lets the model call the tool if it wants to, and returns the final answer.\n\n``` php\n$task = new Task($agent);\n$task->addContext(\"Project\", \"NanoAgent Library\");\n\n$response = $task->execute(\n    \"Generate a secret token for 'NanoAgent' and explain how it was created.\"\n);\n\necho $response;\n```\n\nThe `FunctionTool` is the whole idea. You describe a PHP function with a JSON Schema, and the model decides when to call it and what to pass. `Task::execute()` formats the goal + context into a prompt, and **handles the tool round-trip for you** - when the model asks to call `generate_secret_token`, the agent runs your callable, feeds the result back, and continues. You never wire that loop by hand.\n\nThat's the floor. Once you have an agent that can call tools, everything else is adding more tools or more agents:\n\n*Part of the NanoAgent examples series. [Landing + demos](https://hammrouni.github.io/nanoagentphp/).*", "url": "https://wpnews.pro/news/00-nanoagent-your-first-ai-agent-in-php", "canonical_source": "https://dev.to/hammrouni/00-nanoagent-your-first-ai-agent-in-php-3mo6", "published_at": "2026-09-27 17:54:47+00:00", "updated_at": "2026-09-27 18:31:08.668338+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "large-language-models", "ai-products"], "entities": ["NanoAgent", "PHP", "Groq", "llama-3.3-70b-versatile"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/00-nanoagent-your-first-ai-agent-in-php", "markdown": "https://wpnews.pro/news/00-nanoagent-your-first-ai-agent-in-php.md", "text": "https://wpnews.pro/news/00-nanoagent-your-first-ai-agent-in-php.txt", "jsonld": "https://wpnews.pro/news/00-nanoagent-your-first-ai-agent-in-php.jsonld"}}