Tool Calling with Agents
Tool calling lets an AI agent invoke your PHP functions to fetch data or trigger actions. In this guide you will create a custom tool, wire it into an agent, and let the LLM decide when to call it — including streaming support.
Prerequisites
- Symfony AI Platform component
- Symfony AI Agent component
Step 1: Install Packages
You need Platform for the LLM connection and Agent for the toolbox and processor pipeline:
1
composer require symfony/ai-platform symfony/ai-agent
Step 2: Create a Tool Class
Annotate a class with the AsTool attribute to
register it. The agent reads the attribute name and description to tell the LLM what the tool
does. Parameter descriptions come from @param docblocks on the __invoke() method:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
namespace App\Tool;
use Symfony\AI\Agent\Toolbox\Attribute\AsTool;
#[AsTool('weather', 'Fetches the current weather for a given city')]
final class WeatherTool
{
/**
* @param string $city The name of the city to look up
* @param string $units "metric" or "imperial"
*/
public function __invoke(string $city, string $units = 'metric'): array
{
// Call a weather API, query a database, etc.
return [
'city' => $city,
'temperature' => '22°C',
'condition' => 'sunny',
];
}
}
Tip
A tool can return more than a string — arrays, objects, scalars, and DateTimeInterface
are converted automatically by the ToolResultConverter,
so you rarely need to json_encode() yourself.
Step 3: Build the Agent
Pass your tool instances into a Toolbox, wrap it in an AgentProcessor, and construct the Agent. The processor acts as both an input and output processor:
1 2 3 4 5 6 7 8 9 10 11 12
use App\Tool\WeatherTool;
use Symfony\AI\Agent\Agent;
use Symfony\AI\Agent\Toolbox\AgentProcessor;
use Symfony\AI\Agent\Toolbox\Toolbox;
use Symfony\AI\Platform\Bridge\OpenAi\Factory;
use Symfony\Component\HttpClient\HttpClient;
$platform = Factory::createPlatform($apiKey, HttpClient::create());
$toolbox = new Toolbox([new WeatherTool()]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, 'gpt-5-mini', [$processor], [$processor]);
Step 4: Let the Agent Call Tools
Send a user message. The agent will automatically discover the available tools, decide whether to call one, execute it, and incorporate the result into its response:
1 2 3 4 5 6 7 8 9 10 11
use Symfony\AI\Platform\Message\Message;
use Symfony\AI\Platform\Message\MessageBag;
$messages = new MessageBag(
Message::ofUser('What is the weather like in Paris right now?'),
);
$result = $agent->call($messages);
echo $result->getContent();
// "The current weather in Paris is 22°C and sunny."
Step 5: Use Built-In Tools
The Agent component ships ready-made tools — Wikipedia, YouTube, SimilaritySearch, Brave, and SerpApi — each as a separate Composer package:
1
$ composer require symfony/ai-wikipedia-tool
Add it to the toolbox alongside your custom tools:
1 2 3 4 5 6
use Symfony\AI\Agent\Bridge\Wikipedia\Wikipedia;
$toolbox = new Toolbox([
new WeatherTool(),
new Wikipedia(HttpClient::create()),
]);
See Symfony AI - Agent Component for the full list of built-in tools and their configuration.
Step 6: Stream with Tool Calling
Enable streaming with 'stream' => true. Tool calls are still handled transparently, and
getContent() yields semantic delta objects — filter them by type. Reasoning models also
emit ThinkingDelta deltas when you pass the reasoning option:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
use Symfony\AI\Platform\Result\Stream\Delta\TextDelta;
use Symfony\AI\Platform\Result\Stream\Delta\ThinkingDelta;
$result = $agent->call($messages, [
'stream' => true,
'reasoning' => ['summary' => 'auto'],
]);
foreach ($result->getContent() as $delta) {
if ($delta instanceof ThinkingDelta) {
echo $delta->getThinking();
}
if ($delta instanceof TextDelta) {
echo $delta;
}
}
Once the stream is drained, token usage is available from the metadata as a TokenUsage object:
1
$usage = $result->getMetadata()->get('token_usage');
See Symfony AI - Platform Component for the full list of delta types.
Learn More
- Symfony AI - Agent Component - Processors, memory, and advanced agent patterns
- Symfony AI - Platform Component - Supported providers and models
- AI Bundle - Auto-wiring tools as Symfony services