ByteNoteByteNote

字节笔记本

2026年6月21日

hermes教程-子智能体委派

API中转
¥120

delegate_task 工具会生成具有独立上下文、受限工具集以及自身终端会话的子 AIAgent 实例。每个子智能体都会获得全新的对话并独立工作——只有其最终摘要会进入父智能体的上下文。

单一任务

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

并行批处理

默认最多 3 个并发子智能体(可配置,无硬性上限):

python
delegate_task(tasks=[
    {"goal": "Research topic A", "toolsets": ["web"]},
    {"goal": "Research topic B", "toolsets": ["web"]},
    {"goal": "Fix the build", "toolsets": ["terminal", "file"]}
])

子智能体上下文如何工作

警告 — 关键:子智能体一无所知

子智能体以完全全新的对话开始。它们对父智能体的对话历史、之前的工具调用或委派前讨论的任何内容都一无所知。子智能体的唯一上下文来自父智能体在调用 delegate_task 时填充的 goalcontext 字段。

这意味着父智能体必须在调用中传递子智能体所需的所有信息:

python
## 错误 - 子智能体不知道“错误”是什么
delegate_task(goal="Fix the error")
## 正确 - 子智能体拥有所需的所有上下文
delegate_task(
    goal="Fix the TypeError in api/handlers.py",
    context="""文件 api/handlers.py 在第 47 行有一个 TypeError:
    'NoneType' object has no attribute 'get'。
    函数 process_request() 从 parse_body() 接收一个 dict,
    但当 Content-Type 缺失时 parse_body() 返回 None。
    项目位于 /home/user/myproject,使用 Python 3.11。"""
)

子智能体会收到一个由你的目标和上下文构建的聚焦系统提示,指示它完成任务并提供结构化的摘要,说明它做了什么、发现了什么、修改了哪些文件以及遇到了哪些问题。

实际示例

并行研究

同时研究多个主题并收集摘要:

python
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 the current state of 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 breakthroughs, practical applications, key players",
        "toolsets": ["web"]
    }
])

代码审查 + 修复

将审查和修复工作流委派给全新的上下文:

python
delegate_task(
    goal="Review the authentication module for security issues and fix any found",
    context="""项目位于 /home/user/webapp。
    认证模块文件:src/auth/login.py, src/auth/jwt.py, src/auth/middleware.py。
    项目使用 Flask、PyJWT 和 bcrypt。
    重点关注:SQL 注入、JWT 验证、密码处理、会话管理。
    修复发现的任何问题并运行测试套件(pytest tests/auth/)。""",
    toolsets=["terminal", "file"]
)

多文件重构

将大型重构任务委派出去,避免淹没父智能体的上下文:

python
delegate_task(
    goal="Refactor all Python files in src/ to replace print() with proper logging",
    context="""项目位于 /home/user/myproject。
    使用 'logging' 模块,logger = logging.getLogger(__name__)。
    将 print() 调用替换为适当的日志级别:
    - print(f"Error: ...") -> logger.error(...)
    - print(f"Warning: ...") -> logger.warning(...)
    - print(f"Debug: ...") -> logger.debug(...)
    - 其他 print -> logger.info(...)
    不要更改测试文件或 CLI 输出中的 print()。
    之后运行 pytest 以验证没有破坏任何内容。""",
    toolsets=["terminal", "file"]
)

批处理模式详情

当你提供一个 tasks 数组时,子智能体使用线程池并行运行:

  • 最大并发数: 默认 3 个任务(可通过 delegation.max_concurrent_childrenDELEGATION_MAX_CONCURRENT_CHILDREN 环境变量配置;下限为 1,无硬性上限)。超过限制的批次会返回工具错误,而不是静默截断。
  • 线程池: 使用 ThreadPoolExecutor,最大工作线程数为配置的并发限制
  • 进度显示: 在 CLI 模式下,树状视图会实时显示每个子智能体的工具调用,并附带每个任务的完成行。在网关模式下,进度会批量处理并转发给父智能体的进度回调
  • 结果排序: 结果按任务索引排序,以匹配输入顺序,无论完成顺序如何
  • 中断传播: 中断父智能体(例如发送新消息)会中断所有活跃的子智能体

单一任务委派直接运行,无需线程池开销。

模型覆盖

你可以通过 config.yaml 为子智能体配置不同的模型——这对于将简单任务委派给更便宜/更快的模型很有用:

yaml
## 在 ~/.hermes/config.yaml 中
delegation:
  model: "google/gemini-flash-2.0"    # 子智能体使用更便宜的模型
  provider: "openrouter"              # 可选:将子智能体路由到不同的提供商

如果省略,子智能体将使用与父智能体相同的模型。

工具集选择提示

toolsets 参数控制子智能体可以访问哪些工具。根据任务选择:

工具集模式使用场景
["terminal", "file"]代码工作、调试、文件编辑、构建
["web"]研究、事实核查、文档查找
["terminal", "file", "web"]全栈任务(默认)
["file"]只读分析、无需执行的代码审查
["terminal"]系统管理、进程管理

无论你指定什么,某些工具集对子智能体是禁止的:

  • delegation — 对叶子子智能体(默认)禁止。保留给 role="orchestrator" 的子智能体,受 max_spawn_depth 限制——请参阅下面的深度限制与嵌套编排
  • 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  # 简单任务,不需要很多轮次
)

子智能体超时

默认情况下,子智能体没有挂钟超时。子智能体只会因为实际正在做的事情而失败——API 错误、工具错误或达到迭代预算——而永远不会因为委派级别的计时器而失败。早期版本有一个硬性上限(300 秒,后来 600 秒),这经常在任务进行中杀死合法繁忙的子智能体:深度代码审查、大规模研究展开和慢速推理模型通常需要超过 10 分钟,同时持续取得进展。

真正卡住的子智能体仍然会被检测到:心跳陈旧性监视器会在子智能体没有进展(没有 API 调用,没有工具启动)时停止刷新父智能体的活动,从而让网关不活动超时触发真正卡住的工作进程。

如果你仍然想要一个硬性上限(例如,在无人值守的 cron 驱动委派中进行成本控制),可以在每个安装中启用:

yaml
delegation:
  child_timeout_seconds: 0     # 默认:0 = 无超时
## child_timeout_seconds: 1800  # 选择加入的硬性上限(下限 30 秒)

正值对每个子智能体强制执行硬性挂钟限制;0 或负值禁用。

提示 — 零调用超时的诊断转储

如果配置了硬性上限,并且子智能体在进行了次 API 调用(通常是:提供商不可达、认证失败或工具模式拒绝)时超时,delegate_task 会将结构化诊断写入 ~/.hermes/logs/subagent-timeout-<session>-<timestamp>.log,其中包含子智能体的配置快照、凭据解析跟踪以及任何早期错误消息。这比之前的静默超时行为更容易定位根因。

监控运行中的子智能体(/agents

TUI 提供了一个 /agents 覆盖层(别名 /tasks),将递归的 delegate_task 展开转换为第一等的审计界面:

  • 运行中和最近完成的子智能体的实时树状视图,按父智能体分组
  • 每个分支的成本、令牌和文件接触汇总
  • 终止和暂停控制——在飞行中取消特定子智能体而不中断其兄弟
  • 事后审查:逐步查看每个子智能体的逐轮历史,即使它们已经返回给父智能体

经典 CLI 仅将 /agents 打印为文本摘要;TUI 才是覆盖层大放异彩的地方。请参阅 TUI — 斜杠命令

深度限制与嵌套编排

默认情况下,委派是扁平的:父智能体(深度 0)生成子智能体(深度 1),而这些子智能体不能再委派。这可以防止失控的递归委派。

对于多阶段工作流(研究 → 综合,或对子问题进行并行编排),父智能体可以生成编排器子智能体,这些子智能体可以委派它们自己的工作进程:

python
delegate_task(
    goal="Survey three code review approaches and recommend one",
    role="orchestrator",  # 允许此子智能体生成自己的工作进程
    context="...",
)
  • role="leaf"(默认):子智能体不能再委派——与扁平委派行为相同。
  • role="orchestrator":子智能体保留 delegation 工具集。受 delegation.max_spawn_depth 限制(默认 1 = 扁平,因此 role="orchestrator" 在默认情况下是空操作)。将 max_spawn_depth 提高到 2 以允许编排器子智能体生成叶子孙智能体;3 或更高用于更深的树。没有上限——成本是实际限制。
  • delegation.orchestrator_enabled: false:全局开关,强制所有子智能体为 leaf,无论 role 参数如何。

成本警告:max_spawn_depth: 3max_concurrent_children: 3 时,树可以达到 3×3×3 = 27 个并发叶子智能体。每增加一层都会增加花费——请有意提高 max_spawn_depth

生命周期与持久性

警告 — delegate_task 是同步的 — 不持久

delegate_task父智能体的当前轮次内运行。它会阻塞父智能体,直到每个子智能体完成(或被取消)。它不是后台作业队列:

  • 如果父智能体被中断(用户发送新消息、/stop/new),所有活跃的子智能体都会被取消并返回 status="interrupted"。它们正在进行的工作将被丢弃。
  • 子智能体在父智能体轮次结束后不会继续运行。
  • 被取消的子智能体会返回结构化结果(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_taskclarifymemorysend_messageexecute_code。编排器子智能体保留 delegate_task,但仍然不能使用其他四个。
  • 中断传播——中断父智能体会中断所有活跃的子智能体(包括编排器下的孙智能体)
  • 只有最终摘要进入父智能体的上下文,保持令牌使用效率
  • 子智能体继承父智能体的 API 密钥、提供商配置和凭据池(在速率限制时启用密钥轮换)

委派 vs execute_code

因素delegate_taskexecute_code
推理完整的 LLM 推理循环仅 Python 代码执行
上下文全新的隔离对话无对话,仅脚本
工具访问所有非禁止工具,带推理通过 RPC 的 7 个工具,无推理
并行性默认 3 个并发子智能体(可配置)单个脚本
最佳用途需要判断的复杂任务机械的多步骤流水线
令牌成本较高(完整的 LLM 循环)较低(仅返回 stdout)
用户交互无(子智能体不能澄清)

经验法则: 当子任务需要推理、判断或多步骤问题解决时,使用 delegate_task。当需要机械数据处理或脚本化工作流时,使用 execute_code

配置

yaml
## 在 ~/.hermes/config.yaml 中
delegation:
  max_iterations: 50                        # 每个子智能体的最大轮次(默认:50)
## max_concurrent_children: 3              # 每批次的并行子智能体数(默认:3)
## max_spawn_depth: 1                      # 树深度(下限 1,无上限,默认 1 = 扁平)。提高到 2 以允许编排器子智能体生成叶子;3 或更高用于更深的树。
## orchestrator_enabled: true              # 禁用以强制所有子智能体为叶子角色。
  model: "google/gemini-3-flash-preview"             # 可选的提供商/模型覆盖
  provider: "openrouter"                             # 可选的内置提供商
  api_mode: anthropic_messages                       # 可选;对于 anthropic_messages 端点,从 base_url 自动检测
## 或者使用直接的自定义端点而不是提供商:
delegation:
  model: "qwen2.5-coder"
  base_url: "http://localhost:1234/v1"
  api_key: "local-key"
## api_mode: "anthropic_messages"  # 可选。base_url 的线路协议覆盖("chat_completions"、"codex_responses" 或 "anthropic_messages")。空 = 从 URL 自动检测(例如 /anthropic 后缀)。对于启发式方法无法分类的端点(Azure AI Foundry、MiniMax、Zhipu GLM、LiteLLM 代理等),请显式设置。

base_url 指向一个兼容 Anthropic 的端点——例如以 /anthropic 结尾的路径、Azure Foundry Claude 路由或 MiniMax /anthropic 代理——api_mode 会自动检测为 anthropic_messages,因此子智能体无需你设置任何内容即可使用正确的线路格式。当自动检测猜测错误时(很少见),请显式设置 api_mode

提示

智能体会根据任务复杂性自动处理委派。你不需要明确要求它委派——它会在有意义时自动进行。

分享: