数据截至 (上游 commit a5ac26f27989)
检查点与多 agent
本章讲什么: 两个「带走就值回票价」的精华机制。一是检查点(checkpoint):agent 动手改代码前怎么打一个可回滚的快照,而且巧妙地不污染你的
git stash list。二是多 agent:spawn_agent怎么派生一个有独立人设的子 agent 去干专门的活。
一、检查点:用 git stash 做可回滚快照
1. 它要解决的小问题
agent 会自己改你的文件。万一它改砸了,你想一键回到「它动手之前」的样子。最自然的实现是用 git —— 但你不想让 agent 的快照塞满你的 git stash list,把你自己的 stash 工作流搞乱。
2. 思路:写进「私有 ref 命名空间」
实现是一组 hook,createCheckpointHooks(sdk/packages/core/src/hooks/checkpoint-hooks.ts:155)。关键技巧在 createCheckpoint(:177):
// 示意,非源码 —— 提炼自 checkpoint-hooks.ts:214-252
// ① 用 git stash create 生成一个快照 commit(但不真的入栈!)
const ref = await git("stash", "create", `cline checkpoint run=${runCount}`);
// ② 把这个 commit SHA 写进一个私有 ref 路径,而不是 refs/stash
const privateRef = `refs/cline/checkpoints/${sessionId}/${runCount}`;
await git("update-ref", privateRef, ref);
重点看为什么是 refs/cline/... 而不是 refs/stash(checkpoint-hooks.ts:230-236 的注释讲得很透):
git stash create只创建快照 commit,不像git stash push那样把它推进refs/stash(也就是git stash list显示的那个栈)。- 把这个 SHA 写进自定义的
refs/cline/checkpoints/<session>/<run>路径,有两个好处:- GC 安全 —— 有 ref 指着,git 不会回收这个 commit。
- 对用户隐形 —— 它不在
refs/stash里,所以git stash list看不到它,完全不打扰用户的 stash 工作流。
- 恢复时直接用那个 SHA 跑
git stash apply就行,无需特殊处理。
如果工作区不是 git 仓库或 stash 失败,有降级:退回记录当前 HEAD 的 SHA(createHeadCheckpoint,:190)。
3. 什么时候打快照:挂在 beforeModel
检查点是 01 章那套 hook 的实际应用。createCheckpointHooks 返回的对象挂两个 hook(checkpoint-hooks.ts:255-289):
| Hook | 条件 | 做什么 |
|---|---|---|
beforeRun | 非子 agent | runCount += 1(给本轮编号) |
beforeModel | 非子 agent && 本 run 的第 1 次迭代 | 打一个检查点,写进 session metadata |
注意它只在每个 run 的第一次模型调用前打一次(iteration === 1,:266),也只给顶层 agent 打(子 agent parentAgentId != null 直接跳过)。快照条目(CheckpointEntry:ref + createdAt + runCount + kind)记进会话元数据的 checkpoint.history(:280),供后续 diff / 恢复用(session/checkpoint-diff.ts、checkpoint-restore.ts)。
二、多 agent:派生子 agent
4. 它要解决的小问题
有些任务适合「分给一个专注的子手」去做 —— 比如让主 agent 专注规划,派一个子 agent 带着特定人设去搞定某个子任务,做完只把结果汇报回来。这就是 spawn_agent 工具。
5. 实现:子 agent 就是一个新的 agent 实例
createSpawnAgentTool(sdk/packages/core/src/extensions/tools/team/spawn-agent-tool.ts:117)造出一个工具,它的输入很简单 —— 一个 systemPrompt(子 agent 的人设)和一个 task(要它干的活):
// 示意,非源码 —— 提炼自 spawn-agent-tool.ts:124-182 的 execute
execute: async (input, context) => {
// ① 用父 agent 的 id 作为 parentAgentId,创建一个委派子 agent
const subAgent = createDelegatedAgent({
kind: "subagent",
prompt: input.systemPrompt, // 子 agent 的独立人设
tools, // 给它的工具子集
parentAgentId: context.agentId, // 记住谁是爹(检查点/事件据此区分)
abortSignal: context.signal, // 父被中止 → 子也中止
});
// ② 让子 agent 跑这个任务,等它跑完
const result = await subAgent.run(input.task);
// ③ 只把结果摘要(text + 迭代数 + 用量)汇报回父 agent
return { text: result.text, iterations: result.iterations, usage: {...} };
}
几个关键点:
- 子 agent 是一个完整独立的 agent 运行(
createDelegatedAgent,team/delegated-agent.ts),有自己的agentId/conversationId,跑自己的循环(01 章那套)。 parentAgentId = context.agentId(:144)建立父子关系 —— 检查点 hook 正是靠这个跳过子 agent(只给顶层打快照)。- 父子生命周期联动:把父的
context.signal传给子(:139),父被中止时子也跟着停。 - 子 agent 对父是黑盒:父只拿到
SpawnAgentOutput(摘要文本 + 用量),不会被子 agent 的完整中间过程淹没。这是 context 隔离 —— 子的几十轮探索压缩成一句结果。 - 有
onSubAgentStart/onSubAgentEnd观测回调(:145, 168),且这些回调出错被吞掉(best-effort),不会拖垮任务执行。
spawn_agent 默认在 Act / Plan 预设里开着(presets.ts 的 enableSpawnAgent: true)。更复杂的「组队」(team)能力在同目录的 team-tools.ts / multi-agent.ts,在此基础上做多 agent 协作与持久化。
6. 巧妙之处
- 检查点对用户隐形:
git stash create+ 私有 ref 命名空间,既 GC 安全又不污染git stash list(checkpoint-hooks.ts:230-236)。这是「借力 git 但不打扰用户」的典范。 - 检查点是纯 hook:不侵入内核,挂
beforeRun/beforeModel即可(:255),想关掉就不挂。 - 子 agent = 父 agent 的递归:复用同一套
AgentRuntime,父子关系用parentAgentId一个字段串起来,检查点/事件据此区分顶层与子层。 - 子 agent 结果即摘要:父只看到一句结论,天然做了 context 隔离,避免子 agent 的长探索撑爆父的上下文。
7. 边界与局限
- 检查点用
git stash create,只覆盖 git 跟踪范围内的工作区改动;非 git 仓库降级成只记HEAD(:190),回滚能力大打折扣。 - 子 agent 把结果压成一段文本汇报回父 —— 信息有损,父看不到子的中间推理细节。
spawn_agent有 5 分钟超时(timeoutMs: 300000,:200)且不可重试(retryable: false),长任务子 agent 会被截断。
8. 代码地图
| 主题 | 文件路径 | 符号名 |
|---|---|---|
| 检查点 hooks | sdk/packages/core/src/hooks/checkpoint-hooks.ts | createCheckpointHooks、createCheckpoint |
| 私有 ref 管理 | sdk/packages/core/src/hooks/checkpoint-hooks.ts | retainCheckpointRefs、deleteCheckpointRefs |
| 检查点 diff / 恢复 | sdk/packages/core/src/session/ | checkpoint-diff.ts、checkpoint-restore.ts |
| 派生子 agent 工具 | sdk/packages/core/src/extensions/tools/team/spawn-agent-tool.ts | createSpawnAgentTool、SpawnAgentInputSchema |
| 委派子 agent | sdk/packages/core/src/extensions/tools/team/delegated-agent.ts | createDelegatedAgent |
| 组队/多 agent | sdk/packages/core/src/extensions/tools/team/ | team-tools.ts、multi-agent.ts |