跳转到内容

子 Agent

Bub 应用内置 subagent 工具,允许当前 Agent 将特定子任务委派给同一个 Agent 的一次子运行。

子 Agent 适合将大量检索、长文档阅读、独立代码审查等产生海量中间上下文的任务从主对话中剥离出去,只将最终结论带回主会话,从而防止主会话的上下文窗口被额外信息占用。

在 bub chat 中,可以直接要求模型调用子 Agent:

使用 subagent 工具审查身份验证流程:
1. 使用临时会话,只允许使用 fs.read 和 bash;
2. 不要修改文件;
3. 返回审查发现并附带相关文件路径。

父 Agent 随后调用 subagent 工具,工具在后台启动子 Agent 并立即返回任务 ID。子 Agent 在其独立循环中调用工具完成分析,最终答案以消息的形式送达父 Agent。返回的只有这个答案,也就是子 Agent 最后一步的文本;中间的叙述和工具调用不会进入父 Agent 的上下文。

子 Agent 只能看到 prompt(使用 session="fork" 时还能看到当前对话),因此 prompt 应当自成一体:写清楚要做什么、返回什么、有哪些限制。

除了人工要求外,也可以在工作区 AGENTS.md 或技能中设定规则(例如:「复杂检索或代码审查应先委派给只读子 Agent,主 Agent 仅根据审查结论执行修改」)来实现自动委派。

session 参数决定子 Agent 从什么开始、结束后保留什么:

会话模式 行为 适用场景
temp(默认) 新建空的 temp/<task_id> 会话,结束后丢弃 最常用。一次性分析或调研,仅返回结论
fork 从当前对话(包括本轮已有内容)的副本开始,结束后丢弃 子任务需要用户和父 Agent 已经说过的内容,又不想让父 Agent 重新复述
自定义字符串 使用指定的固定会话 ID,会话会被保留 较长的工作,之后要用 subagent.send 继续,或事后查看

inherit 作为 fork 的别名仍可使用。fork 在调用发生时复制对话,子 Agent 看不到父 Agent 之后的动作,子 Agent 的记录也不会写回父会话历史。

子 Agent 总是在后台运行:它们运行期间父 Agent 继续工作,多个子 Agent 可以在父 Agent 做别的事时并行处理:

启动三个子 Agent,每个服务一个,检查日志中的错误。
你继续做迁移;它们完成后汇总结论。

任务结束时,结果会以消息的形式送达父 Agent:

<subagent-notification task_id="sub-1a2b3c4d" status="completed">
自上次部署以来,支付服务日志中没有错误。
</subagent-notification>

父 Agent 会在下一步之前读到它。由它启动的子 Agent 还在运行时,这一轮不会结束:父 Agent 没有别的事可做时,会等待下一个结果并带着它继续,因此可以在回复前汇总所有结论。只有当这一轮失败、被取消或达到步数上限时,尚未结束的任务才会随会话的下一轮报告。父 Agent 也可以直接管理任务:

工具 作用
subagent.wait 返回结果,最多等待 timeout_seconds(默认 60;0 只查看不等待)。不传 task_ids 时覆盖本会话中尚未读取的任务。在这里读到的结果不会再发通知。
subagent.send 给运行中的任务发消息,它会在下一步之前读到;或者继续一个使用命名会话、已经结束的任务。
subagent.cancel 停止运行中的任务。

同时运行的子 Agent 最多 BUB_SUBAGENT_MAX_CONCURRENCY 个(默认 4),超出的排队等待。调用时的 timeout_seconds,或全局的 BUB_SUBAGENT_TIMEOUT_SECONDS,会停止运行过久的子 Agent。退出 Bub,或对某个会话执行 ,quit,都会取消其运行中的子 Agent。

子 Agent 配置(profile)是一个可复用的子 Agent:放在工作区 .agents/agents/ 下的 markdown 文件,或放在 ~/.agents/agents/ 下供所有工作区使用。front matter 设定配置,正文会加入子 Agent 的系统提示词:

.agents/agents/reviewer.md
---
description: 审查改动中的 bug 并报告发现,不修改文件
model: openai:gpt-5-mini
tools: [fs.read, bash, tape.search]
skills: []
timeout_seconds: 600
---
你负责代码审查。阅读相关文件,报告具体问题并附上文件路径和行号,绝不修改文件。
字段 含义
description 必填。告诉父 Agent 何时使用该配置
name 可选;默认为去掉 .md 的文件名
model、reasoning_effort 子 Agent 的模型和推理强度
tools、skills 子 Agent 可用的工具和技能(列表,或逗号分隔的字符串)
timeout_seconds 子 Agent 的运行时限

当 subagent 工具可用时,父 Agent 的系统提示词会列出这些配置,模型通过把配置名传给 agent 来使用。调用时显式给出的参数优先于配置。工作区中的配置会覆盖 home 目录下的同名配置。

子 Agent 是父 Agent 所在实例的一次子运行,其继承与隔离边界如下:

资源类别 边界关系 说明与控制参数
基础实例 完全共享 共享插件 Hooks、模型凭据与 BubAgent 配置
执行环境 完全共享 共享工作区目录、本地文件系统、Shell 进程和网络访问
模型选择 可单独指定 默认使用配置中的模型或父模型,可用 model 换成轻量模型
工具与技能 不超过父 Agent 默认沿用父 Agent 本轮的工具和技能,allowed_tools、allowed_skills 可以进一步收窄。子 Agent 不能再启动子 Agent
轮次状态 复制 子 Agent 得到父 Agent 轮次状态的副本,并使用自己的 steering 键,发给父 Agent 的消息仍归父 Agent
会话记录 视策略而定 temp 和 fork 结束后丢弃;命名会话会被保留

各参数的详细类型定义及默认值见 subagent 参考。Channel 可以通过事件观察子 Agent。

和父 Agent 一样,子 Agent 本质上也运行在当前用户权限下的本地环境中,可能会对当前系统产生影响:

  1. 会话策略隔离的仅是对话记录与模型上下文,而不是文件、网络或系统进程。子 Agent 对文件进行的修改、发送的网络请求均具有真实的系统副作用,不会在退出时回滚。
  2. 在对话中,subagent 的参数由模型生成,因此 allowed_tools 只能限制模型行为,不构成强制安全边界。如需对危险命令或越权工具进行硬性拦截,必须使用工具拦截 Hooks;如需物理环境隔离,应配置独立的执行环境。