Neuron AI
GitHubForumNewsletter
  • Getting Started
    • Introduction
  • Key Concepts
  • Installation
  • Agent
  • Tools & Function Calls
  • Streaming
  • RAG
  • Attachments (Documents & Images)
  • Advanced
    • Structured Output
    • Logging & Observability
    • MCP Connector
    • Error Handling
  • Post Processor
  • Components
    • AI provider
    • Chat History & Memory
    • Embeddings Provider
    • Vector Store
    • Data loader
  • Examples
    • YouTube Agent
Powered by GitBook
On this page
  • Implement Custom Tools
  • Monitoring
  • Define Tool Properties
  • ToolProperty
  • ArrayProperty
  • ObjectProperty
  • Available Tools
  • MySQL
  • Tavily
  • Jina
  • Zep Memory

Tools & Function Calls

Give Agents the ability to interact with your application context and services.

PreviousAgentNextStreaming

Last updated 2 days ago

Tools enable Agents to go beyond generating text by facilitating interaction with your application services, or external APIs.

Think about Tools as special functions that your AI agent can use when it needs to perform specific tasks. They let you extend your Agent's capabilities by giving it access to specific functions it can call inside your code.

In the example we can define a tool to make the Agent able to retrieve the YouTube video transcription, so it can crteate a short summary:

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\SystemPrompt;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\Anthropic\Anthropic;
use NeuronAI\Tools\PropertyType;
use NeuronAI\Tools\Tool;
use NeuronAI\Tools\ToolProperty;

class YouTubeAgent extends Agent
{
    protected function provider(): AIProviderInterface
    {
        // return an AI provider instance (Anthropic, OpenAI, Ollama, Gemini, etc.)
        return new Anthropic(
            key: 'ANTHROPIC_API_KEY',
            model: 'ANTHROPIC_MODEL',
        );
    }
    
    public function instructions(): string 
    {
        return new SystemPrompt(
            background: ["You are an AI Agent specialized in writing YouTube video summaries."],
            steps: [
                "Get the url of a YouTube video, or ask the user to provide one.",
                "Use the tools you have available to retrieve the transcription of the video.",
                "Write the summary.",
            ],
            output: [
                "Write a summary in a paragraph without using lists. Use just fluent text.",
                "After the summary add a list of three sentences as the three most important take away from the video.",
            ]
        );
    }
    
    protected function tools(): array
    {
        return [
            Tool::make(
                'get_transcription',
                'Retrieve the transcription of a youtube video.',
            )->addProperty(
                new ToolProperty(
                    name: 'video_url',
                    type: PropertyType::STRING
                    description: 'The URL of the YouTube video.',
                    required: true
                )
            )->setCallable(function (string $video_url) {
                return "Video transcripton...";
            })
        ];
    }
}

Let’s break down the code.

We introduced the new method tools() into the Agent class. This method expects to return an array of Tool objects that the AI will be able to use if needed.

In this example we return an array of just one tool, named get_transcription.

Notice that the ToolProperty we define should match with the signature of the function you use as a callable. The callable gets the $video_url arguments, and the name of the property is exactly "video_url".

The most important thing are the name and description you give to the tool and its properties. All these pieces of information will be passed to the LLM in natural language. The more explicit and clear you are, the more likely the LLM understands when, if, and why, it’s the case to use the tool.

Once the Agent decides to use a tool the callable function is executed. Here we can implement the logic to retrieve the video transcription and return the information back to the LLM.

Neuron provides you with these clear and simple APIs and automates all the underlying interactions with the LLM. Once you get the point it can immediately open to a possibility to connect basically everything you want to the Agent. Being able to execute local functions allows you to invoke any external APIs or application components.

Implement Custom Tools

Thanks to the NeuronAI modular architecture, Tools are just a component of the toolkit that rely on the ToolInterface interface. You are free to create pre-packaged tool classes that implements common functionalities, and release them as external composer packages or submit a PR to our repository to have them integrated into the core framework.

To create a new Tool you can extend the NeuronAI\Tools\Tool class.

<?php

namespace App\Neuron\Tools;

use GuzzleHttp\Client;
use NeuronAI\Tools\PropertyType;
use NeuronAI\Tools\Tool;
use NeuronAI\Tools\ToolProperty;

class GetTranscriptionTool extends Tool
{
    protected Client $client;
    
    public function __construct(protected string $key)
    {
        parent::__construct(
            'get_transcription',
            'Retrieve the transcription of a youtube video.',
        );
    
        $this->addProperty(
            new ToolProperty(
                name: 'video_url',
                type: PropertyType::STRING,
                description: 'The URL of the YouTube video.',
                required: true
            )
        )->setCallable($this); // <-- Look at the __invoke method below
        
        $this->client = new Client([
            'base_uri' => 'https://api.supadata.ai/v1/youtube/',
            'headers' => [
                'x-api-key' => $this->key,
            ]
        ]);
    }
    
    /**
     * Implementing the __invoke magic mathod you make this class callable.
     */
    public function __invoke(string $video_url)
    {
        $response = $this->client->get('transcript?url=' . $video_url.'&text=true');

        if ($response->getStatusCode() !== 200) {
            return "Transcription APIs error: {$response->getBody()->getContents()}";
        }

        $response = json_decode($response->getBody()->getContents(), true);

        return $response['content'];
    }
}

You can attach the tool in the agent class as usual:

<?php

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Providers\AIProviderInterface;
use NeuronAI\Providers\Anthropic\Anthropic;
use NeuronAI\SystemPrompt;
use App\Neuron\Tools\MyCustomTool;

class YouTubeAgent extends Agent
{
    public function provider(): AIProviderInterface
    {
        // return an AI provider instance (Gemini, OpenAI, Ollama, etc.)
        return new Anthropic(
            key: 'ANTHROPIC_API_KEY',
            model: 'ANTHROPIC_MODEL',
        );
    }
    
    public function instructions() 
    {
        return new SystemPrompt(...);
    }
    
    public function tools(): array
    {
        return [
            GetTranscriptionTool::make(key: 'API_KEY'),
        ];
    }
}

Transcriptions are just an example. You can eventually implement other tools to make the Agent able to retrieve other video metadata to enhance its video analysis capabilities.

Finally you can talk to the agent asking the summary of a YouTube video.

use NeuronAI\Chat\Messages\UserMessage;
use NeuronAI\Observability\AgentMonitoring;

// The Inspector instance in your application - https://inspector.dev/
$inspector = new \Inspector\Inspector(
    new \Inspector\Configuration('INSPECTOR_INGESTION_KEY')
);

$response = YouTubeAgent::make($user)
    ->observe(new AgentMonitoring($inspector))
    ->chat(
        new UserMessage('What about this video: https://www.youtube.com/watch?v=WmVLcj-XKnM')
    );
    
echo $response->getContent();

/**

Based on the transcription, I'll provide a summary of this powerful environmental 
message from "Mother Nature":
This video presents ...

Three most important takeaways:

1. Nature has existed ...

2. The wellbeing of humanity is ...

3. How humans choose to act toward Nature determines ...

*/

Monitoring

When you provide the Agent with tools, Neuron sends their information to the LLM along with the user message.

Once the LLM reads the prompt and the information of the tools attached, it will decide if some tool can help to gather additional information to respond to the user prompt. In that case it will return a special response that contains the tools the LLM wants to call.

Neuron automatically manages this response for you, executing the callable of the tools the LLM decided to call, and return the result back to the LLM to get its final response.

In the image below you can see all the details about the execution of the tool to retrieve the transcription of the video:

Define Tool Properties

Neuron allows you to define the format of the data you want to receive into the tool function. You can nest these objects inside each other to define complex data structures.

Be careful when defining complex data structures. Even the more advanced models can make mistakes with just a couple of properties. We strongly recommend to keep the input properties of your tools as simple as possible to improve the reliability of your agent execution.

ToolProperty

This class represent a simple scalar value like string, int, or boolean.

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\PropertyType;
use NeuronAI\Tools\Tool;
use NeuronAI\Tools\ToolProperty;

class MyAgent extends Agent
{
    ...
	
    public function tools(): array
    {
        return [
            Tool::make(
                'tool_name',
                'Provide a description.',
            )->addProperty(
                new ToolProperty(
                    name: 'arg',
                    type: PropertyType::STRING,
                    description: 'Describe the value you expect',
                    required: true
                )
            )->setCallable(...)
        ];
    }
}

ArrayProperty

Neuron allows you to instruct the LLM to provide complex data structures as input parameters of the tool function. ArrayProperty allows you to require a list of items with specific characteristics.

In the example below we require an array of string.

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\PropertyType;
use NeuronAI\Tools\Tool;
use NeuronAI\Tools\ToolProperty;

class MyAgent extends Agent
{
    ...
	
    public function tools(): array
    {
        return [
            Tool::make(
                'tool_name',
                'Provide a description.',
            )->addProperty(
                new ArrayProperty(
                    name: 'prop_array',
                    description: 'Describe the value you expect',
                    required: true,
                    items: [
                        new ToolProperty(
                            name: 'simple_prop',
                            type: PropertyType::STRING,
                            description: 'Describe the value you expect',
                            required: true
                        )
                    ]
                )
            )->setCallable(function (array $prop_array) {
                /*
                [
                    'simple_prop' => 'value'
                ]
                */
            })
        ];
    }
}

ObjectProperty

In the same way you can define the object data structure:

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\PropertyType;
use NeuronAI\Tools\Tool;
use NeuronAI\Tools\ToolProperty;

class MyAgent extends Agent
{
    ...
	
    public function tools(): array
    {
        return [
            Tool::make(
                'tool_name',
                'Provide a description.',
            )->addProperty(
                new ObjectProperty(
                    name: 'prop_object',
                    description: 'Describe the value you expect',
                    required: true,
                    properties: [
                        new ToolProperty(
                            name: 'simple_prop',
                            type: PropertyType::STRING,
                            description: 'Describe the value you expect',
                            required: true
                        )
                    ]
                )
            )->setCallable(function (array $prop_object) {
                /*
                [
                    ['simple_prop' => 'value']
                ]
                */
            })
        ];
    }
}

Available Tools

Neuron ships with several built-in tools that allows you to quickly equip your agents with many skills. You can use these tools individually or attach entire toolkits with a single line of code.

MySQL

The MySQL toolkit makes your agent able to interact with your database. If you ask "How many votes did the authors get in the last 14 days?", the agent doesn’t guess or hallucinate an answer. Instead, it recognizes that this question requires database access, identifies the appropriate tables involved and retrieves real data from your system.

The PDO instance is basically a connection to a specific database, so you could aslo think to create dedicated credentials for your agent. It could be helpful to control the level of access your agent has to the database.

Anyway you have separate tools for reading and writing to the database. If you are not confident about your agent behaviour you may not provide the writing tool.

<?php

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\MySQL\MySQLToolkit;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            ...MySQLToolkit::make(
                new \PDO("mysql:host=localhost;dbname=$dbname;charset=utf8mb4", $dbuser, $dbpass),
            )->tools(),
        ];
    }
}

MySQL Schema

This tool allows agents to understand the structure of your database, enabling them to construct intelligent queries without requiring you to hardcode table structures or relationships into prompts. This tool essentially gives your agent the equivalent of a database administrator’s understanding of your schema, allowing it to craft queries that respect your data model and take advantage of existing indexes and relationships.

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\MySQL\MySQLSchemaTool;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            MySQLSchemaTool::make(new \PDO(...)),
        ];
    }
}

This tool also accept a second argument $tables. You can basically pass a list of tables that you want to include in the schema information passed to the LLM. This is basically a way to limit the scope of the queries the agent will later execute on the database.

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\MySQL\MySQLSchemaTool;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            MySQLSchemaTool::make(
                new \PDO(...),
                ['users', 'categories', 'articles', 'tags']
            ),
        ];
    }
}

By limiting the schema scope, you can create specialized agents that focus on specific areas of your application. A content management agent might only need access to articles, categories, and tags, while a user administration agent requires visibility into users, roles, and permissions tables. This approach not only improves performance but also reduces the cognitive load on the language model, leading to more accurate and focused responses.

MySQL Select

Use this tool to make your agent able to run SELECT query against the database.

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\MySQL\MySQLSchemaTool;
use NeuronAI\Tools\Toolkits\MySQL\MySQLSelectTool;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            MySQLSchemaTool::make(new \PDO(...)),
            MySQLSelectTool::make(new \PDO(...)),
        ];
    }
}

MySQL Write

Use this tool to make your agent able to performs write operations against the database (INSERT, UPDATE, DELETE).

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\MySQL\MySQLSchemaTool;
use NeuronAI\Tools\Toolkits\MySQL\MySQLWriteTool;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            MySQLSchemaTool::make(new \PDO(...)),
            MySQLWriteTool::make(new \PDO(...)),
        ];
    }
}

Tavily

This toolkit enable your agent to performs web search, and read the content of a specific URL.

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\Tavily\TavilyToolkit;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            ...TavilyToolkit::make(
                key: 'TAVILY_API_KEY'
            )->tools(),
        ];
    }
}

Tavily Web Search

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\Tavily\TavilySearchTool;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            TavilySearchTool::make(
                key: 'TAVILY_API_KEY'
            ),
        ];
    }
}

You can customize the default options to retrieve search results by passing your preference in the withOptions method:

TavilySearchTool::make(
    key: 'TAVILY_API_KEY'
)->withOptions([
    'days' => 30,
    'max_results' => 10,
]),

Tavily Extract

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\Tavily\TavilyExtractTool;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            TavilyExtractTool::make(
                key: 'TAVILY_API_KEY'
            ),
        ];
    }
}

Jina

This toolkit enable your agent to performs web search, and read the content of a specific URL.

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\Jina\JinaToolkit;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            ...JinaToolkit::make(
                key: 'JINA_API_KEY'
            )->tools(),
        ];
    }
}

Jina Web Search

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\Jina\JinaWebSearch;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            JinaWebSearch::make(
                key: 'JINA_API_KEY'
            ),
        ];
    }
}

Jina URL Reader

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\Jina\JinaUrlReader;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            JinaUrlReader::make(
                key: 'JINA_API_KEY'
            ),
        ];
    }
}

Zep Memory

namespace App\Neuron;

use NeuronAI\Agent;
use NeuronAI\Tools\Toolkits\Zep\ZepLongTermMemoryToolkit;

class MyAgent extends Agent
{
    ...
    
    protected function tools(): array
    {
        return [
            ...ZepLongTermMemoryToolkit::make(
                key: 'ZEP_API_KEY',
                user_id: 'ID'
            )->tools(),
        ];
    }
}

The user_id arguments allows you to separate the long term memory in different silos if you want to serve multiple users. Based on your use case you can use this parameter as a "key" to separate the memory for the various entities the agent interact to (users, companies, etc.).

Notice how the __invoke() method accepts the same arguments defined by the ToolProperty . In this example I'm using an external service to retrieve the YouTube video transcription called .

To watch inside this workflow you should to the Inspector monitoring dashboard in order to see the tool call execution flow in real-time.

All the tools in the MySQL toolkit require a instance as a constructor argument. If you are in a framework environment or you are already using an ORM in general, you can gather the underlying PDO instance from the ORM and pass it to the tools. You can learn more about this implementation strategy in this in-depth article:

It makes your Agent able to search the web. It requires access to .

Extract web page content from an URL. It requires access to .

It makes your Agent able to search the web. It requires access to .

Extract web page content from an URL. It requires access to .

This toolkit connects a NeuronAI Agent to knowledge graph. This kind of system allows the agent to store relevant facts that may emerge during interactions with the agent over time. It's a long term memory in the sense that is not limited to the current conversation like the component does. It's an external persistent storage the agent will use to store and retrieve single pieces of information that can allow more personalized answers.

To learn more about the capabilities of these kind of system you can visit the Zep website:

YouTubeAgent
Supadata.ai
connect your Agent
PDO
https://inspector.dev/mysql-ai-toolkit-bringing-intelligence-to-your-database-layer-in-php/
Tavily APIs
Tavily APIs
Jina API
Jina API
Zep
ChatHistory
https://www.getzep.com/