docs(delegation): align guidance with current contract

This commit is contained in:
Gille 2026-07-17 16:06:11 -06:00 committed by Teknium
parent 38233b61c2
commit 35c578177b
5 changed files with 90 additions and 145 deletions

View file

@ -2,14 +2,15 @@
"""
Delegate Tool -- Subagent Architecture
Spawns child AIAgent instances with isolated context, restricted toolsets,
Spawns child AIAgent instances with isolated context, inherited toolsets,
and their own terminal sessions. Supports single-task and batch (parallel)
modes. The parent blocks until all children complete.
modes. Top-level model calls run in the background; orchestrator children
wait for their own workers so they can synthesize the results.
Each child gets:
- A fresh conversation (no parent history)
- Its own task_id (own terminal session, file ops cache)
- A restricted toolset (configurable, with blocked tools always stripped)
- The parent's toolsets, with child-only blocked tools stripped
- A focused system prompt built from the delegated goal + context
The parent's context only sees the delegation call and the summary result,
@ -2391,8 +2392,8 @@ def delegate_task(
Spawn one or more child agents to handle delegated tasks.
Supports two modes:
- Single: provide goal (+ optional context, toolsets, role)
- Batch: provide tasks array [{goal, context, toolsets, role}, ...]
- Single: provide goal (+ optional context and role)
- Batch: provide tasks array [{goal, context, role}, ...]
The 'role' parameter controls whether a child can further delegate:
'leaf' (default) cannot; 'orchestrator' retains the delegation
@ -3272,16 +3273,16 @@ def _build_top_level_description() -> str:
"Only the final summary is returned -- intermediate tool results "
"never enter your context window.\n\n"
"TWO MODES (one of 'goal' or 'tasks' is required):\n"
"1. Single task: provide 'goal' (+ optional context, toolsets).\n"
"1. Single task: provide 'goal' (+ optional context and role).\n"
f"2. Batch (parallel): provide 'tasks' array with up to {max_children} "
f"items concurrently for this user (configured via "
f"delegation.max_concurrent_children in config.yaml). {nesting_clause}\n\n"
"BOTH MODES RUN IN THE BACKGROUND. delegate_task returns immediately — "
"you and the user keep working, and each subagent's full result "
"re-enters the conversation as its own new message when it finishes. A "
"batch is just N independent background subagents (N handles, each "
"completes on its own). Do NOT wait or poll; just continue with other "
"work after dispatching.\n\n"
"you and the user keep working, and the completed result re-enters "
"the conversation as a new message. A "
"batch returns one handle, runs N subagents concurrently, and delivers "
"one consolidated result after ALL of them finish. Do NOT wait or poll; "
"just continue with other work after dispatching.\n\n"
"WHEN TO USE delegate_task:\n"
"- Reasoning-heavy subtasks (debugging, code review, research synthesis)\n"
"- Tasks that would flood your context with intermediate data\n"
@ -3335,7 +3336,7 @@ def _build_tasks_param_description() -> str:
f"Batch mode: tasks to run in parallel (up to {max_children} for this "
f"user, set via delegation.max_concurrent_children). Each gets "
"its own subagent with isolated context and terminal session. "
"When provided, top-level goal/context/toolsets are ignored."
"When provided, top-level goal/context/role are ignored."
)
@ -3464,13 +3465,13 @@ DELEGATE_TASK_SCHEMA = {
"background": {
"type": "boolean",
"description": (
"DEPRECATED / IGNORED. Single-task delegations always run "
"in the background automatically — you do not need to (and "
"cannot) opt in or out. The result re-enters the "
"conversation as a new message when the subagent finishes; "
"just continue working in the meantime. Setting this has no "
"effect; the parameter remains only for backward "
"compatibility."
"DEPRECATED / IGNORED. Top-level single and batch "
"delegations run in the background automatically — you do "
"not need to (and cannot) opt in or out. A single result or "
"consolidated batch result re-enters the conversation when "
"the work finishes; just continue working in the meantime. "
"Setting this has no effect; the parameter remains only for "
"backward compatibility."
),
},
},

View file

@ -25,7 +25,7 @@ For the full feature reference, see [Subagent Delegation](/user-guide/features/d
- Mechanical multi-step work with logic between steps → `execute_code`
- Tasks needing user interaction → subagents can't use `clarify`
- Quick file edits → do them directly
- 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.
- Durable long-running work that must survive session closure or process restart → `cronjob` or `terminal(background=True, notify_on_complete=True)`. Top-level delegation is asynchronous but still process-local.
---
@ -48,18 +48,15 @@ Behind the scenes, Hermes uses:
delegate_task(tasks=[
{
"goal": "Research WebAssembly outside the browser in 2025",
"context": "Focus on: runtimes (Wasmtime, Wasmer), cloud/edge use cases, WASI progress",
"toolsets": ["web"]
"context": "Focus on: runtimes (Wasmtime, Wasmer), cloud/edge use cases, WASI progress"
},
{
"goal": "Research RISC-V server chip adoption",
"context": "Focus on: server chips shipping, cloud providers adopting, software ecosystem",
"toolsets": ["web"]
"context": "Focus on: server chips shipping, cloud providers adopting, software ecosystem"
},
{
"goal": "Research practical quantum computing applications",
"context": "Focus on: error correction breakthroughs, real-world use cases, key companies",
"toolsets": ["web"]
"context": "Focus on: error correction breakthroughs, real-world use cases, key companies"
}
])
```
@ -87,8 +84,7 @@ delegate_task(
Auth files: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py
Test command: pytest tests/auth/ -v
Focus on: SQL injection, JWT validation, password hashing, session management.
Fix issues found and verify tests pass.""",
toolsets=["terminal", "file"]
Fix issues found and verify tests pass."""
)
```
@ -130,8 +126,7 @@ delegate_task(tasks=[
Old format: return {"data": result, "status": "ok"}
New format: return APIResponse(data=result, status=200).to_dict()
Import: from src.responses import APIResponse
Run tests after: pytest tests/handlers/ -v""",
"toolsets": ["terminal", "file"]
Run tests after: pytest tests/handlers/ -v"""
},
{
"goal": "Update all client SDK methods to handle the new response format",
@ -139,16 +134,14 @@ delegate_task(tasks=[
Files: sdk/python/client.py, sdk/python/models.py
Old parsing: result = response.json()["data"]
New parsing: result = response.json()["data"] (same key, but add status code checking)
Also update sdk/python/tests/test_client.py""",
"toolsets": ["terminal", "file"]
Also update sdk/python/tests/test_client.py"""
},
{
"goal": "Update API documentation to reflect the new response format",
"context": """Project at /home/user/api-server.
Docs at: docs/api/. Format: Markdown with code examples.
Update all response examples from old format to new format.
Add a 'Response Format' section to docs/api/overview.md explaining the schema.""",
"toolsets": ["terminal", "file"]
Add a 'Response Format' section to docs/api/overview.md explaining the schema."""
}
])
```
@ -191,8 +184,7 @@ delegate_task(
context="""Raw data at /tmp/ai-funding-data.json contains search results and
extracted web pages about AI funding, acquisitions, and IPOs in Q1 2026.
Write a structured market report: key deals, trends, notable players,
and outlook. Focus on deals over $100M.""",
toolsets=["terminal", "file"]
and outlook. Focus on deals over $100M."""
)
```
@ -200,18 +192,9 @@ This is often the most efficient pattern: `execute_code` handles the 10+ sequent
---
## Toolset Selection
## Inherited Tool Access
Choose toolsets based on what the subagent needs:
| Task type | Toolsets | Why |
|-----------|----------|-----|
| Web research | `["web"]` | web_search + web_extract only |
| Code work | `["terminal", "file"]` | Shell access + file operations |
| Full-stack | `["terminal", "file", "web"]` | Everything except messaging |
| Read-only analysis | `["file"]` | Can only read files, no shell |
Restricting toolsets keeps the subagent focused and prevents accidental side effects (like a research subagent running shell commands).
Subagents inherit the parent's enabled toolsets. `delegate_task` does not accept a model-facing `toolsets` parameter, so delegated work cannot grant itself capabilities that the parent does not have. Configure the parent's tools before starting the conversation when a delegated task needs web, terminal, file, or other access. Hermes still strips child-blocked tools such as `clarify`, `memory`, and `execute_code`.
---
@ -238,7 +221,7 @@ delegation:
- **Separate terminals** — each subagent gets its own terminal session with separate working directory and state
- **No conversation history** — subagents see only the `goal` and `context` the parent agent passes when calling `delegate_task`
- **Default 50 iterations** — set `max_iterations` lower for simple tasks to save cost
- **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)`.
- **Not durable**top-level delegation runs in the background and posts its result back later, but it remains tied to the owning session and Hermes process. Session closure, `/stop`, `/new`, or a process restart can cancel or strand in-progress work. Use `cronjob` or `terminal(background=True, notify_on_complete=True)` for work that must survive those boundaries.
---

View file

@ -6,15 +6,16 @@ description: "Spawn isolated child agents for parallel workstreams with delegate
# Subagent Delegation
The `delegate_task` tool spawns child AIAgent instances with isolated context, restricted toolsets, and their own terminal sessions. Each child gets a fresh conversation and works independently — only its final summary enters the parent's context.
The `delegate_task` tool spawns child AIAgent instances with isolated context, inherited tool access, and their own terminal sessions. Each child gets a fresh conversation and works independently — only its final summary enters the parent's context.
Top-level model calls run in the background automatically. Hermes returns a handle immediately so the conversation can continue, then posts the result back as a new message. An orchestrator subagent waits for its own workers so it can synthesize their results before returning.
## Single Task
```python
delegate_task(
goal="Debug why tests fail",
context="Error: assertion in test_foo.py line 42",
toolsets=["terminal", "file"]
context="Error: assertion in test_foo.py line 42"
)
```
@ -24,9 +25,9 @@ Up to 3 concurrent subagents by default (configurable, no hard ceiling):
```python
delegate_task(tasks=[
{"goal": "Research topic A", "toolsets": ["web"]},
{"goal": "Research topic B", "toolsets": ["web"]},
{"goal": "Fix the build", "toolsets": ["terminal", "file"]}
{"goal": "Research topic A", "context": "Focus on recent primary sources"},
{"goal": "Research topic B", "context": "Compare the leading explanations"},
{"goal": "Fix the build", "context": "Project root: /home/user/project"}
])
```
@ -65,18 +66,15 @@ Research multiple 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"]
"context": "Focus on: browser support, non-browser runtimes, language support"
},
{
"goal": "Research the current state of RISC-V adoption in 2025",
"context": "Focus on: server chips, embedded systems, software ecosystem",
"toolsets": ["web"]
"context": "Focus on: server chips, embedded systems, software ecosystem"
},
{
"goal": "Research quantum computing progress in 2025",
"context": "Focus on: error correction breakthroughs, practical applications, key players",
"toolsets": ["web"]
"context": "Focus on: error correction breakthroughs, practical applications, key players"
}
])
```
@ -92,8 +90,7 @@ delegate_task(
Auth module files: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py.
The project uses Flask, PyJWT, and bcrypt.
Focus on: SQL injection, JWT validation, password handling, session management.
Fix any issues found and run the test suite (pytest tests/auth/).""",
toolsets=["terminal", "file"]
Fix any issues found and run the test suite (pytest tests/auth/)."""
)
```
@ -112,22 +109,21 @@ delegate_task(
- print(f"Debug: ...") -> logger.debug(...)
- Other prints -> logger.info(...)
Don't change print() in test files or CLI output.
Run pytest after to verify nothing broke.""",
toolsets=["terminal", "file"]
Run pytest after to verify nothing broke."""
)
```
## Batch Mode Details
When you provide a `tasks` array, subagents run in **parallel** using a thread pool:
When a top-level agent provides a `tasks` array, Hermes returns one background handle, runs the subagents in parallel, and posts one consolidated result after every child finishes. An orchestrator subagent waits for its batch in the current turn so it can synthesize the results.
- **Maximum concurrency:** 3 tasks by default (configurable via `delegation.max_concurrent_children` or the `DELEGATION_MAX_CONCURRENT_CHILDREN` env var; floor of 1, no hard ceiling). Batches larger than the limit return a tool error rather than being silently truncated.
- **Thread pool:** Uses `ThreadPoolExecutor` with the configured concurrency limit as max workers
- **Progress display:** In CLI mode, a tree-view shows tool calls from each subagent in real-time with per-task completion lines. In gateway mode, progress is batched and relayed to the parent's progress callback
- **Result ordering:** Results are sorted by task index to match input order regardless of completion order
- **Interrupt propagation:** Interrupting the parent (e.g., sending a new message) interrupts all active children
- **Cancellation:** Follow-up messages do not cancel a top-level background batch. `/stop` or closing/resetting the owning session cancels its active children. Synchronous orchestrator children still follow their parent's interrupt state
Single-task delegation runs directly without thread pool overhead.
Synchronous single-task delegation from an orchestrator runs directly without thread pool overhead.
### Durable background completions
@ -157,19 +153,11 @@ delegation:
If omitted, subagents use the same model as the parent.
## Toolset Selection Tips
## Inherited Tool Access
The `toolsets` parameter controls what tools the subagent has access to. Choose based on the task:
`delegate_task` does not accept a model-facing `toolsets` parameter. Each subagent inherits the parent's enabled toolsets so the model cannot grant a child capabilities that the parent does not have. Configure the parent's tools before starting the conversation if delegated work needs additional capabilities.
| Toolset Pattern | Use Case |
|----------------|----------|
| `["terminal", "file"]` | Code work, debugging, file editing, builds |
| `["web"]` | Research, fact-checking, documentation lookup |
| `["terminal", "file", "web"]` | Full-stack tasks (default) |
| `["file"]` | Read-only analysis, code review without execution |
| `["terminal"]` | System administration, process management |
Certain toolsets are blocked for subagents regardless of what you specify:
Certain tools are blocked for subagents even when the parent has them:
- `delegation` — blocked for leaf subagents (the default). Retained for `role="orchestrator"` children, bounded by `max_spawn_depth` — see [Depth Limit and Nested Orchestration](#depth-limit-and-nested-orchestration) below.
- `clarify` — subagents cannot interact with the user
- `memory` — no writes to shared persistent memory
@ -241,9 +229,9 @@ delegate_task(
## Lifetime and Durability
:::warning Background completion durability is not durable execution
By default, `delegate_task` runs **inside the parent's current turn** and blocks until every child finishes. With `background=true`, the child may continue after that turn returns while the owning session and Hermes process remain alive:
Top-level model-facing `delegate_task` calls run in the background automatically where the session supports later delivery. Hermes returns a handle immediately, and the result re-enters the conversation after the child or batch finishes. Orchestrator subagents wait for their workers in the current turn because they must synthesize those results before returning. Stateless request/response endpoints fall back to synchronous execution when they cannot deliver a detached result later.
- If the parent is interrupted (user sends a new message, `/stop`, `/new`), all active children are cancelled and return `status="interrupted"`. Their in-progress work is discarded.
- Normal follow-up messages do not cancel background children. `/stop` cancels running background delegations, and closing or resetting the owning session discards its active children.
- Explicit session close/reset interrupts that session's background children. Closing a TUI viewer of a gateway-owned session does not kill the gateway's work.
- A Hermes process restart does **not** resume a running child. Its attempt becomes `unknown` because Hermes cannot prove which side effects happened.
- A child that completed before restart but whose result was not delivered is restored and routed back through the owning session's normal checks.
@ -258,9 +246,10 @@ For **durable execution** that must survive session closure or process restart,
## Key Properties
- Each subagent gets its **own terminal session** (separate from the parent)
- Subagents inherit the parent's enabled toolsets; the model cannot select or widen them per call
- **Nested delegation is opt-in** — only `role="orchestrator"` children can delegate further, and only when `max_spawn_depth` is raised from its default of 1 (flat). Disable globally with `orchestrator_enabled: false`.
- Leaf subagents **cannot** call: `delegate_task`, `clarify`, `memory`, `execute_code`. Orchestrator subagents retain `delegate_task` but still cannot use the other three.
- **Interrupt propagation** — interrupting the parent interrupts all active children (including grandchildren under orchestrators)
- **Cancellation follows ownership** — `/stop` or closing/resetting the owning session cancels its background children; synchronous descendants under orchestrators follow their parent's interrupt state
- Only the final summary enters the parent's context, keeping token usage efficient
- Subagents inherit the parent's **API key, provider configuration, and credential pool** (enabling key rotation on rate limits)

View file

@ -25,7 +25,7 @@ Hermes 可以生成隔离的子代理来并行处理任务。每个子代理拥
- 步骤间有逻辑的机械性多步骤工作 → `execute_code`
- 需要用户交互的任务 → 子代理无法使用 `clarify`
- 快速文件编辑 → 直接操作
- 必须在当前轮次结束后继续运行的持久性长任务 → `cronjob``terminal(background=True, notify_on_complete=True)``delegate_task` 是**同步**的:若父轮次被中断,活跃的子代理将被取消,其工作将被丢弃
- 必须在会话关闭或进程重启后继续运行的持久性长任务 → `cronjob``terminal(background=True, notify_on_complete=True)`顶层委派是异步的,但仍依赖当前进程
---
@ -48,18 +48,15 @@ Hermes 可以生成隔离的子代理来并行处理任务。每个子代理拥
delegate_task(tasks=[
{
"goal": "Research WebAssembly outside the browser in 2025",
"context": "Focus on: runtimes (Wasmtime, Wasmer), cloud/edge use cases, WASI progress",
"toolsets": ["web"]
"context": "Focus on: runtimes (Wasmtime, Wasmer), cloud/edge use cases, WASI progress"
},
{
"goal": "Research RISC-V server chip adoption",
"context": "Focus on: server chips shipping, cloud providers adopting, software ecosystem",
"toolsets": ["web"]
"context": "Focus on: server chips shipping, cloud providers adopting, software ecosystem"
},
{
"goal": "Research practical quantum computing applications",
"context": "Focus on: error correction breakthroughs, real-world use cases, key companies",
"toolsets": ["web"]
"context": "Focus on: error correction breakthroughs, real-world use cases, key companies"
}
])
```
@ -87,8 +84,7 @@ delegate_task(
Auth files: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py
Test command: pytest tests/auth/ -v
Focus on: SQL injection, JWT validation, password hashing, session management.
Fix issues found and verify tests pass.""",
toolsets=["terminal", "file"]
Fix issues found and verify tests pass."""
)
```
@ -129,8 +125,7 @@ delegate_task(tasks=[
Old format: return {"data": result, "status": "ok"}
New format: return APIResponse(data=result, status=200).to_dict()
Import: from src.responses import APIResponse
Run tests after: pytest tests/handlers/ -v""",
"toolsets": ["terminal", "file"]
Run tests after: pytest tests/handlers/ -v"""
},
{
"goal": "Update all client SDK methods to handle the new response format",
@ -138,16 +133,14 @@ delegate_task(tasks=[
Files: sdk/python/client.py, sdk/python/models.py
Old parsing: result = response.json()["data"]
New parsing: result = response.json()["data"] (same key, but add status code checking)
Also update sdk/python/tests/test_client.py""",
"toolsets": ["terminal", "file"]
Also update sdk/python/tests/test_client.py"""
},
{
"goal": "Update API documentation to reflect the new response format",
"context": """Project at /home/user/api-server.
Docs at: docs/api/. Format: Markdown with code examples.
Update all response examples from old format to new format.
Add a 'Response Format' section to docs/api/overview.md explaining the schema.""",
"toolsets": ["terminal", "file"]
Add a 'Response Format' section to docs/api/overview.md explaining the schema."""
}
])
```
@ -190,8 +183,7 @@ delegate_task(
context="""Raw data at /tmp/ai-funding-data.json contains search results and
extracted web pages about AI funding, acquisitions, and IPOs in Q1 2026.
Write a structured market report: key deals, trends, notable players,
and outlook. Focus on deals over $100M.""",
toolsets=["terminal", "file"]
and outlook. Focus on deals over $100M."""
)
```
@ -199,18 +191,9 @@ delegate_task(
---
## 工具集选择
## 继承的工具访问权限
根据子代理的需求选择工具集:
| 任务类型 | 工具集 | 原因 |
|-----------|----------|-----|
| 网络研究 | `["web"]` | 仅 web_search + web_extract |
| 代码工作 | `["terminal", "file"]` | Shell 访问 + 文件操作 |
| 全栈 | `["terminal", "file", "web"]` | 除消息功能外的全部工具 |
| 只读分析 | `["file"]` | 只能读取文件,无 Shell |
限制工具集可使子代理保持专注,并防止意外副作用(例如研究子代理执行 Shell 命令)。
子代理会继承父代理已启用的工具集。`delegate_task` 不接受面向模型的 `toolsets` 参数因此委派任务无法自行授予父代理没有的能力。如果委派任务需要网络、终端、文件或其他访问权限请在开始对话前配置父代理的工具。Hermes 仍会移除 `clarify``memory``execute_code` 等对子代理屏蔽的工具。
---
@ -237,7 +220,7 @@ delegation:
- **独立终端** — 每个子代理拥有独立的终端会话,具有独立的工作目录和状态
- **无对话历史** — 子代理只能看到父代理调用 `delegate_task` 时传入的 `goal``context`
- **默认 50 次迭代** — 对简单任务设置较低的 `max_iterations` 以节省成本
- **非持久性**`delegate_task` 是同步的,在父轮次内运行。若父轮次被中断(新用户消息、`/stop``/new`),所有活跃子代理将被取消(`status="interrupted"`),其工作将被丢弃。对于必须在当前轮次结束后继续运行的工作,请使用 `cronjob``terminal(background=True, notify_on_complete=True)`
- **非持久性**顶层委派会在后台运行并稍后发送结果,但仍依赖所属会话和 Hermes 进程。会话关闭、`/stop``/new` 或进程重启都可能取消或遗留正在执行的工作。对于必须跨越这些边界继续运行的任务,请使用 `cronjob``terminal(background=True, notify_on_complete=True)`
---
@ -253,4 +236,4 @@ delegation:
---
*完整的委托参考——所有参数、ACP 集成和高级配置——请参阅[子代理委托](/user-guide/features/delegation)。*
*完整的委托参考——所有参数、ACP 集成和高级配置——请参阅[子代理委托](/user-guide/features/delegation)。*

View file

@ -6,15 +6,16 @@ description: "使用 delegate_task 为并行工作流生成隔离的子智能体
# 子智能体委派
`delegate_task` 工具会生成具有隔离上下文、受限工具集和独立终端会话的子 AIAgent 实例。每个子智能体获得全新的对话并独立运行——只有其最终摘要会进入父智能体的上下文。
`delegate_task` 工具会生成具有隔离上下文、继承工具访问权限和独立终端会话的子 AIAgent 实例。每个子智能体获得全新的对话并独立运行——只有其最终摘要会进入父智能体的上下文。
顶层模型调用会自动在后台运行。Hermes 会立即返回句柄,使对话可以继续,并在任务完成后将结果作为新消息发送回来。编排者子智能体会等待自己的工作线程完成,以便在返回前综合结果。
## 单任务
```python
delegate_task(
goal="Debug why tests fail",
context="Error: assertion in test_foo.py line 42",
toolsets=["terminal", "file"]
context="Error: assertion in test_foo.py line 42"
)
```
@ -24,9 +25,9 @@ delegate_task(
```python
delegate_task(tasks=[
{"goal": "Research topic A", "toolsets": ["web"]},
{"goal": "Research topic B", "toolsets": ["web"]},
{"goal": "Fix the build", "toolsets": ["terminal", "file"]}
{"goal": "Research topic A", "context": "Focus on recent primary sources"},
{"goal": "Research topic B", "context": "Compare the leading explanations"},
{"goal": "Fix the build", "context": "Project root: /home/user/project"}
])
```
@ -65,18 +66,15 @@ delegate_task(
delegate_task(tasks=[
{
"goal": "Research the current state of WebAssembly in 2025",
"context": "Focus on: browser support, non-browser runtimes, language support",
"toolsets": ["web"]
"context": "Focus on: browser support, non-browser runtimes, language support"
},
{
"goal": "Research the current state of RISC-V adoption in 2025",
"context": "Focus on: server chips, embedded systems, software ecosystem",
"toolsets": ["web"]
"context": "Focus on: server chips, embedded systems, software ecosystem"
},
{
"goal": "Research quantum computing progress in 2025",
"context": "Focus on: error correction breakthroughs, practical applications, key players",
"toolsets": ["web"]
"context": "Focus on: error correction breakthroughs, practical applications, key players"
}
])
```
@ -92,8 +90,7 @@ delegate_task(
Auth module files: src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py.
The project uses Flask, PyJWT, and bcrypt.
Focus on: SQL injection, JWT validation, password handling, session management.
Fix any issues found and run the test suite (pytest tests/auth/).""",
toolsets=["terminal", "file"]
Fix any issues found and run the test suite (pytest tests/auth/)."""
)
```
@ -112,22 +109,21 @@ delegate_task(
- print(f"Debug: ...") -> logger.debug(...)
- Other prints -> logger.info(...)
Don't change print() in test files or CLI output.
Run pytest after to verify nothing broke.""",
toolsets=["terminal", "file"]
Run pytest after to verify nothing broke."""
)
```
## 批处理模式详情
你提供 `tasks` 数组时,子智能体会使用线程池**并行**运行:
顶层智能体提供 `tasks` 数组时Hermes 会返回一个后台句柄,并行运行所有子智能体,并在每个子智能体完成后发送一条汇总结果。编排者子智能体则会在当前轮次中等待批处理完成,以便综合结果。
- **最大并发数:** 默认 3 个任务(可通过 `delegation.max_concurrent_children` 或环境变量 `DELEGATION_MAX_CONCURRENT_CHILDREN` 配置;最低为 1无硬性上限。超出限制的批次会返回工具错误而不是被静默截断。
- **线程池:** 使用 `ThreadPoolExecutor`,以配置的并发限制作为最大工作线程数
- **进度显示:** 在 CLI 模式下,树形视图会实时显示每个子智能体的工具调用,并附带每个任务的完成行。在 gateway 模式下,进度会被批量汇总并转发给父智能体的进度回调
- **结果排序:** 结果按任务索引排序,与输入顺序一致,不受完成顺序影响
- **中断传播:** 中断父智能体(例如发送新消息)会中断所有活跃的子智能体
- **取消:** 后续消息不会取消顶层后台批处理。`/stop` 或关闭/重置所属会话会取消其活跃子智能体。同步编排者的子智能体仍会跟随其父智能体的中断状态
单任务委派直接运行,不会产生线程池开销。
编排者发起的同步单任务委派直接运行,不会产生线程池开销。
### 持久化后台完成事件
@ -148,19 +144,11 @@ delegation:
如果省略,子智能体将使用与父智能体相同的模型。
## 工具集选择建议
## 继承的工具访问权限
`toolsets` 参数控制子智能体可以访问的工具。根据任务选择:
`delegate_task` 不接受面向模型的 `toolsets` 参数。每个子智能体都会继承父智能体已启用的工具集,因此模型无法授予子智能体父智能体本身没有的能力。如果委派任务需要其他能力,请在开始对话前配置父智能体的工具。
| 工具集模式 | 使用场景 |
|----------------|----------|
| `["terminal", "file"]` | 代码工作、调试、文件编辑、构建 |
| `["web"]` | 研究、事实核查、文档查阅 |
| `["terminal", "file", "web"]` | 全栈任务(默认) |
| `["file"]` | 只读分析、无需执行的代码审查 |
| `["terminal"]` | 系统管理、进程管理 |
无论你指定什么,某些工具集对子智能体始终被屏蔽:
即使父智能体拥有某些工具,以下工具仍会对子智能体屏蔽:
- `delegation` — 对叶子子智能体屏蔽(默认)。`role="orchestrator"` 的子智能体可保留,受 `max_spawn_depth` 约束——参见下方[深度限制与嵌套编排](#depth-limit-and-nested-orchestration)。
- `clarify` — 子智能体无法与用户交互
- `memory` — 不可写入共享持久内存
@ -233,9 +221,9 @@ delegate_task(
## 生命周期与持久性
:::warning 后台完成事件持久化并不等于执行持久化
默认情况下,`delegate_task` 在**父智能体的当前轮次内**运行,并阻塞到所有子智能体完成。使用 `background=true` 时,只要所属会话和 Hermes 进程仍然存活,子智能体可以在该轮次返回后继续运行:
在会话支持稍后交付结果时,顶层面向模型的 `delegate_task` 调用会自动在后台运行。Hermes 会立即返回句柄,并在子智能体或批处理完成后将结果重新发送到对话中。编排者子智能体会在当前轮次中等待自己的工作线程,因为它们必须在返回前综合这些结果。无法稍后交付分离结果的无状态请求/响应端点会回退到同步执行。
- 如果父智能体被中断(用户发送新消息、`/stop``/new`),所有活跃的子智能体都会被取消并返回 `status="interrupted"`。其进行中的工作将被丢弃
- 普通后续消息不会取消后台子智能体。`/stop` 会取消运行中的后台委派,关闭或重置所属会话会丢弃其活跃子智能体
- 显式关闭或重置会话会中断该会话的后台子智能体。关闭由 TUI 查看、但由网关拥有的会话不会终止网关自己的后台工作。
- Hermes 进程重启后不会恢复仍在运行的子智能体;该尝试会变为 `unknown`,因为 Hermes 无法证明哪些外部副作用已经发生。
- 如果子智能体在重启前已经完成、但结果尚未交付,该完成事件会被恢复,并重新经过所属会话的正常路由检查。
@ -250,9 +238,10 @@ delegate_task(
## 关键特性
- 每个子智能体获得其**独立的终端会话**(与父智能体分离)
- 子智能体继承父智能体已启用的工具集;模型无法按调用选择或扩大这些工具集
- **嵌套委派为可选项**——只有 `role="orchestrator"` 的子智能体可以进一步委派,且仅在 `max_spawn_depth` 从默认值 1扁平提高后才生效。可通过 `orchestrator_enabled: false` 全局禁用。
- 叶子子智能体**不能**调用:`delegate_task``clarify``memory``send_message``execute_code`。编排者子智能体保留 `delegate_task`,但仍不能使用其他四个。
- **中断传播**——中断父智能体会中断所有活跃的子智能体(包括编排者下的孙智能体)
- **取消遵循所有权**——`/stop` 或关闭/重置所属会话会取消其后台子智能体;编排者下的同步后代会跟随父智能体的中断状态
- 只有最终摘要进入父智能体的上下文,保持 token 使用高效
- 子智能体继承父智能体的 **API 密钥、provider 配置和凭据池**(支持在速率限制时轮换密钥)
@ -295,4 +284,4 @@ delegation:
:::tip
智能体会根据任务复杂度自动处理委派。你无需明确要求它进行委派——它会在合适时自行决定。
:::
:::