delegation-patterns.md
1 --- 2 sidebar_position: 13 3 title: "Delegation & Parallel Work" 4 description: "When and how to use subagent delegation — patterns for parallel research, code review, and multi-file work" 5 --- 6 7 # Delegation & Parallel Work 8 9 Hermes can spawn isolated child agents to work on tasks in parallel. Each subagent gets its own conversation, terminal session, and toolset. Only the final summary comes back — intermediate tool calls never enter your context window. 10 11 For the full feature reference, see [Subagent Delegation](/docs/user-guide/features/delegation). 12 13 --- 14 15 ## When to Delegate 16 17 **Good candidates for delegation:** 18 - Reasoning-heavy subtasks (debugging, code review, research synthesis) 19 - Tasks that would flood your context with intermediate data 20 - Parallel independent workstreams (research A and B simultaneously) 21 - Fresh-context tasks where you want the agent to approach without bias 22 23 **Use something else:** 24 - Single tool call → just use the tool directly 25 - Mechanical multi-step work with logic between steps → `execute_code` 26 - Tasks needing user interaction → subagents can't use `clarify` 27 - Quick file edits → do them directly 28 - Durable long-running work that must outlive the current turn → `cronjob` or `terminal(background=True, notify_on_complete=True)`. `delegate_task` is **synchronous**: if the parent turn is interrupted, active children are cancelled and their work is discarded. 29 30 --- 31 32 ## Pattern: Parallel Research 33 34 Research three topics simultaneously and get structured summaries back: 35 36 ``` 37 Research these three topics in parallel: 38 1. Current state of WebAssembly outside the browser 39 2. RISC-V server chip adoption in 2025 40 3. Practical quantum computing applications 41 42 Focus on recent developments and key players. 43 ``` 44 45 Behind the scenes, Hermes uses: 46 47 ```python 48 delegate_task(tasks=[ 49 { 50 "goal": "Research WebAssembly outside the browser in 2025", 51 "context": "Focus on: runtimes (Wasmtime, Wasmer), cloud/edge use cases, WASI progress", 52 "toolsets": ["web"] 53 }, 54 { 55 "goal": "Research RISC-V server chip adoption", 56 "context": "Focus on: server chips shipping, cloud providers adopting, software ecosystem", 57 "toolsets": ["web"] 58 }, 59 { 60 "goal": "Research practical quantum computing applications", 61 "context": "Focus on: error correction breakthroughs, real-world use cases, key companies", 62 "toolsets": ["web"] 63 } 64 ]) 65 ``` 66 67 All three run concurrently. Each subagent searches the web independently and returns a summary. The parent agent then synthesizes them into a coherent briefing. 68 69 --- 70 71 ## Pattern: Code Review 72 73 Delegate a security review to a fresh-context subagent that approaches the code without preconceptions: 74 75 ``` 76 Review the authentication module at src/auth/ for security issues. 77 Check for SQL injection, JWT validation problems, password handling, 78 and session management. Fix anything you find and run the tests. 79 ``` 80 81 The key is the `context` field — it must include everything the subagent needs: 82 83 ```python 84 delegate_task( 85 goal="Review src/auth/ for security issues and fix any found", 86 context="""Project at /home/user/webapp. Python 3.11, Flask, PyJWT, bcrypt. 87 Auth files: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py 88 Test command: pytest tests/auth/ -v 89 Focus on: SQL injection, JWT validation, password hashing, session management. 90 Fix issues found and verify tests pass.""", 91 toolsets=["terminal", "file"] 92 ) 93 ``` 94 95 :::warning The Context Problem 96 Subagents know **absolutely nothing** about your conversation. They start completely fresh. If you delegate "fix the bug we were discussing," the subagent has no idea what bug you mean. Always pass file paths, error messages, project structure, and constraints explicitly. 97 ::: 98 99 --- 100 101 ## Pattern: Compare Alternatives 102 103 Evaluate multiple approaches to the same problem in parallel, then pick the best: 104 105 ``` 106 I need to add full-text search to our Django app. Evaluate three approaches 107 in parallel: 108 1. PostgreSQL tsvector (built-in) 109 2. Elasticsearch via django-elasticsearch-dsl 110 3. Meilisearch via meilisearch-python 111 112 For each: setup complexity, query capabilities, resource requirements, 113 and maintenance overhead. Compare them and recommend one. 114 ``` 115 116 Each subagent researches one option independently. Because they're isolated, there's no cross-contamination — each evaluation stands on its own merits. The parent agent gets all three summaries and makes the comparison. 117 118 --- 119 120 ## Pattern: Multi-File Refactoring 121 122 Split a large refactoring task across parallel subagents, each handling a different part of the codebase: 123 124 ```python 125 delegate_task(tasks=[ 126 { 127 "goal": "Refactor all API endpoint handlers to use the new response format", 128 "context": """Project at /home/user/api-server. 129 Files: src/handlers/users.py, src/handlers/auth.py, src/handlers/billing.py 130 Old format: return {"data": result, "status": "ok"} 131 New format: return APIResponse(data=result, status=200).to_dict() 132 Import: from src.responses import APIResponse 133 Run tests after: pytest tests/handlers/ -v""", 134 "toolsets": ["terminal", "file"] 135 }, 136 { 137 "goal": "Update all client SDK methods to handle the new response format", 138 "context": """Project at /home/user/api-server. 139 Files: sdk/python/client.py, sdk/python/models.py 140 Old parsing: result = response.json()["data"] 141 New parsing: result = response.json()["data"] (same key, but add status code checking) 142 Also update sdk/python/tests/test_client.py""", 143 "toolsets": ["terminal", "file"] 144 }, 145 { 146 "goal": "Update API documentation to reflect the new response format", 147 "context": """Project at /home/user/api-server. 148 Docs at: docs/api/. Format: Markdown with code examples. 149 Update all response examples from old format to new format. 150 Add a 'Response Format' section to docs/api/overview.md explaining the schema.""", 151 "toolsets": ["terminal", "file"] 152 } 153 ]) 154 ``` 155 156 :::tip 157 Each subagent gets its own terminal session. They can work on the same project directory without stepping on each other — as long as they're editing different files. If two subagents might touch the same file, handle that file yourself after the parallel work completes. 158 ::: 159 160 --- 161 162 ## Pattern: Gather Then Analyze 163 164 Use `execute_code` for mechanical data gathering, then delegate the reasoning-heavy analysis: 165 166 ```python 167 # Step 1: Mechanical gathering (execute_code is better here — no reasoning needed) 168 execute_code(""" 169 from hermes_tools import web_search, web_extract 170 171 results = [] 172 for query in ["AI funding Q1 2026", "AI startup acquisitions 2026", "AI IPOs 2026"]: 173 r = web_search(query, limit=5) 174 for item in r["data"]["web"]: 175 results.append({"title": item["title"], "url": item["url"], "desc": item["description"]}) 176 177 # Extract full content from top 5 most relevant 178 urls = [r["url"] for r in results[:5]] 179 content = web_extract(urls) 180 181 # Save for the analysis step 182 import json 183 with open("/tmp/ai-funding-data.json", "w") as f: 184 json.dump({"search_results": results, "extracted": content["results"]}, f) 185 print(f"Collected {len(results)} results, extracted {len(content['results'])} pages") 186 """) 187 188 # Step 2: Reasoning-heavy analysis (delegation is better here) 189 delegate_task( 190 goal="Analyze AI funding data and write a market report", 191 context="""Raw data at /tmp/ai-funding-data.json contains search results and 192 extracted web pages about AI funding, acquisitions, and IPOs in Q1 2026. 193 Write a structured market report: key deals, trends, notable players, 194 and outlook. Focus on deals over $100M.""", 195 toolsets=["terminal", "file"] 196 ) 197 ``` 198 199 This is often the most efficient pattern: `execute_code` handles the 10+ sequential tool calls cheaply, then a subagent does the single expensive reasoning task with a clean context. 200 201 --- 202 203 ## Toolset Selection 204 205 Choose toolsets based on what the subagent needs: 206 207 | Task type | Toolsets | Why | 208 |-----------|----------|-----| 209 | Web research | `["web"]` | web_search + web_extract only | 210 | Code work | `["terminal", "file"]` | Shell access + file operations | 211 | Full-stack | `["terminal", "file", "web"]` | Everything except messaging | 212 | Read-only analysis | `["file"]` | Can only read files, no shell | 213 214 Restricting toolsets keeps the subagent focused and prevents accidental side effects (like a research subagent running shell commands). 215 216 --- 217 218 ## Constraints 219 220 - **Default 3 parallel tasks**: batches default to 3 concurrent subagents (configurable via `delegation.max_concurrent_children` in config.yaml, no hard ceiling, only a floor of 1) 221 - **Nested delegation is opt-in**: leaf subagents (default) cannot call `delegate_task`, `clarify`, `memory`, `send_message`, or `execute_code`. Orchestrator subagents (`role="orchestrator"`) retain `delegate_task` for further delegation, but only when `delegation.max_spawn_depth` is raised above the default of 1 (1-3 supported); the other four remain blocked. Disable globally via `delegation.orchestrator_enabled: false`. 222 223 ### Tuning Concurrency and Depth 224 225 | Config | Default | Range | Effect | 226 |--------|---------|-------|--------| 227 | `max_concurrent_children` | 3 | >=1 | Parallel batch size per `delegate_task` call | 228 | `max_spawn_depth` | 1 | 1-3 | How many delegation levels can spawn further | 229 230 Example: running 30 parallel workers with nested subagents: 231 232 ```yaml 233 delegation: 234 max_concurrent_children: 30 235 max_spawn_depth: 2 236 ``` 237 238 - **Separate terminals** — each subagent gets its own terminal session with separate working directory and state 239 - **No conversation history** — subagents see only the `goal` and `context` the parent agent passes when calling `delegate_task` 240 - **Default 50 iterations** — set `max_iterations` lower for simple tasks to save cost 241 - **Not durable** — `delegate_task` is synchronous and runs inside the parent turn. If the parent is interrupted (new user message, `/stop`, `/new`), all active children are cancelled (`status="interrupted"`) and their work is discarded. For work that must outlive the current turn, use `cronjob` or `terminal(background=True, notify_on_complete=True)`. 242 243 --- 244 245 ## Tips 246 247 **Be specific in goals.** "Fix the bug" is too vague. "Fix the TypeError in api/handlers.py line 47 where process_request() receives None from parse_body()" gives the subagent enough to work with. 248 249 **Include file paths.** Subagents don't know your project structure. Always include absolute paths to relevant files, the project root, and the test command. 250 251 **Use delegation for context isolation.** Sometimes you want a fresh perspective. Delegating forces you to articulate the problem clearly, and the subagent approaches it without the assumptions that built up in your conversation. 252 253 **Check results.** Subagent summaries are just that — summaries. If a subagent says "fixed the bug and tests pass," verify by running the tests yourself or reading the diff. 254 255 --- 256 257 *For the complete delegation reference — all parameters, ACP integration, and advanced configuration — see [Subagent Delegation](/docs/user-guide/features/delegation).*