📑 Table of contents

    Hermes Agent #14: Task Delegation — Orchestrating Sub-agents

    Hermes Agent 🔴 Advanced ⏱️ 11 min read 📅 2026-05-05

    After exploring cron jobs for recurring automation, let's dive into one of Hermes Agent's most powerful features: task delegation. Through the delegate_task tool, an agent can spawn isolated sub-agents, each with its own context, dedicated terminal, and tools — capable of working in parallel on complex subtasks, then returning a summary to the parent.

    This capability transforms Hermes Agent from a linear executor into a true autonomous agent orchestrator, capable of parallelizing research, multi-file development, code audits, and much more.

    What is delegate_task?

    The delegate_task tool allows the agent to spawn child AIAgent instances. Each sub-agent:

    • Starts with a fresh, isolated conversation — it knows nothing about the parent context
    • Has its own terminal, separate from the parent
    • Gets a restricted toolset defined by the parent
    • Returns only a structured summary of its work

    This isolation model is fundamental: it prevents context pollution and enables safe parallelization.

    Two Delegation Modes

    Single Task Mode (goal)

    The simplest mode: delegate a single task to one sub-agent.

    delegate_task(
      goal="Debug why tests fail",
      context="Error: assertion in test_foo.py line 42",
      toolsets=["terminal", "file"]
    )

    The sub-agent receives a system prompt built from goal and context, executes its mission with its own LLM reasoning loop, then returns a structured summary: what it did, files modified, issues encountered.

    Batch Mode (tasks array)

    For parallelization, pass a tasks array:

    delegate_task(tasks=[
      {
        "goal": "Research topic A",
        "context": "Focus on browser support and tooling",
        "toolsets": ["web"]
      },
      {
        "goal": "Research topic B",
        "context": "Focus on ecosystem maturity",
        "toolsets": ["web"]
      },
      {
        "goal": "Fix the build",
        "context": "TypeError in api/handlers.py line 47",
        "toolsets": ["terminal", "file"]
      }
    ])

    Sub-agents execute in parallel via a ThreadPoolExecutor, up to max_concurrent_children simultaneous agents (3 by default). Results are sorted by index to match input order, regardless of completion order.

    Isolated Context: The Golden Rule

    Sub-agents know nothing about the parent. Zero conversation history, zero prior tool calls. Their only context comes from the goal and context fields provided in the call.

    Common mistake:

    # BAD - the sub-agent has no idea what "the error" is
    delegate_task(goal="Fix the error")

    Best practice:

    # GOOD - all necessary context is provided
    delegate_task(
      goal="Fix the TypeError in api/handlers.py",
      context="The file api/handlers.py has a TypeError on line 47:
      'NoneType' object has no attribute 'get'.
      The function process_request() receives a dict from parse_body(),
      but parse_body() returns None when Content-Type is missing.
      Project at /home/user/myproject, Python 3.11."
    )

    The parent must pass absolutely everything the sub-agent needs: file paths, error messages, technical constraints, stack traces, quality goals.

    Roles: leaf vs orchestrator

    Hermes Agent introduces two sub-agent roles:

    Leaf (default)

    A leaf sub-agent is a terminal executor. It cannot delegate further. It accomplishes its task and returns its summary. This is the default and safest behavior.

    Orchestrator

    An orchestrator sub-agent can spawn its own sub-agents, creating a delegation tree:

    delegate_task(
      goal="Survey three code review approaches and recommend one",
      role="orchestrator",
      context="Compare: GitHub PR reviews, CodeMirror, custom lint rules..."
    )

    The orchestrator child can spawn leaf workers to parallelize its research, then synthesize the results.

    Control Parameters: max_concurrent_children and max_spawn_depth

    Two essential safeguards prevent uncontrolled proliferation:

    • max_concurrent_children (default: 3): maximum sub-agents running simultaneously per batch. Configurable via delegation.max_concurrent_children or DELEGATION_MAX_CONCURRENT_CHILDREN env var. No hard ceiling — floor is 1.
    • max_spawn_depth (default: 1 = flat): maximum delegation tree depth. At 1, only the parent can delegate. At 2, orchestrators can spawn leaves. At 3, three levels (maximum).

    Cost warning: with max_spawn_depth: 3 and max_concurrent_children: 3, the tree can reach 3x3x3 = 27 concurrent leaf agents. Each extra level multiplies spend — raise max_spawn_depth intentionally.

    A global kill switch exists: delegation.orchestrator_enabled: false forces all children to leaf role, regardless of the role parameter.

    Full Configuration

    # ~/.hermes/config.yaml
    delegation:
      max_iterations: 50           # Max turns per child (default: 50)
      max_concurrent_children: 3   # Parallel children per batch (default: 3)
      max_spawn_depth: 1           # Tree depth 1-3 (default: 1 = flat)
      orchestrator_enabled: true   # false = force leaf for all
      child_timeout_seconds: 600   # Idle timeout (default: 600s)
      model: "google/gemini-flash-2.0"  # Optional model for sub-agents
      provider: "openrouter"       # Optional provider
      # base_url: "http://localhost:1234/v1"  # Custom endpoint
      # api_key: "local-key"

    Child Timeout

    Sub-agents are killed if they go silent for more than child_timeout_seconds (600 by default). The timer resets on each API or tool call — only genuinely idle workers trigger the kill. Tune: lower for fast local models, higher for slow reasoning models.

    On timeout with zero API calls (typically: unreachable provider, auth failure, schema rejection), Hermes writes a structured diagnostic to ~/.hermes/logs/subagent-timeout-*.log.

    Model Override

    For simple tasks, delegate to a cheaper, faster model:

    delegation:
      model: "google/gemini-flash-2.0"
      provider: "openrouter"

    If omitted, sub-agents use the same model as the parent.

    Max Iterations

    delegate_task(
      goal="Quick file check",
      context="Check if /etc/nginx/nginx.conf exists",
      max_iterations=10  # Simple task, few turns needed
    )

    Available Tools for Sub-agents

    The toolsets parameter controls accessible tools:

    • ["terminal", "file"] — Code, debugging, builds
    • ["web"] — Research, fact-checking
    • ["terminal", "file", "web"] — Full-stack (default)
    • ["file"] — Read-only analysis
    • ["terminal"] — System administration

    Blocked Tools for Sub-agents

    Certain tools are systematically blocked, regardless of configuration:

    • clarify — sub-agents cannot interact with the user
    • memory — no writes to shared persistent memory
    • send_message — no cross-platform side effects (no Telegram messages, etc.)
    • code_execution — children should reason step-by-step
    • delegate_task — blocked for leafs (default), retained for orchestrators

    These restrictions are fundamental: a sub-agent cannot ask questions, memorize, or send messages to the user. It must be fully autonomous.

    When to Delegate vs Do It Yourself

    Delegate when:

    • The task needs a fresh context to avoid pollution (long parent session)
    • Multiple tasks are independent and parallelizable
    • The task risks flooding the parent context (massive refactoring, long logs)
    • You want to use a different model (faster/cheaper) for a subtask
    • The task requires full reasoning with tool-LLM loop

    Do it yourself when:

    • The task is simple and short (read one file, run one command)
    • Parent context is essential to understanding the task
    • You need to interact with the user during the process
    • The task modifies files the parent also manipulates (conflict risk)
    • The cost of an additional sub-agent isn't justified

    Concrete Examples

    Parallel Research

    Research three topics simultaneously and collect summaries:

    delegate_task(tasks=[
      {
        "goal": "Research the current state of WebAssembly in 2025",
        "context": "Focus on: browser support, non-browser runtimes, language support",
        "toolsets": ["web"]
      },
      {
        "goal": "Research RISC-V adoption in 2025",
        "context": "Focus on: server chips, embedded systems, software ecosystem",
        "toolsets": ["web"]
      },
      {
        "goal": "Research quantum computing progress in 2025",
        "context": "Focus on: error correction, practical applications",
        "toolsets": ["web"]
      }
    ])

    All three sub-agents work in parallel, each with its own terminal and research cycle. The parent receives three structured summaries to synthesize.

    Multi-File Development

    Delegate a massive refactoring that would flood the parent context:

    delegate_task(
      goal="Replace all print() with logging in src/",
      context="Project at /home/user/myproject.
      Use logging.getLogger(__name__).
      - print(f'Error: ...') -> logger.error(...)
      - print(f'Warning: ...') -> logger.warning(...)
      - print(f'Debug: ...') -> logger.debug(...)
      - Other prints -> logger.info(...)
      Don't change test files or CLI output.
      Run pytest after to verify.",
      toolsets=["terminal", "file"]
    )

    Security Audit with Fixes

    delegate_task(
      goal="Audit the authentication module and fix vulnerabilities",
      context="Project at /home/user/webapp.
      Auth files: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py
      Stack: Flask, PyJWT, bcrypt.
      Focus: SQL injection, JWT validation, password handling, sessions.
      Run pytest tests/auth/ after fixes.",
      toolsets=["terminal", "file"]
    )

    Code Review in Isolated Context

    When a parent session accumulates too much context, delegating the review to a fresh sub-agent ensures unbiased analysis:

    delegate_task(
      goal="Review recent commits and identify issues",
      context="Project at /home/user/myapp. Run 'git log --oneline -20' first.",
      toolsets=["terminal", "file"]
    )

    Verifying Sub-agent Results

    A sub-agent returns only a final summary, not intermediate results. The parent must:

    1. Read the summary to understand what was done
    2. Check modified files listed in the summary
    3. Validate results (run tests, read modified code)
    4. Fix if needed — the parent can pick up where the sub-agent left off

    Never blindly trust a sub-agent. Parental verification is essential, especially for production code modifications.

    Monitoring: the /agents Command

    Hermes Agent's TUI includes an /agents overlay (alias /tasks) for real-time sub-agent monitoring:

    • Live tree view of active and recently finished sub-agents
    • Per-branch metrics: cost, tokens, files touched
    • Controls: kill or pause a specific sub-agent without interrupting siblings
    • Post-hoc review: step through each sub-agent's turn-by-turn history

    In classic CLI, /agents shows a text summary. The TUI view is the most comprehensive.

    Interrupt Propagation

    Parent interruption = all active children interrupted, including grandchildren under orchestrators. Interrupted sub-agents return a structured status="interrupted" result, but since the parent is also interrupted, this result often never reaches the user.

    For durable work that must survive interrupts, prefer cron jobs or terminal(background=True, notify_on_complete=True).

    Delegation vs execute_code

    Hermes Agent also offers execute_code for mechanical pipelines. How to choose?

    • delegate_task — full LLM reasoning, tool-LLM loop, parallelism, best for complex tasks requiring judgment. Higher token cost.
    • execute_code — Python script execution, no conversation, 7 tools via RPC, no reasoning. Better for mechanical multi-step pipelines. Lower token cost.

    Rule of thumb: delegate when the subtask requires reasoning, judgment, or multi-step problem solving. Use execute_code for mechanical data processing.

    ACP: Spawning Claude Code and Codex CLI as Sub-agents

    Thanks to Hermes Agent's available tools, it's possible to spawn external agents as subcontractors:

    # Spawn Claude Code for a code audit
    delegate_task(
      goal="Run Claude Code to audit the codebase",
      context="Launch claude code in /home/user/project.
      Ask it to review the auth module for security issues.
      Report findings as a structured list.",
      toolsets=["terminal"]
    )
    
    # Spawn Codex CLI for code generation
    delegate_task(
      goal="Use Codex CLI to generate API endpoints",
      context='Project at /home/user/api.
      Run codex "generate CRUD endpoints for users model"
      Integrate the output into the existing FastAPI app.',
      toolsets=["terminal"]
    )

    This approach combines the best of each tool: Hermes Agent's orchestration with Claude Code or Codex CLI's specialized expertise, all in isolated, parallelizable contexts.

    Common Pitfalls to Avoid

    • Insufficient context: not passing enough info in context. The sub-agent is blind — be explicit.
    • File conflicts: two sub-agents modifying the same file simultaneously. Plan tasks to avoid overlaps.
    • Expecting intermediate results: only the final summary is returned. No step-by-step streaming.
    • Forgetting verification: a sub-agent can produce partially incorrect results. Always validate.
    • Hidden costs: each sub-agent consumes tokens. Monitor with /agents.
    • Excessive depth: max_spawn_depth: 3 with 3 children = 27 potential agents. Be cautious.

    Conclusion

    Task delegation via delegate_task is one of the most transformative capabilities of Hermes Agent. It enables a shift from sequential execution to parallel orchestration of autonomous agents, each isolated in context but coordinated by an intelligent parent.

    Key takeaways:

    • Sub-agents start with a blank context — provide everything they need via goal and context
    • Batch mode parallelizes up to N simultaneous tasks (3 by default)
    • leaf vs orchestrator roles and max_spawn_depth/max_concurrent_children control tree complexity
    • Sub-agents cannot use clarify, memory, send_message, or code_execution
    • Always verify results returned by sub-agents
    • Combine with external tools like Claude Code or Codex CLI for powerful hybrid workflows

    Conclusion

    Mastering delegation means transforming Hermes Agent into a true AI conductor, capable of tackling complex projects by intelligently breaking down work — while keeping human oversight where it matters.

    Key points:

    • Use delegate_task for autonomous subtasks that would consume too much context
    • Subagents work in complete isolation — pass all necessary context upfront
    • Respect the max_concurrent_children and max_spawn_depth limits
    • Always verify returned results before using them

    To go further, check out our guide on MCP servers which extend subagent capabilities with external tools.

    ## Conclusion Delegation via `delegate_task` is one of Hermes Agent's most powerful features. It enables work parallelization, simultaneous task management, and keeps the main context clean while exploring paths in parallel. Sub-agents work in complete isolation, ensuring the parent context remains relevant and usable. For complex projects requiring parallel research, development, and testing, delegation is a decisive asset that multiplies your AI agent's productivity.