Skip to content
广告 · 本站推荐广告

子代理

子代理是从现有代理运行中生成的后台代理运行。它们在自己的会话(agent::<agentId>:subagent:<id>)中运行,完成后会将结果通告回请求者的聊天频道。

斜杠命令

使用 /subagents 检查或控制当前会话的子代理运行:

  • /subagents list
  • /subagents kill <id>
  • /subagents log <id> [limit] [tools]
  • /subagents info <id>
  • /subagents send <id> <message>
  • /subagents steer <id> <instruction>
  • /subagents spawn [--model <name>] [--thinking <level>]

线程绑定控制: 以下命令在支持持久线程绑定的频道上工作。参见下方支持线程的频道

  • /focus <thread>
  • /unfocus
  • /agents
  • /session idle <hours>
  • /session max-age <hours>

/subagents info 显示运行元数据(状态、时间戳、会话 ID、转录路径、清理策略)。

生成行为

/subagents spawn 以用户命令(而非内部中继)方式启动后台子代理,并在运行完成时向请求者的聊天发送一条最终完成更新。

  • spawn 命令是非阻塞的;它会立即返回一个运行 ID。
  • 完成后,子代理向请求者的聊天频道通告摘要/结果消息。
  • 对于手动生成,交付具有弹性:
    • OpenClaw 首先尝试使用稳定的幂等键直接进行 agent 交付。
    • 如果直接交付失败,则回退到队列路由。
    • 如果队列路由仍然不可用,通告将以短指数退避重试,直到最终放弃。
  • 完成交接给请求者会话的内容是运行时生成的内部上下文(非用户编写的文本),包括:
    • Resultassistant 回复文本,如果助手回复为空则取最新的 toolResult
    • Statuscompleted successfully / failed / timed out / unknown
    • 紧凑的运行时/token 统计信息
    • 一条交付指令,告诉请求者代理用正常的助手语气改写(不要转发原始内部元数据)
  • --model--thinking 可覆盖该特定运行的默认值。
  • 使用 info/log 在完成后检查详情和输出。
  • /subagents spawn 是一次性模式(mode: "run")。对于持久的线程绑定会话,使用带 thread: truemode: "session"sessions_spawn
  • 对于 ACP 运行时会话(Codex、Claude Code、Gemini CLI),使用带 runtime: "acp"sessions_spawn,参见 ACP Agents

主要目标:

  • 并行化"研究 / 长任务 / 慢工具"工作,不阻塞主运行。
  • 默认保持子代理隔离(会话隔离 + 可选沙箱)。
  • 保持工具接口不易被误用:子代理默认获得会话工具。
  • 支持可配置的嵌套深度以适应编排模式。

费用说明:每个子代理有其自己的上下文和 token 用量。对于繁重或重复的任务,为子代理设置更便宜的模型,将主代理保持在更高质量的模型上。可通过 agents.defaults.subagents.model 或每代理覆盖进行配置。

工具使用

sessions_spawn

  • 启动子代理运行(deliver: false,全局通道:subagent
  • 然后运行通告步骤并将通告回复发布到请求者的聊天频道
  • 默认模型:继承调用者,除非你设置了 agents.defaults.subagents.model(或每代理 agents.list[].subagents.model);显式的 sessions_spawn.model 仍然优先。
  • 默认思考级别:继承调用者,除非你设置了 agents.defaults.subagents.thinking(或每代理 agents.list[].subagents.thinking);显式的 sessions_spawn.thinking 仍然优先。
  • 默认运行超时:如果 sessions_spawn.runTimeoutSeconds 被省略,OpenClaw 在设置了 agents.defaults.subagents.runTimeoutSeconds 时使用它;否则回退到 0(无超时)。

工具参数:

  • task(必需)
  • label?(可选)
  • agentId?(可选;如果允许,可在另一个代理 ID 下生成)
  • model?(可选;覆盖子代理模型;无效值会被跳过,子代理将使用默认模型运行并在工具结果中附带警告)
  • thinking?(可选;覆盖子代理运行的思考级别)
  • runTimeoutSeconds?(设置了 agents.defaults.subagents.runTimeoutSeconds 时使用该默认值,否则为 0;设置后,子代理运行在 N 秒后中止)
  • thread?(默认 false;为 true 时,请求为此子代理会话绑定频道线程)
  • mode?run|session
    • 默认为 run
    • 如果 thread: truemode 被省略,默认变为 session
    • mode: "session" 需要 thread: true
  • cleanup?delete|keep,默认 keep
  • sandbox?inherit|require,默认 inheritrequire 在目标子运行时未沙箱化时拒绝生成)
  • sessions_spawn 接受频道交付参数(targetchanneltothreadIdreplyTotransport)。对于交付,从生成的运行中使用 message/sessions_send

线程绑定会话

当频道启用了线程绑定时,子代理可以保持绑定到某个线程,这样该线程中的后续用户消息会持续路由到同一个子代理会话。

支持线程的频道

  • Discord(目前是唯一支持的频道):支持持久的线程绑定子代理会话(带 thread: truesessions_spawn)、手动线程控制(/focus/unfocus/agents/session idle/session max-age),以及适配器键 channels.discord.threadBindings.enabledchannels.discord.threadBindings.idleHourschannels.discord.threadBindings.maxAgeHourschannels.discord.threadBindings.spawnSubagentSessions

快速流程:

  1. 使用带 thread: true(以及可选 mode: "session")的 sessions_spawn 进行生成。
  2. OpenClaw 在活跃频道中创建或绑定一个线程到该会话目标。
  3. 该线程中的回复和后续消息路由到绑定的会话。
  4. 使用 /session idle 检查/更新不活跃自动解除聚焦,使用 /session max-age 控制硬性上限。
  5. 使用 /unfocus 手动解除绑定。

手动控制:

  • /focus <thread> 将当前线程(或创建一个新线程)绑定到子代理/会话目标。
  • /unfocus 移除当前绑定线程的绑定。
  • /agents 列出活跃运行和绑定状态(thread:<id>unbound)。
  • /session idle/session max-age 仅对已聚焦的绑定线程有效。

配置开关:

  • 全局默认值:session.threadBindings.enabledsession.threadBindings.idleHourssession.threadBindings.maxAgeHours
  • 频道覆盖和生成自动绑定键是适配器特定的。参见上方支持线程的频道

参见 配置参考斜杠命令 了解当前适配器详情。

允许列表:

  • agents.list[].subagents.allowAgents:可通过 agentId 定位的代理 ID 列表(["*"] 允许任何代理)。默认:仅限请求者代理。
  • 沙箱继承守卫:如果请求者会话处于沙箱模式,sessions_spawn 会拒绝将以非沙箱方式运行的目标。

发现:

  • 使用 agents_list 查看当前允许用于 sessions_spawn 的代理 ID。

自动归档:

  • 子代理会话在 agents.defaults.subagents.archiveAfterMinutes(默认:60)之后自动归档。
  • 归档使用 sessions.delete 并将转录重命名为 *.deleted.*(同一文件夹)。
  • cleanup: "delete" 在通告后立即归档(仍通过重命名保留转录)。
  • 自动归档是尽力而为的;如果 Gateway 重启,待处理的计时器会丢失。
  • runTimeoutSeconds 不会自动归档;它仅停止运行。会话保留直到自动归档。
  • 自动归档同样适用于深度-1 和深度-2 会话。

嵌套子代理

默认情况下,子代理不能生成自己的子代理(maxSpawnDepth: 1)。你可以通过设置 maxSpawnDepth: 2 启用一级嵌套,这允许编排模式:主代理 → 编排子代理 → 工作子子代理。

如何启用

json5
{
  agents: {
    defaults: {
      subagents: {
        maxSpawnDepth: 2, // 允许子代理生成子代理(默认:1)
        maxChildrenPerAgent: 5, // 每个代理会话的最大活跃子代理数(默认:5)
        maxConcurrent: 8, // 全局并发通道上限(默认:8)
        runTimeoutSeconds: 900, // sessions_spawn 省略时的默认超时(0 = 无超时)
      },
    },
  },
}

深度级别

深度会话键形式角色能否生成子代理?
0agent::<agentId>:main主代理始终可以
1agent::<agentId>:subagent:<id>子代理(深度 2 允许时为编排者)仅当 maxSpawnDepth >= 2
2agent::<agentId>:subagent::<id>:<id>子子代理(叶工作者)永远不可以

通告链

结果沿链条向上流动:

  1. 深度-2 工作者完成 → 向其父级(深度-1 编排者)通告
  2. 深度-1 编排者接收通告,综合结果,完成 → 向主代理通告
  3. 主代理接收通告并交付给用户

每个级别仅看到来自其直接子级的通告。

按深度的工具策略

  • 深度 1(编排者,当 maxSpawnDepth >= 2 时):获得 sessions_spawnsubagentssessions_listsessions_history,以便管理其子代理。其他会话/系统工具保持拒绝。
  • 深度 1(叶节点,当 maxSpawnDepth == 1 时):无会话工具(当前默认行为)。
  • 深度 2(叶工作者):无会话工具 — sessions_spawn 在深度 2 始终被拒绝。不能生成更多子代理。

每代理生成限制

每个代理会话(在任何深度)最多可以有 maxChildrenPerAgent(默认:5)个活跃子代理。这可以防止单个编排者的失控扇出。

级联停止

停止深度-1 编排者会自动停止其所有深度-2 子代理:

  • 在主聊天中 /stop 会停止所有深度-1 代理并级联到其深度-2 子代理。
  • /subagents kill <id> 停止特定子代理并级联到其子代理。
  • /subagents kill all 停止请求者的所有子代理并级联。

认证

子代理认证按代理 ID 解析,而非按会话类型:

  • 子代理会话键为 agent::<agentId>:subagent:<id>
  • 认证存储从该代理的 agentDir 加载。
  • 主代理的认证配置文件作为回退合并;代理配置文件在冲突时覆盖主配置文件。

注意:合并是累加的,因此主配置文件始终可作为回退使用。目前尚不支持每代理完全隔离的认证。

通告

子代理通过通告步骤报告:

  • 通告步骤在子代理会话内运行(不在请求者会话中)。
  • 如果子代理回复的确切内容为 ANNOUNCE_SKIP,则不会发布任何内容。
  • 否则,通告回复通过后续 agent 调用(deliver=true)发布到请求者的聊天频道。
  • 通告回复在频道适配器可用时保留线程/话题路由。
  • 通告上下文被规范化为稳定的内部事件块:
    • 来源(subagentcron
    • 子会话键/ID
    • 通告类型 + 任务标签
    • 从运行时结果派生的状态行(successerrortimeoutunknown
    • 通告步骤的结果内容(如果缺失则为 (no output)
    • 描述何时回复、何时保持静默的后续指令
  • Status 不是从模型输出推断的;它来自运行时结果信号。

通告载荷在末尾包含统计行(即使被包装时也是):

  • 运行时间(例如 runtime 5m12s
  • Token 用量(输入/输出/总计)
  • 配置了模型定价时的估算费用(models.providers.*.models[].cost
  • sessionKeysessionId 和转录路径(这样主代理可以通过 sessions_history 获取历史记录或在磁盘上检查文件)
  • 内部元数据仅用于编排;面向用户的回复应以正常助手语气改写。

工具策略(子代理工具)

默认情况下,子代理获得除会话工具和系统工具之外的所有工具

  • sessions_list
  • sessions_history
  • sessions_send
  • sessions_spawn

maxSpawnDepth >= 2 时,深度-1 编排子代理额外获得 sessions_spawnsubagentssessions_listsessions_history,以便管理其子代理。

通过配置覆盖:

json5
{
  agents: {
    defaults: {
      subagents: {
        maxConcurrent: 1,
      },
    },
  },
  tools: {
    subagents: {
      tools: {
        // deny 优先
        deny: ["gateway", "cron"],
        // 如果设置了 allow,则变为仅允许模式(deny 仍然优先)
        // allow: ["read", "exec", "process"]
      },
    },
  },
}

并发

子代理使用专用的进程内队列通道:

  • 通道名称:subagent
  • 并发数:agents.defaults.subagents.maxConcurrent(默认 8

停止

  • 在请求者聊天中发送 /stop 会中止请求者会话并停止从它生成的所有活跃子代理运行,级联到嵌套子代理。
  • /subagents kill <id> 停止特定子代理并级联到其子代理。

限制

  • 子代理通告是尽力而为的。如果 Gateway 重启,待处理的"通告回传"工作会丢失。
  • 子代理仍然共享相同的 Gateway 进程资源;将 maxConcurrent 视为安全阀。
  • sessions_spawn 始终是非阻塞的:它立即返回 { status: "accepted", runId, childSessionKey }
  • 子代理上下文仅注入 AGENTS.md + TOOLS.md(没有 SOUL.mdIDENTITY.mdUSER.mdHEARTBEAT.mdBOOTSTRAP.md)。
  • 最大嵌套深度为 5(maxSpawnDepth 范围:1–5)。建议大多数用例使用深度 2。
  • maxChildrenPerAgent 限制每个会话的活跃子代理数(默认:5,范围:1–20)。

基于MIT协议开源 | 内容翻译自 官方文档,同步更新