AgentTools System
The AgentTools system in the Multi-Agent Orchestrator provides a flexible framework for defining, building, and managing tools that agents can use.
It consists of three main classes: AgentTool
and AgentTools
, which work together to enable tool-based interactions in the orchestrator.
Key Features
- Support for multiple AI provider formats: Claude, Bedrock, OpenAI (coming soon)
- Automatic function signature parsing
- Type hint conversion to JSON schema
- Flexible tool definition methods
- Async/sync function handling
- Built-in tool result formatting
AgentTool Class
The AgentTool
class is the core component that represents a single tool definition. It can be created in multiple ways and supports various formats for different AI providers.
Creating a AgentTool
There are several ways to create a tool:
- Using the Constructor:
// TypeScript implementation coming soon
from multi_agent_orchestrator.utils import AgentTool
def get_weather(location: str, units: str = "celsius") -> str: """Get weather information for a location.
:param location: The city name to get weather for :param units: Temperature units (celsius/fahrenheit) """ return f'It is sunny in {city} with 30 {units}!'
tool = AgentTool( name="weather_tool", description="Get current weather information", properties = { "location": { "type": "string", "description": "The city name to get weather for" }, "units": { "type": "string", "description": "the units of the weather data", } }, func=get_weather, enum_values={"units": ["celsius", "fahrenheit"]})
- Using the docstring:
// TypeScript implementation coming soon
from multi_agent_orchestrator.utils import AgentTool
def get_weather(location: str, units: str = "celsius") -> str: """Get weather information for a location.
:param location: The city name to get weather for :param units: Temperature units (celsius/fahrenheit) """ return f'It is sunny in {city} with 30 {units}!'
tool = AgentTool( name="weather_tool", func=get_weather, enum_values={"units": ["celsius", "fahrenheit"]})
Format Conversion
The AgentTool class can output its definition in different formats for various AI providers:
tool = AgentTool( name="weather_tool", description="Get current weather information", func=get_weather, enum_values={"units": ["celsius", "fahrenheit"]})
# For Claudeclaude_format = tool.to_claude_format()
# For Bedrockbedrock_format = tool.to_bedrock_format()
# For OpenAIopenai_format = tool.to_openai_format()
AgentTools Class
The AgentTools
class manages multiple tool definitions and handles tool execution during agent interactions. It provides a unified interface for tool processing across different AI providers.
Creating and Using AgentTools
from multi_agent_orchestrator.utils import AgentTools, AgentTool
# Define your toolsweather_tool = AgentTool("weather", "Get weather info", get_weather)
# Create AgentTools instancetools = AgentTools([weather_tool])
# Format tool with an agentweather_agent = BedrockLLMAgent(BedrockLLMAgentOptions( name="Weather Agent", streaming=True, description="Specialized agent for giving weather condition from a city.", tool_config={ 'tool': tools, 'toolMaxRecursions': 5, },))
# Use AgentTools class with an agentweather_agent = BedrockLLMAgent(BedrockLLMAgentOptions( name="Weather Agent", streaming=True, description="Specialized agent for giving weather condition from a city.", tool_config={ 'tool': AgentTools([weather_tool]), 'toolMaxRecursions': 5, },))
By using AgentTools, the logic of parsing the tool response from the Agent is hanlded directly by the class.
Using a AgentTool with an Agent
1. Definition
// TypeScript implementation coming soon
from multi_agent_orchestrator.utils import AgentTools, AgentTool
def get_weather(city:str): """ Fetches weather data for the given city using the Open-Meteo API. Returns the weather data or an error message if the request fails.
:param city: The name of the city to get weather for :return: A formatted weather report for the specified city """ return f'It is sunny in {city}!'
# Create a tool definition with name and descriptionweather_tools:AgentTools = AgentTools(tools=[AgentTool( name='get_weather', func=get_weather)])
2. Adding AgentTool to Agent
Here is an example of how you can add AgentTools to your Agent
// TypeScript implementation coming soon
from multi_agent_orchestrator.utils import AgentTools, AgentToolfrom multi_agent_orchestrator.agents import (BedrockLLMAgent, BedrockLLMAgentOptions)
# Configure and create the agent with our weather toolweather_agent = BedrockLLMAgent(BedrockLLMAgentOptions( name='weather-agent', description='Agent specialized in providing weather information for cities', tool_config={ 'tool': weather_tools, 'toolMaxRecursions': 5, # Maximum number of tool calls in one conversation }))
3. Overriding the tool hanlder
When you need more control over tool execution, you can implement a custom handler using the useToolHandler option in your tool_config. This handler lets you:
- Intercept and process the tool invocation before execution
- Parse the tool block directly from your Agent’s output
- Generate and format custom tool responses
// TypeScript implementation coming soon
from multi_agent_orchestrator.utils import AgentTools, AgentToolfrom multi_agent_orchestrator.agents import (BedrockLLMAgent, BedrockLLMAgentOptions)
async def bedrock_weather_tool_handler( response: ConversationMessage, conversation: list[dict[str, Any]]) -> ConversationMessage: """ Handles tool execution requests from the agent and processes the results.
This handler: 1. Extracts tool use requests from the agent's response 2. Executes the requested tools with provided parameters 3. Formats the results for the agent to understand
Parameters: response: The agent's response containing tool use requests conversation: The current conversation history
Returns: A formatted message containing tool execution results """ response_content_blocks = response.content tool_results = []
if not response_content_blocks: raise ValueError("No content blocks in response")
for content_block in response_content_blocks: # Handle regular text content if present if "text" in content_block: continue
# Process tool use requests if "toolUse" in content_block: tool_use_block = content_block["toolUse"] tool_use_name = tool_use_block.get("name")
if tool_use_name == "get_weather": tool_response = get_weather(tool_use_block["input"].get('city')) tool_results.append({ "toolResult": { "toolUseId": tool_use_block["toolUseId"], "content": [{"json": {"result": tool_response}}], } })
return ConversationMessage( role=ParticipantRole.USER.value, content=tool_results )
# Configure and create the agent with our weather toolweather_agent = BedrockLLMAgent(BedrockLLMAgentOptions( name='weather-agent', description='Agent specialized in providing weather information for cities', tool_config={ 'tool': weather_tools.to_bedrock_format(), 'toolMaxRecursions': 5, # Maximum number of tool calls in one conversation 'useToolHandler': bedrock_weather_tool_handler }))
This approach provides flexibility when you need to extend the default tool behavior with custom logic, validation, or response formatting. The handler receives the raw tool block text and is responsible for all aspects of tool execution and response generation.
Best Practices
-
Function Documentation: Always provide clear docstrings for functions used in tools. The system uses these for generating descriptions and parameter documentation.
-
Type Hints: Use Python type hints in your tool functions. These are automatically converted to appropriate JSON schema types.
-
Error Handling: Implement proper error handling in your tool functions. AgentTool execution errors are automatically captured and formatted appropriately.
-
Provider Compatibility: When creating tools, consider the formatting requirements of different AI providers if you plan to use the tools across multiple provider types.
-
AgentTool Naming: Use clear, descriptive names for your tools and maintain consistency in naming conventions across your application.
By following these guidelines and leveraging the AgentTools system effectively, you can create powerful and flexible tool-based interactions in your Multi-Agent Orchestrator implementation.
Next Steps
To continue learning about AgentTools in the Multi-Agent Orchestrator System, head over to our examples in Github