Converting Agents to Tools Using AgentTool for Agent Composition
AgentTool wraps any AutoGen BaseChatAgent as an invokable tool, enabling hierarchical multi-agent orchestration where master agents delegate tasks to specialist agents through standard function calling.
The microsoft/autogen repository provides the AgentTool class to convert standalone agents into composable tools. This pattern allows a "master" agent to invoke specialist agents—such as domain-specific experts—using standard tool-call semantics, creating modular workflows without rewriting orchestration logic.
How AgentTool Enables Agent Composition
AgentTool inherits from TaskRunnerTool and serves as a bridge between AutoGen's agent architecture and its tool-calling infrastructure. When you wrap an agent with AgentTool, the agent becomes a callable function that other agents can invoke during their reasoning process.
The implementation resides in python/packages/autogen-agentchat/src/autogen_agentchat/tools/_agent.py. At initialization, AgentTool.__init__ accepts an agent instance (typically AssistantAgent or any BaseChatAgent subclass) and stores it as the internal task runner. The class definition spans lines 20-36 in this file, where it configures the tool name and description based on the wrapped agent's properties.
Architecture and Components
The agent-to-tool conversion relies on several coordinated components:
AgentToolConfig — A Pydantic model defined in _agent.py (lines 10-18) that stores the serialized agent component and the return_value_as_last_message flag. This configuration object enables persistent storage of the tool state.
TaskRunnerTool — The abstract base class in _task_runner_tool.py that handles task execution, argument validation, and streaming support. AgentTool delegates its run and run_stream methods to this infrastructure, which forwards calls to the wrapped agent's run method.
Component System — AgentTool implements Component[AgentToolConfig], providing dump_component and load_component methods for serializing the entire tool including the wrapped agent. This enables checkpoint-style workflows where agent states can be saved and restored.
Practical Implementation: Wrapping Specialist Agents
Below is a complete example demonstrating how to convert specialist agents into tools for a master agent to invoke. Note that the master agent must disable parallel tool calls to ensure correct execution order.
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.tools import AgentTool
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
async def main() -> None:
# Initialize model client with parallel_tool_calls disabled (required for AgentTool)
model_client = OpenAIChatCompletionClient(model="gpt-4.1", parallel_tool_calls=False)
# Create specialist agents
math_agent = AssistantAgent(
name="math_expert",
model_client=model_client,
system_message="You are a math expert.",
description="Solves mathematical problems.",
model_client_stream=True,
)
# Convert to tool, returning only the final assistant message
math_tool = AgentTool(agent=math_agent, return_value_as_last_message=True)
chemistry_agent = AssistantAgent(
name="chemistry_expert",
model_client=model_client,
system_message="You are a chemistry expert.",
description="Answers chemistry questions.",
model_client_stream=True,
)
chemistry_tool = AgentTool(agent=chemistry_agent, return_value_as_last_message=True)
# Create master agent with specialist tools
master = AssistantAgent(
name="general_assistant",
system_message="You are a helpful assistant. Use expert tools when needed.",
model_client=model_client,
model_client_stream=True,
tools=[math_tool, chemistry_tool],
max_tool_iterations=5,
)
# Execute tasks - master will automatically invoke appropriate tools
await Console(master.run_stream(task="What is the integral of x^2?"))
await Console(master.run_stream(task="What is the molecular weight of water?"))
asyncio.run(main())
Critical Configuration Requirements
Disable Parallel Tool Calls — When configuring the model client for the master agent, you must set parallel_tool_calls=False. This requirement is enforced by AgentTool's design and documented in the class docstring in _agent.py. Parallel execution can cause race conditions in agent-to-agent delegation.
Return Value Formatting — The return_value_as_last_message parameter controls output formatting. When True, the tool returns only the final assistant message from the wrapped agent. When False, TaskRunnerTool.return_value_as_string concatenates all non-user messages with their source labels (e.g., "assistant: ...").
State Persistence and Serialization
AgentTool supports full state management through its component interface. The save_state_json and load_state_json methods delegate to the underlying wrapped agent, preserving internal memory and conversation context.
The repository's test suite in python/packages/autogen-agentchat/tests/test_task_runner_tool.py validates this functionality across four key scenarios:
test_agent_tool_run— Verifies synchronous execution returns correctTaskResulttest_agent_tool_state— Confirms state saving and loading preserves agent memory (lines 27-42)test_agent_tool_component— Tests JSON serialization viadump_componentandload_component(lines 44-56)test_agent_tool_stream— Validates end-to-end streaming orchestration (lines 58-82)
When to Use AgentTool for Composition
Convert agents to tools when building:
- Domain-specific delegation pipelines — Route mathematical, coding, or scientific queries to specialized expert agents defined in
python/packages/autogen-agentchat/src/autogen_agentchat/agents/assistant_agent.py - Modular agent marketplaces — Swap specialist tools in and out of master agents without modifying orchestration code
- Stateful sub-workflows — Maintain persistent context across multiple tool invocations using the underlying agent's memory
Summary
- AgentTool converts any
BaseChatAgentinto an invokable tool for hierarchical multi-agent systems according to themicrosoft/autogensource code - Located in
python/packages/autogen-agentchat/src/autogen_agentchat/tools/_agent.py, it inherits fromTaskRunnerTooland implementsComponent[AgentToolConfig] - The master agent must use
parallel_tool_calls=Falseto prevent race conditions during tool execution return_value_as_last_messagecontrols whether the tool returns only the final message or the full conversation history- Full serialization support enables persistent agent states through
dump_componentandload_componentmethods
Frequently Asked Questions
Why must parallel tool calls be disabled when using AgentTool?
The master agent must disable parallel tool calls because AgentTool expects sequential execution when delegating to specialist agents. Parallel execution could cause race conditions where multiple tool calls interfere with each other's state or where the master agent receives out-of-order responses. Set parallel_tool_calls=False in your OpenAIChatCompletionClient or equivalent model client configuration.
How does AgentTool handle streaming responses?
AgentTool delegates streaming to the underlying TaskRunnerTool infrastructure, which calls the wrapped agent's run_stream method. When the master agent processes a tool call, it receives intermediate events from the specialist agent in real-time, allowing the UI to display progressive results before the final tool result is returned.
Can I serialize an AgentTool with its wrapped agent state?
Yes. AgentTool implements the Component[AgentToolConfig] interface, providing dump_component and load_component methods that serialize both the tool configuration and the internal agent state. This allows you to save a complete agent-tool composition to JSON and restore it later, including the specialist agent's conversation memory and configuration.
What is the difference between return_value_as_last_message True and False?
When return_value_as_last_message=True, the tool returns only the final assistant message content from the wrapped agent's response. When False, the tool concatenates all non-user messages from the conversation, prefixing each with its source label (e.g., "assistant: ..."), providing full context of the specialist's reasoning process to the master agent.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →