# How delegate_tool Enables Subagent Spawning and Iteration Budget Sharing in Hermes Agent

> Learn how the delegate_tool in Hermes Agent spawns subagents and shares iteration budgets. Discover its role in enhancing agent capabilities and managing resources effectively.

- Repository: [Nous Research/hermes-agent](https://github.com/NousResearch/hermes-agent)
- Tags: deep-dive
- Published: 2026-03-09

---

**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`](https://github.com/NousResearch/hermes-agent/blob/main/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`](https://github.com/NousResearch/hermes-agent/blob/main/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`](https://github.com/NousResearch/hermes-agent/blob/main/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:

1. **Depth Validation**: The function checks the parent's `_delegate_depth` against `MAX_DEPTH = 2` (defined at line 40), rejecting attempts to spawn grandchildren (lines 315-322).

2. **Input Normalization**: The tool converts either a single `goal` string or a `tasks` array into an internal `task_list`, enforcing a maximum of 3 concurrent children via `MAX_CONCURRENT_CHILDREN` (lines 329-344).

3. **Execution Mode Selection**: For single tasks, the system calls `_run_single_child` directly. For batches, it creates a `ThreadPoolExecutor` and schedules `_run_single_child` for each task (lines 452-492).

4. **Child Instantiation**: Inside `_run_single_child` (lines 201-226), a new `AIAgent` is created with critical subagent parameters:
   - `ephemeral_system_prompt`: A focused prompt built via `_build_child_system_prompt`
   - `enabled_toolsets`: Parent's tools filtered through `_strip_blocked_tools`
   - `iteration_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`](https://github.com/NousResearch/hermes-agent/blob/main/tools/delegate_tool.py)).

This `IterationBudget` object, defined in [`agent/context_compressor.py`](https://github.com/NousResearch/hermes-agent/blob/main/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`](https://github.com/NousResearch/hermes-agent/blob/main/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:

```python
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`:

```python
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_tool` enables hierarchical task decomposition in Hermes Agent through controlled subagent spawning via the `AIAgent` class.
- Key implementation files include [`tools/delegate_tool.py`](https://github.com/NousResearch/hermes-agent/blob/main/tools/delegate_tool.py) for the core logic, [`run_agent.py`](https://github.com/NousResearch/hermes-agent/blob/main/run_agent.py) for agent instantiation, and [`agent/context_compressor.py`](https://github.com/NousResearch/hermes-agent/blob/main/agent/context_compressor.py) for budget tracking.
- Iteration budget sharing uses a mutable `IterationBudget` object 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`](https://github.com/NousResearch/hermes-agent/blob/main/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`](https://github.com/NousResearch/hermes-agent/blob/main/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`](https://github.com/NousResearch/hermes-agent/blob/main/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`](https://github.com/NousResearch/hermes-agent/blob/main/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.