How to Call a Subordinate Agent with the `call_subordinate` Tool in Agent Zero
The call_subordinate tool creates a child agent, forwards a message, executes its monologue, and returns the response while maintaining parent-child hierarchy.
The call_subordinate tool in the agent0ai/agent-zero repository enables hierarchical multi-agent workflows by allowing a parent agent to delegate tasks to a subordinate. This implementation leverages a dedicated Delegation class that handles agent instantiation, message forwarding, and result propagation across the agent hierarchy.
Understanding the call_subordinate Tool Architecture
The delegation system is distributed across three core components that manage the lifecycle of a subordinate agent.
Core Components
| Component | Role | Source File |
|---|---|---|
Delegation tool |
Concrete implementation of call_subordinate that creates or recreates subordinate agents, forwards messages, executes monologues, and returns results. |
python/tools/call_subordinate.py |
Agent class |
Central execution engine storing hierarchical relationships (_superior / _subordinate), providing hist_add_user_message, monologue, and _process_chain for result propagation. |
agent.py |
Tool base class |
Abstract base defining the execute contract, progress handling, and logging infrastructure. |
python/helpers/tool.py |
Hierarchical Data Storage
Each Agent instance maintains parent-child relationships through its data dictionary using reserved keys:
Agent.DATA_NAME_SUPERIOR("_superior"): References the parent agentAgent.DATA_NAME_SUBORDINATE("_subordinate"): References the child agent
These constants are defined in agent.py and enable the framework to traverse the agent hierarchy during result propagation.
How call_subordinate Works Step by Step
The Delegation.execute method in python/tools/call_subordinate.py follows a strict sequence to delegate tasks and retrieve results.
Step 1: Creating or Resetting the Subordinate Agent
The tool first checks for an existing subordinate or respects a reset request:
if (
self.agent.get_data(Agent.DATA_NAME_SUBORDINATE) is None
or str(reset).lower().strip() == "true"
):
config = initialize_agent() # Default configuration from initialize.py
# Optional profile override
agent_profile = kwargs.get("profile", kwargs.get("agent_profile", ""))
if agent_profile:
config.profile = agent_profile
# Instantiate child agent with sequential numbering
sub = Agent(self.agent.number + 1, config, self.agent.context)
# Establish bidirectional hierarchy
sub.set_data(Agent.DATA_NAME_SUPERIOR, self.agent)
self.agent.set_data(Agent.DATA_NAME_SUBORDINATE, sub)
The child agent receives the same AgentContext as its parent to ensure shared logging, memory, and services remain coherent across the hierarchy.
Step 2: Sending Messages to the Child Agent
Once the subordinate exists, the tool forwards the user message:
subordinate: Agent = self.agent.get_data(Agent.DATA_NAME_SUBORDINATE)
subordinate.hist_add_user_message(
UserMessage(message=message, attachments=[])
)
The UserMessage class (defined in agent.py) encapsulates the message content and any attachments, storing the turn in the child's conversation history.
Step 3: Executing the Subordinate Monologue
The tool triggers the child's autonomous reasoning loop:
result = await subordinate.monologue()
The Agent.monologue() method executes the full message loop, allowing the subordinate to utilize its own tools, reasoning steps, and external integrations independently of the parent.
Step 4: Sealing the Topic and Returning Results
After the monologue completes, the child's current topic is sealed to enable memory management:
subordinate.history.new_topic()
The tool then constructs the response, adding hints for large outputs:
additional = None
if len(result) >= save_tool_call_file.LEN_MIN:
hint = self.agent.read_prompt("fw.hint.call_sub.md")
if hint:
additional = {"hint": hint}
return Response(message=result, break_loop=False, additional=additional)
The Response object signals success to the framework, with break_loop=False indicating the parent agent should continue its own processing.
Step 5: Propagating Results Up the Hierarchy
The Agent._process_chain method handles recursive result propagation:
msg_template = (
agent.hist_add_user_message(msg) if user
else agent.hist_add_tool_result(
tool_name="call_subordinate", tool_result=msg
)
)
response = await agent.monologue()
superior = agent.data.get(Agent.DATA_NAME_SUPERIOR, None)
if superior:
response = await self._process_chain(superior, response, False)
This recursive mechanism ensures that in multi-level hierarchies (A → B → C), the final response bubbles back to the original requester.
Practical Code Examples for Calling Subordinates
Direct Tool Invocation (Developer API)
To programmatically delegate tasks from a parent agent:
from agent import Agent, initialize_agent
from python.tools.call_subordinate import Delegation
# Initialize the main agent
main_cfg = initialize_agent()
main_agent = Agent(0, main_cfg, None)
# Instantiate the delegation tool
tool = Delegation(
agent=main_agent,
name="call_subordinate",
method=None,
args={},
message="", # Will be set during execution
loop_data=None,
)
# Execute delegation
response = await tool.execute(message="Summarize the latest news about AI.")
print("Subordinate replied:", response.message)
Automatic Delegation in Chat Sessions
In conversational workflows, the LLM automatically invokes call_subordinate when task decomposition is required:
User: "Please draft a short blog post about quantum computing."
LLM (internal thought): "I need a specialized agent to research the topic."
→ Invokes call_subordinate tool
(Subordinate agent executes research and drafting monologue)
LLM (receives result): "Here is your draft: ..."
Resetting a Subordinate Agent
To clear a subordinate's memory and start fresh, pass the reset parameter:
# Force creation of a new subordinate instance
response = await tool.execute(
message="Explain blockchain basics.",
reset="true"
)
Key Source Files and Implementation Details
| File | Purpose | Key Elements |
|---|---|---|
python/tools/call_subordinate.py |
Delegation tool implementation | Delegation class, execute() method, subordinate lifecycle management |
agent.py |
Core agent logic | Agent class, DATA_NAME_SUPERIOR, DATA_NAME_SUBORDINATE, monologue(), _process_chain(), hist_add_user_message() |
python/helpers/tool.py |
Tool infrastructure | Tool base class, Response class, execution contract |
initialize.py |
Agent initialization | initialize_agent() function, AgentConfig setup |
python/extensions/hist_add_tool_result/_90_save_tool_call_file.py |
Large response handling | LEN_MIN constant, file saving logic for tool outputs |
Summary
- The
call_subordinatetool enables hierarchical multi-agent delegation through theDelegationclass inpython/tools/call_subordinate.py. - Subordinate agents are stored using reserved keys
_superiorand_subordinatein the parent agent'sdatadictionary. - The tool automatically handles agent instantiation, message forwarding via
hist_add_user_message, and execution viamonologue(). - Results propagate upward through the recursive
_process_chainmethod, supporting complex agent chains (A → B → C). - Large responses trigger automatic hint generation based on the
LEN_MINthreshold defined in the save tool call file extension.
Frequently Asked Questions
What is the difference between a superior and subordinate agent?
A superior agent is the parent that initiates delegation, while a subordinate is the child agent created to handle specific tasks. The superior stores a reference to the subordinate using the _subordinate key in its data dictionary, and the subordinate maintains a back-reference to its superior via the _superior key. This bidirectional linking enables result propagation and hierarchical chain management.
How does call_subordinate handle long responses?
When a subordinate's response exceeds the LEN_MIN threshold defined in python/extensions/hist_add_tool_result/_90_save_tool_call_file.py, the tool automatically generates a hint by reading the fw.hint.call_sub.md prompt file. This hint is attached to the Response object as additional metadata, informing the parent agent that the output has been saved to a file and can be accessed there rather than displayed inline.
Can I chain multiple subordinate calls?
Yes, the architecture supports deep hierarchical chains through the _process_chain method in agent.py. When agent A calls agent B, which then calls agent C, the final result propagates back through each level via recursive calls to _process_chain. Each agent in the chain receives the result as a tool result message (via hist_add_tool_result) rather than a user message, maintaining proper conversation context throughout the hierarchy.
How do I reset a subordinate's memory?
Pass the reset="true" parameter when invoking the tool to force creation of a new subordinate instance. This clears the existing _subordinate reference from the parent agent's data dictionary and instantiates a fresh Agent object with the same configuration but empty history. Use this when you need to clear context from previous delegations or start a new task with a clean slate.
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 →