--- sidebar_position: 7 title: "子智能体委派" description: "使用 delegate_task 为并行工作流生成隔离的子智能体" --- # 子智能体委派 `delegate_task` 工具会生成具有隔离上下文、继承工具访问权限和独立终端会话的子 AIAgent 实例。每个子智能体获得全新的对话并独立运行——只有其最终摘要会进入父智能体的上下文。 顶层模型调用会自动在后台运行。Hermes 会立即返回句柄,使对话可以继续,并在任务完成后将结果作为新消息发送回来。编排者子智能体会等待自己的工作线程完成,以便在返回前综合结果。 ## 单任务 ```python delegate_task( goal="Debug why tests fail", context="Error: assertion in test_foo.py line 42" ) ``` ## 并行批处理 默认最多 3 个并发子智能体(可配置,无硬性上限): ```python delegate_task(tasks=[ {"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"} ]) ``` ## 子智能体上下文的工作方式 :::warning 关键:子智能体一无所知 子智能体以**全新对话**启动。它们对父智能体的对话历史、之前的工具调用或委派前讨论的任何内容一无所知。子智能体的唯一上下文来自父智能体调用 `delegate_task` 时填写的 `goal` 和 `context` 字段。 ::: 唯一例外:当父智能体有已解析的工作区目录时,每个子智能体的系统提示都会嵌入该工作区的**项目上下文文件**(`.hermes.md` > AGENTS.md 链 > CLAUDE.md > `.cursorrules`——与主智能体系统提示相同的发现逻辑、优先级和大小上限;SOUL.md 除外)。在仓库中工作的子智能体无需重新发现即可遵循仓库自身的约定。 这意味着父智能体必须在调用中传递子智能体所需的**一切**信息: ```python # BAD - subagent has no idea what "the error" is delegate_task(goal="Fix the error") # GOOD - subagent has all context it needs 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. The project is at /home/user/myproject and uses Python 3.11.""" ) ``` 子智能体会收到一个基于你的 goal 和 context 构建的专注系统 prompt(提示词),指示其完成任务并提供结构化摘要,包括所做的事情、发现的内容、修改的文件以及遇到的问题。 ## 实际示例 ### 并行研究 同时研究多个主题并收集摘要: ```python delegate_task(tasks=[ { "goal": "Research the current state of WebAssembly in 2025", "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" }, { "goal": "Research quantum computing progress in 2025", "context": "Focus on: error correction breakthroughs, practical applications, key players" } ]) ``` ### 代码审查 + 修复 将审查并修复的工作流委派给全新上下文: ```python delegate_task( goal="Review the authentication module for security issues and fix any found", context="""Project at /home/user/webapp. 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/).""" ) ``` ### 多文件重构 将会大量占用父智能体上下文的大型重构任务委派出去: ```python delegate_task( goal="Refactor all Python files in src/ to replace print() with proper logging", context="""Project at /home/user/myproject. Use the 'logging' module with logger = logging.getLogger(__name__). Replace print() calls with appropriate log levels: - print(f"Error: ...") -> logger.error(...) - print(f"Warning: ...") -> logger.warning(...) - 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.""" ) ``` ## 批处理模式详情 当顶层智能体提供 `tasks` 数组时,Hermes 会返回一个后台句柄,并行运行所有子智能体,并在每个子智能体完成后发送一条汇总结果。编排者子智能体则会在当前轮次中等待批处理完成,以便综合结果。 - **最大并发数:** 默认 3 个任务(可通过 `delegation.max_concurrent_children` 或环境变量 `DELEGATION_MAX_CONCURRENT_CHILDREN` 配置;最低为 1,无硬性上限)。超出限制的批次会返回工具错误,而不是被静默截断。 - **线程池:** 使用 `ThreadPoolExecutor`,以配置的并发限制作为最大工作线程数 - **进度显示:** 在 CLI 模式下,树形视图会实时显示每个子智能体的工具调用,并附带每个任务的完成行。在 gateway 模式下,进度会被批量汇总并转发给父智能体的进度回调 - **结果排序:** 结果按任务索引排序,与输入顺序一致,不受完成顺序影响 - **取消:** 后续消息不会取消顶层后台批处理。`/stop` 或关闭/重置所属会话会取消其活跃子智能体。同步编排者的子智能体仍会跟随其父智能体的中断状态 编排者发起的同步单任务委派会直接运行,不会产生线程池开销。 ### 持久化后台完成事件 后台委派完成后,Hermes 会先把完成事件写入当前 profile 的 `state.db`,再发布到正常的新轮次队列。如果 Hermes 在完成后、交付前重启,待处理事件会被恢复,并继续经过相同的所有权检查。多个消费者通过持久化 claim 竞争;只有成功接收合成轮次的消费者会确认交付,失败尝试会释放 claim 以便重试。 这不会在崩溃后恢复子智能体执行。如果委派仍在运行时其所有者进程消失,Hermes 会将其记录为 `unknown`,因为无法证明外部副作用是否已经发生。待处理和已交付记录都有界,并按 profile 隔离。 ## 模型覆盖 你可以通过 `config.yaml` 为子智能体配置不同的模型——适用于将简单任务委派给更便宜/更快的模型: ```yaml # In ~/.hermes/config.yaml delegation: model: "google/gemini-flash-2.0" # Cheaper model for subagents provider: "openrouter" # Optional: route subagents to a different provider ``` 如果省略,子智能体将使用与父智能体相同的模型。 ### 成本策略:前沿模型规划,低价模型执行 将问题分解为规格清晰的子任务需要前沿模型级别的判断力;而执行一个已经带有明确目标、完整上下文和输出约定的子任务通常不需要。与此同时,token 消耗主要发生在子智能体身上——并行批量子智能体通常消耗一次运行中绝大多数的 token,因此成本真正落在 worker 模型上。将 `delegation.model` 固定为低价模型、同时主会话保持前沿模型,可以把规划质量留在最需要的地方,并在消耗量最大的地方削减开支: ```yaml # ~/.hermes/config.yaml model: default: "your-frontier-model" # 父智能体(规划者)保持前沿模型 delegation: model: "your-inexpensive-model" # 所有 delegate_task 子智能体运行此模型 provider: "openrouter" # 可选:将子智能体路由到不同的提供商 ``` 解析顺序:`delegation.base_url`(直连端点)优先,其次是 `delegation.provider`(通过运行时提供商系统解析完整凭证包);两者都未设置时,子智能体继承父智能体的提供商和凭证。`delegation.model` 在所有情况下生效,为空时子智能体继承父智能体的模型。 注意此固定是全局的:`delegate_task` 没有按任务指定模型的参数,批处理中的每个子智能体都运行配置的委派模型。对于需要更强模型的质量敏感型子任务,可以在该会话中不设置 `delegation.model`,或者将任务交给[看板](kanban.md)——看板支持按任务覆盖模型。 ## `/review` 命令 `/review` 会派生一个独立的、拥有完整工具权限的后台评审子智能体,专门评审对话刚刚产出的工作——PR、diff、代码、文档、设计。它在所有界面均可用:CLI、TUI、桌面应用以及所有网关消息平台。 ``` /review # 评审最近 10 条消息中呈现的工作 /review 重点关注安全性 # 为评审者附加额外指示 ``` 工作流程: 1. 最近 10 条用户/助手消息被快照为评审者的起始证据(工具输出和系统消息被排除)。 2. 评审子智能体在与 `delegate_task` 相同的后台委派通道上派发——它拥有完整的常规子智能体工具集(终端、网络、文件、浏览器等),因此会实际打开 PR、阅读 diff、运行代码,而不是仅凭摘录下判断。 3. 评审者继承主智能体的工作上下文:主智能体已加载的技能(启动预加载或会话中通过 `skill_view` 加载)会列在其简报中,并指示其加载这些技能、以其约定为标准评判工作。与所有子智能体一样,其系统提示也会嵌入工作区的项目上下文文件(AGENTS.md / CLAUDE.md / .cursorrules)作为具有约束力的约定。 4. 完成后,完整评审作为常规后台子智能体完成事件重新进入同一会话——你的主智能体可以看到并据此行动(修复问题、推送后续提交、回复你)。 典型流程:主智能体开了一个 PR,你输入 `/review`,第二双眼睛在你继续工作的同时对其进行调查;评审结果回到聊天中,交给创建该 PR 的智能体。 ### 评审模型 默认情况下评审者运行在你的主模型上。要固定专用评审模型,请在 `config.yaml` 中设置 `auxiliary.review`: ```yaml auxiliary: review: provider: openrouter # 或 nous、anthropic、直连 base_url 等 model: anthropic/claude-opus-4.6 # 一个强力的评审模型 ``` 凭证解析方式与 `delegation.provider` 固定完全相同(完整运行时提供商凭证包:base_url、API 密钥、api_mode)。`provider: auto` 加空 `model` 表示"继承主智能体的模型"——这是默认值。 `/review` 与 `/refine` 刻意分开:`/refine` 评审对话本身以更新记忆和技能,`/review` 评审对话产出的*工作成果*。 ## 继承的工具访问权限 `delegate_task` 不接受面向模型的 `toolsets` 参数。每个子智能体都会继承父智能体已启用的工具集,因此模型无法授予子智能体父智能体本身没有的能力。如果委派任务需要其他能力,请在开始对话前配置父智能体的工具。 即使父智能体拥有某些工具,以下工具仍会对子智能体屏蔽: - `delegation` — 对叶子子智能体屏蔽(默认)。`role="orchestrator"` 的子智能体可保留,受 `max_spawn_depth` 约束——参见下方[深度限制与嵌套编排](#depth-limit-and-nested-orchestration)。 - `clarify` — 子智能体无法与用户交互 - `memory` — 不可写入共享持久内存 - `code_execution` — 子智能体应逐步推理 - `send_message` — 无跨平台副作用(例如发送 Telegram 消息) ## 最大迭代次数 每个子智能体都有迭代次数限制(默认:50),控制其可进行的工具调用轮次: ```python delegate_task( goal="Quick file check", context="Check if /etc/nginx/nginx.conf exists and print its first 10 lines", max_iterations=10 # Simple task, don't need many turns ) ``` ## 子智能体超时 默认情况下,子智能体**没有挂钟超时限制**。子智能体只会因其实际执行的操作而失败——API 错误、工具错误或达到迭代预算上限——而不会被委派层面的计时器终止。早期版本曾设有硬性上限(300 秒,后为 600 秒),但这会在任务执行过程中误杀正常工作的子智能体:深度代码审查、大规模研究分发以及慢速推理模型经常需要超过 10 分钟,而它们全程都在稳定推进。 真正卡死的子智能体仍会被检测到:当子智能体没有任何进展(无 API 调用、无工具启动)时,心跳陈旧度监控会停止刷新父智能体的活动状态,从而让网关的不活动超时机制对真正卡死的工作进程生效。 如果仍需要硬性上限(例如对无人值守的 cron 驱动委派进行成本控制),可按安装实例选择启用: ```yaml delegation: child_timeout_seconds: 0 # 默认:0 = 无超时 # child_timeout_seconds: 1800 # 选择启用的硬性上限(下限 30 秒) ``` 正值会对每个子智能体强制执行挂钟时间硬限制;`0` 或负值表示禁用。 :::tip 零调用超时时的诊断转储 在配置了硬性上限的情况下,如果子智能体在**零次** API 调用的情况下超时(通常原因:provider 不可达、认证失败或工具 schema 被拒绝),`delegate_task` 会将结构化诊断信息写入 `~/.hermes/logs/subagent-timeout--.log`,其中包含子智能体的配置快照、凭据解析追踪以及早期错误消息。比之前的静默超时行为更易于定位根因。 ::: ## 监控运行中的子智能体(`/agents`) TUI 提供 `/agents` 浮层(别名 `/tasks`),将递归 `delegate_task` 扇出转化为一级审计界面: - 运行中和最近完成的子智能体的实时树形视图,按父智能体分组 - 每个分支的费用、token 和已触及文件的汇总 - 终止和暂停控制——可在不中断其兄弟智能体的情况下取消特定子智能体 - 事后回顾:即使子智能体已返回父智能体,也可逐轮查看其历史记录 经典 CLI 仅将 `/agents` 打印为文本摘要;TUI 才是浮层真正发挥作用的地方。参见 [TUI — 斜杠命令](/user-guide/tui#slash-commands)。 ## 深度限制与嵌套编排 {#depth-limit-and-nested-orchestration} 默认情况下,委派是**扁平的**:父智能体(深度 0)生成子智能体(深度 1),而这些子智能体无法进一步委派。这可防止失控的递归委派。 对于多阶段工作流(研究 → 综合,或对子问题进行并行编排),父智能体可以生成**编排者**子智能体,这些子智能体*可以*委派自己的工作线程: ```python delegate_task( goal="Survey three code review approaches and recommend one", role="orchestrator", # Allows this child to spawn its own workers context="...", ) ``` - `role="leaf"`(默认):子智能体无法进一步委派——与扁平委派行为相同。 - `role="orchestrator"`:子智能体保留 `delegation` 工具集。受 `delegation.max_spawn_depth` 约束(默认 **1** = 扁平,因此在默认设置下 `role="orchestrator"` 无效)。将 `max_spawn_depth` 提高到 2 可允许编排者子智能体生成叶子孙智能体;设为 3 则允许三层(上限)。 - `delegation.orchestrator_enabled: false`:全局开关,无论 `role` 参数如何,强制所有子智能体为 `leaf`。 **费用警告:** 在 `max_spawn_depth: 3` 和 `max_concurrent_children: 3` 的情况下,树可达到 3×3×3 = 27 个并发叶子智能体。每增加一层都会成倍增加开销——请谨慎提高 `max_spawn_depth`。 ## 生命周期与持久性 :::warning 后台完成事件持久化并不等于执行持久化 在会话支持稍后交付结果时,顶层面向模型的 `delegate_task` 调用会自动在后台运行。Hermes 会立即返回句柄,并在子智能体或批处理完成后将结果重新发送到对话中。编排者子智能体会在当前轮次中等待自己的工作线程,因为它们必须在返回前综合这些结果。无法稍后交付分离结果的无状态请求/响应端点会回退到同步执行。 - 普通后续消息不会取消后台子智能体。`/stop` 会取消运行中的后台委派,关闭或重置所属会话会丢弃其活跃子智能体。 - 显式关闭或重置会话会中断该会话的后台子智能体。关闭由 TUI 查看、但由网关拥有的会话不会终止网关自己的后台工作。 - Hermes 进程重启后不会恢复仍在运行的子智能体;该尝试会变为 `unknown`,因为 Hermes 无法证明哪些外部副作用已经发生。 - 如果子智能体在重启前已经完成、但结果尚未交付,该完成事件会被恢复,并重新经过所属会话的正常路由检查。 - 被取消的子智能体会返回结构化结果(`status="interrupted"`,`exit_reason="interrupted"`),但由于父智能体也被中断,该结果通常不会出现在用户可见的回复中。 对于必须在会话关闭或进程重启后继续的**持久执行**,请使用: - `cronjob`(action=`create`)——调度独立的智能体运行;不受父智能体轮次中断影响。 - `terminal(background=True, notify_on_complete=True)`——长时间运行的 shell 命令,在智能体执行其他操作时持续运行。 ::: ## 关键特性 - 每个子智能体获得其**独立的终端会话**(与父智能体分离) - 子智能体继承父智能体已启用的工具集;模型无法按调用选择或扩大这些工具集 - **嵌套委派为可选项**——只有 `role="orchestrator"` 的子智能体可以进一步委派,且仅在 `max_spawn_depth` 从默认值 1(扁平)提高后才生效。可通过 `orchestrator_enabled: false` 全局禁用。 - 叶子子智能体**不能**调用:`delegate_task`、`clarify`、`memory`、`send_message`、`execute_code`。编排者子智能体保留 `delegate_task`,但仍不能使用其他四个。 - **取消遵循所有权**——`/stop` 或关闭/重置所属会话会取消其后台子智能体;编排者下的同步后代会跟随父智能体的中断状态 - 只有最终摘要进入父智能体的上下文,保持 token 使用高效 - 子智能体继承父智能体的 **API 密钥、provider 配置和凭据池**(支持在速率限制时轮换密钥) ## delegate_task 与 execute_code 对比 | 因素 | delegate_task | execute_code | |--------|--------------|-------------| | **推理** | 完整 LLM 推理循环 | 仅 Python 代码执行 | | **上下文** | 全新隔离对话 | 无对话,仅脚本 | | **工具访问** | 所有非屏蔽工具,具备推理能力 | 通过 RPC 访问 7 个工具,无推理 | | **并行性** | 默认 3 个并发子智能体(可配置) | 单脚本 | | **最适合** | 需要判断力的复杂任务 | 机械式多步骤流水线 | | **Token 费用** | 较高(完整 LLM 循环) | 较低(仅返回 stdout) | | **用户交互** | 无(子智能体无法澄清) | 无 | **经验法则:** 当子任务需要推理、判断或多步骤问题解决时,使用 `delegate_task`。当需要机械式数据处理或脚本化工作流时,使用 `execute_code`。 ## 配置 ```yaml # In ~/.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). Raise to 2 to allow orchestrator children to spawn leaves; 3 for three levels. # orchestrator_enabled: true # Disable to force all children to leaf role. model: "google/gemini-3-flash-preview" # Optional provider/model override provider: "openrouter" # Optional built-in provider api_mode: anthropic_messages # optional; auto-detected from base_url for anthropic_messages endpoints # Or use a direct custom endpoint instead of provider: delegation: model: "qwen2.5-coder" base_url: "http://localhost:1234/v1" api_key: "local-key" # api_mode: "anthropic_messages" # Optional. Wire protocol override for base_url ("chat_completions", "codex_responses", or "anthropic_messages"). Empty = auto-detect from URL (e.g. /anthropic suffix). Set explicitly for endpoints the heuristic can't classify (Azure AI Foundry, MiniMax, Zhipu GLM, LiteLLM proxies, …). ``` 当 `base_url` 指向 Anthropic 兼容端点时——例如路径以 `/anthropic` 结尾、Azure Foundry Claude 路由或 MiniMax `/anthropic` 代理——`api_mode` 会被自动检测为 `anthropic_messages`,子智能体无需任何配置即可使用正确的传输格式。当自动检测结果有误时(罕见),请显式设置 `api_mode`。 :::tip 智能体会根据任务复杂度自动处理委派。你无需明确要求它进行委派——它会在合适时自行决定。 :::