How delegate_tool Enables Subagent Spawning and Iteration Budget Sharing in Hermes Agent
The delegate_tool spawns isolated subagents by instantiating new AIAgent instances with a shared reference to the parent's IterationBudget object, enforcing a maximum delegation depth of 2 while blocking recursive delegation capabilities.
The delegate_tool is the core mechanism in NousResearch/hermes-agent that enables hierarchical task decomposition through controlled subagent spawning. By leveraging a shared iteration budget and strict depth limits implemented in tools/delegate_tool.py, the tool allows parent agents to delegate work to isolated child agents while maintaining global resource constraints across the entire delegation tree.
Understanding the delegate_tool Architecture
Tool Registration and Schema Definition
The delegation capability begins with explicit schema definition and registry integration. In tools/delegate_tool.py, the OpenAI function-calling schema DELEGATE_TASK_SCHEMA is defined at lines 560-580, specifying parameters for goal, tasks, context, and toolsets. The tool is registered with the central registry at lines 552-566 in tools/registry.py, making it available for LLM invocation.
Subagent Spawning Workflow
When the LLM invokes delegate_task, the execution follows a strict validation and instantiation pipeline:
-
Depth Validation: The function checks the parent's
_delegate_depthagainstMAX_DEPTH = 2(defined at line 40), rejecting attempts to spawn grandchildren (lines 315-322). -
Input Normalization: The tool converts either a single
goalstring or atasksarray into an internaltask_list, enforcing a maximum of 3 concurrent children viaMAX_CONCURRENT_CHILDREN(lines 329-344). -
Execution Mode Selection: For single tasks, the system calls
_run_single_childdirectly. For batches, it creates aThreadPoolExecutorand schedules_run_single_childfor each task (lines 452-492). -
Child Instantiation: Inside
_run_single_child(lines 201-226), a newAIAgentis created with critical subagent parameters:ephemeral_system_prompt: A focused prompt built via_build_child_system_promptenabled_toolsets: Parent's tools filtered through_strip_blocked_toolsiteration_budget=shared_budget: Shares the parent's mutable budget object (lines 199-200)tool_progress_callback=child_progress_cb: Forwards progress to the parent UI (lines 224-225)
How delegate_tool Shares the Iteration Budget
The iteration budget sharing mechanism relies on object reference mutability rather than value copying. When delegate_task prepares to spawn a child, it creates shared_budget as a direct reference to parent_agent.iteration_budget (lines 197-200 in tools/delegate_tool.py).
This IterationBudget object, defined in agent/context_compressor.py, is mutable. When passed to the child agent constructor as iteration_budget=shared_budget, every tool call made by the child decrements the same counter instance. This guarantees a global iteration limit across the entire delegation tree, preventing subagents from exhausting resources independently of the parent.
Safety Mechanisms and Depth Limits
Hermes Agent implements strict guardrails to prevent unbounded recursion and capability escalation:
Depth Enforcement: The constant MAX_DEPTH = 2 (line 40 in tools/delegate_tool.py) creates a hard limit: parent agents may spawn children, but those children cannot spawn grandchildren. The current depth is tracked in child._delegate_depth (lines 228-229).
Tool Blocking: The DELEGATE_BLOCKED_TOOLS list (lines 30-37) removes dangerous capabilities from subagents, including:
delegate_task(prevents recursive delegation)clarify,memory(prevents memory pollution)send_message(prevents unauthorized messaging)execute_code(prevents arbitrary code execution by less trusted subagents)
Each child receives a fresh conversation history and a restricted toolset via _strip_blocked_tools, ensuring isolation between parent and child contexts.
Practical Examples
Single Task Delegation
When the LLM needs focused research, it can spawn a single subagent with specific toolsets:
from hermes_agent.tools.delegate_tool import delegate_task
# Parent AIAgent instance `agent` is already initialized
payload = delegate_task(
goal="Research Python 3.12 release notes and summarize breaking changes",
context="Focus on syntax changes and performance improvements",
toolsets=["web", "file"],
parent_agent=agent,
max_iterations=30
)
print(payload) # Returns JSON with final_response
The subagent receives the ephemeral system prompt, shares the parent's iteration budget, and returns only the final result to the parent conversation.
Batch Delegation with Parallel Subagents
For independent tasks, the tool supports parallel execution via ThreadPoolExecutor:
tasks = [
{"goal": "Check OpenSSL security advisories", "toolsets": ["web"]},
{"goal": "Run unit tests and report failures", "toolsets": ["terminal"]},
{"goal": "Summarize repository README", "toolsets": ["file"]}
]
result_json = delegate_task(
tasks=tasks,
parent_agent=agent
)
This spawns up to three concurrent children (MAX_CONCURRENT_CHILDREN = 3), each with isolated conversation history. The parent aggregates results into a sorted JSON array, with real-time progress displayed via the CLI spinner callback.
Summary
- The
delegate_toolenables hierarchical task decomposition in Hermes Agent through controlled subagent spawning via theAIAgentclass. - Key implementation files include
tools/delegate_tool.pyfor the core logic,run_agent.pyfor agent instantiation, andagent/context_compressor.pyfor budget tracking. - Iteration budget sharing uses a mutable
IterationBudgetobject reference, ensuring global limits across the entire delegation tree. - Safety is enforced through
MAX_DEPTH = 2,DELEGATE_BLOCKED_TOOLS, and isolated conversation contexts for each child. - The tool supports both single-task delegation and parallel batch processing with up to three concurrent subagents.
Frequently Asked Questions
What is the maximum delegation depth in Hermes Agent?
The maximum delegation depth is strictly enforced at 2 levels by the MAX_DEPTH = 2 constant defined in tools/delegate_tool.py. This architecture allows a parent agent to spawn child subagents, but prevents those children from spawning grandchildren, effectively eliminating risks of unbounded recursion or exponential agent proliferation.
How does the iteration budget work across parent and child agents?
The iteration budget operates through shared object mutability rather than value copying. When delegate_task creates a subagent, it passes parent_agent.iteration_budget as the iteration_budget parameter (lines 197-200). Because IterationBudget (defined in agent/context_compressor.py) is a mutable object, every tool call made by any agent in the delegation tree decrements the same counter, enforcing a global limit across all agents.
Which tools are blocked from subagents and why?
The DELEGATE_BLOCKED_TOOLS list in tools/delegate_tool.py (lines 30-37) explicitly removes delegate_task, clarify, memory, send_message, and execute_code from child agents. This prevents recursive delegation loops, memory pollution across agent boundaries, unauthorized external messaging, and arbitrary code execution by potentially less trusted subagents, maintaining security and isolation between parent and child contexts.
Can delegate_tool run multiple subagents in parallel?
Yes, the tool supports parallel execution when the tasks parameter contains multiple goals. It utilizes a ThreadPoolExecutor to spawn up to MAX_CONCURRENT_CHILDREN = 3 subagents simultaneously (as implemented in lines 452-492 of tools/delegate_tool.py). Each child runs in its own thread with isolated conversation history, and the parent aggregates all results into a sorted JSON array upon completion.
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 →