第 13 章:子代理、Goal 与 Workflow
三种机制都能让 Agent 做“比一轮对话更长的事”,但它们的控制权不同:
| 机制 | 控制者 | 最适合 |
|---|---|---|
| Subagent | 主模型按需委派 | 并行/隔离的认知子任务 |
| Goal | harness 持续监督主 Agent | 开放式、需验证的长期目标 |
| Workflow | Rhai 程序 | 可重复、可恢复的确定编排 |
理解差异,比记住三个工具名更重要。
13.1 Subagent:有身份的子会话
Task tool 不是简单递归调用模型。它向共享 coordinator 提交 SubagentRequest,创建或恢复一个真正的 child session。
请求可包含:
- prompt 与短 description;
- agent type/persona;
- parent session/prompt;
- resume id;
- cwd 或 worktree isolation;
- model/effort;
- foreground/background;
- 是否把完成主动送回 parent;
- 是否 fork parent context;
- owner(普通 task 或 workflow);
- cancellation token。
13.2 深度限制
MAX_SUBAGENT_DEPTH = 1:
Primary session (depth 0)
├─ Child A (depth 1)
└─ Child B (depth 1)
Child A ─X─> Grandchild (被拒绝)2
3
4
5
这把并行度变成“主 Agent 扇出”,避免递归 agent tree 指数增长、权限继承失控和 token 归属难以追踪。
13.3 Spawn 的控制流
Task tool 执行大致为:
- 检查 depth;
- 校验 resume/model/cwd;
- 拒绝 cwd 与 worktree isolation 的冲突组合;
- 提前解析 agent type/persona;
- 创建 UUIDv7 request id;
- 向 coordinator 提交;
- foreground 等待结果并传播取消;
- background 立即返回 handle,完成后通过 reminder/auto-wake 送回。
Eager validation 很重要:若 background 先返回“已启动”,随后才发现 agent type 不存在,父 Agent 会得到虚假的进度。
13.4 Coordinator 为什么共享
Coordinator 拥有:
- child 生命周期与 registry;
- parent/child 关系;
- 请求与回复路由;
- background completion;
- cancellation;
- usage 汇总;
- resume/fork context;
- workflow owner。
具体 child runner 接收 plain request,不需要知道所有 UI/parent 协调细节。MvpAgent 持有共享 coordinator,多个 session 可通过它追踪各自 child。
13.5 Context Fork 与 Resume
Fork context
Child 继承父会话的必要 conversation/tool state,得到新的 session id 与新 system prompt。它从共同背景开始,但后续历史独立。
Resume
恢复既有 child 的 raw transcript、工具状态和 model 选择,同时重新渲染 system prompt,以反映当前规则/能力。
新渲染 system prompt 避免长期 resume 永远使用过时模板;保留 transcript 又维持子任务连续性。
13.6 Workspace Isolation
Child 可:
- 与 parent 共享 cwd;
- 使用指定 cwd;
- 创建隔离 worktree。
Worktree 适合可能产生冲突的实现任务;共享 cwd 适合只读研究或明确分区的工作。系统还要决定 permission context 是否继承,以及 completion 时如何把修改/结果交回 parent。
13.7 Foreground 与 Background
| 模式 | Task tool 返回时机 | 完成如何送回 |
|---|---|---|
| Foreground | child 完成/失败/取消 | 当前 ToolResult |
| Background | child 成功启动后 | completion reminder、monitor、auto-wake |
Background 不应把最终结果塞进最初的 tool result,因为结果当时还不存在。它返回可查询 handle,并用 session notification 保证完成不会悄悄丢失。
13.8 Goal:持久的监督循环
Goal 解决的问题不是“多调几次模型”,而是:
当任务跨越很多回合时,如何保存目标、预算和计划,怎样验证真的完成,以及何时自动继续或暂停?
核心状态在 goal_tracker.rs。
13.9 Goal 状态与阶段
阶段 GoalPhase:
- Idle;
- Planning;
- Executing。
状态 GoalStatus:
- Active;
- UserPaused;
- BackOffPaused;
- NoProgressPaused;
- InfraPaused;
- Blocked;
- BudgetLimited;
- Complete。
状态表达生命周期,phase 表达当前正在做哪类工作。恢复时,若进程在 Planning/Executing 中断,会把 phase 收敛回 Idle;仍 Active 的旧快照会谨慎恢复为 UserPaused,避免重启后未经确认自动行动。
13.10 Goal 状态机
这些 paused variants 是可恢复终态;Complete 与 BudgetLimited 是更明确的终结状态。
13.11 Goal 每轮如何继续
Goal continuation 会向主 Agent 注入:
- 原始 objective;
- 当前 plan;
- Task checklist 中第一个未勾选项;
- 已用/剩余 token;
- 实施与测试纪律;
- verifier/strategist 的反馈。
goal_next_step 只从 Task checklist 提取首个 unchecked checkbox,忽略 acceptance/non-goals/deviations,并限制文本大小(约 8 KiB)。
这么严格的解析是为了让“下一步”可预测,不让任意 Markdown 段落变成自动执行指令。
13.12 Planner、Classifier、Evaluator
Goal harness 把角色拆开:
- Planner:把 objective 转成可执行计划;
- Classifier/Evaluator:判断当前结果是 achieved、not achieved 或需暂停;
- Evidence:收集代码、测试和任务状态证据;
- Stop detector:判断主模型是否试图结束;
- Orchestrator/Tracker:持久化状态并决定下一轮。
Planner 失败采用 fail-closed:没有可靠计划时暂停,而不是让 open-ended goal 盲目执行。
13.13 为什么不能相信主模型说“完成”
主模型既是执行者又是报告者,天然存在乐观偏差。Goal 使用 skeptic/verifier 角色和 evidence 检查:
- 声称改了哪些文件;
- 是否真的运行测试;
- acceptance criteria 是否满足;
- 是否只做了表面/模拟实现;
- 是否还有 unchecked task;
- 环境阻碍是否真实。
只有验证路径接受,Tracker 才转 Complete。
这类似软件中的双重记账:执行输出是一份陈述,独立验证是另一份证据。
13.14 Strategist 与 Summarizer
Strategist
连续若干轮 NotAchieved 后触发,给结构性建议。它:
- fail-open,失败不阻止主目标继续;
- 只写 strategy note;
- 使用 RAII 恢复
plan.md,防止顾问角色意外改执行计划。
Summarizer
只在 verified achieved 后运行一次,生成最终总结。它只读、fail-open:总结失败不能把已经验证完成的工作改回失败。
这说明不同辅助角色应有不同失败策略:
| 角色 | 失败策略 | 原因 |
|---|---|---|
| Planner | fail-closed | 没计划继续可能危险 |
| Verifier关键阻碍 | 可阻断完成 | 完成声明需证据 |
| Strategist | fail-open | 建议不是执行前提 |
| Summarizer | fail-open | 展示失败不否定事实完成 |
13.15 Token Budget
Goal Tracker 记录各模型/角色 usage,并在 turn-end 执行预算检查。预算到达后转 BudgetLimited,而不是在任意 token 中间粗暴杀死正在提交的状态。
预算不仅要计主模型,还应折叠 planner/verifier/strategist 等辅助角色使用,否则“监督成本”会变成隐形。
13.16 Workflow:程序控制的 Agent 编排
xai-workflow 使用 Rhai 脚本描述确定控制流。工作流可以:
- 调用一个或多个 agent;
- 串行/并行;
- 写 scratch;
- 读取 git diff;
- 发 telemetry/event;
- 按条件 pause/cancel/return;
- 验证结构化输出。
内置 deep_research.rhai 是一个实际示例。
13.17 为什么需要 Journal
工作流可能在第 5 个 agent call 后进程退出。若重启后从头执行,会重复费用和副作用。Journal 记录:
- host call request hash;
- 返回值或错误;
- 顺序;
- pause/terminal token。
恢复时相同 request 可 replay 已记录结果,未记录动作才继续。
13.18 Workflow 的边界与配额
Session workflow manager 施加多种限制:
- 每 session 最多 4 个 active runs;
- 恢复扫描最多 128 个 run;
- 每 run/脚本 agent call budget;
- scratch 最多约 64 files;
- 单文件约 10 MiB;
- scratch 总量约 64 MiB;
- journal/script/manifest 有界读取;
- run id 校验与 no-follow 路径读取。
脚本在启动时复制为不可变版本,resume 不受原文件后来编辑影响。
13.19 Host Service 与 Schema
Rhai 引擎不直接持有 SessionActor。它通过 WorkflowHost 请求:
- spawn agent;
- scratch I/O;
- git diff;
- telemetry。
结构化输出由 host 侧 schema 验证,失败可进行一次纠正重试。把验证放在 host,而不是完全相信脚本/模型返回,使 journal 记录的是已经过契约检查的结果。
13.20 Pause、Cancel 与所有权
Workflow run 拥有它创建的 subagent(owner run id):
- cancel workflow 应传播到其 child;
- pause 保存可恢复状态;
- shutdown 将未完成 run 标记为可解释的 interruption;
- drain 等待必要收尾;
- untrusted workflow 不允许 fork parent context。
Session 不应根据“child 是后台的”就忘记其工作流所有者。
13.21 Goal 与 Workflow 的能力 Gate
Builder 会根据运行配置决定暴露:
- GoalUpdate;
- Workflow。
启用 background workflows 时可能移除 GoalUpdate、启用 Workflow,反之亦然。这样模型不会同时面对两套竞争的“长期任务控制协议”,减少错误编排。
13.22 选择指南
| 任务 | 推荐机制 | 原因 |
|---|---|---|
| 并行研究三个模块 | Subagent | 主 Agent 汇总独立认知结果 |
| “直到测试全通过,不要停” | Goal | 需要持续监督与独立验证 |
| 固定执行研究→评审→汇总 | Workflow | 控制流可编码、可重放 |
| 临时请 reviewer 看 diff | Subagent | 一次委派足够 |
| 跨数小时、预算明确的实现 | Goal | 状态、预算、暂停/恢复 |
| 团队标准化重复流程 | Workflow | 脚本与 journal 可复用 |
13.23 源码阅读卡
| 目的 | 文件 |
|---|---|
| Task tool/depth | task/mod.rs |
| Subagent coordinator | mvp_agent/subagent_coordinator.rs |
| Spawn 实现 | agent/subagent/handle_request.rs |
| 角色/恢复解析 | xai-grok-subagent-resolution/src/lib.rs |
| Goal 状态 | goal_tracker.rs |
| Goal 执行集成 | acp_session_impl/goal.rs |
| Planner/Verifier | goal_planner.rs、goal_classifier.rs、goal_evaluator.rs |
| Workflow core | xai-workflow/src/engine.rs |
| Journal | xai-workflow/src/journal.rs |
| Session manager | session/workflow/manager.rs |
13.24 本章结论
长任务不能只有一种“递归调用模型”:
Subagent 提供有界的认知并行;Goal 用持久状态、预算和独立证据监督开放任务;Workflow 用脚本与 journal 保证确定编排可恢复。
下一章看这些内置机制之外,MCP、插件、Hook 与 Skill 如何构成扩展平台。