跳到主要内容

检查点与多 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> 路径,有两个好处:
    1. GC 安全 —— 有 ref 指着,git 不会回收这个 commit。
    2. 对用户隐形 —— 它不在 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非子 agentrunCount += 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.tscheckpoint-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.tsenableSpawnAgent: 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. 代码地图

主题文件路径符号名
检查点 hookssdk/packages/core/src/hooks/checkpoint-hooks.tscreateCheckpointHookscreateCheckpoint
私有 ref 管理sdk/packages/core/src/hooks/checkpoint-hooks.tsretainCheckpointRefsdeleteCheckpointRefs
检查点 diff / 恢复sdk/packages/core/src/session/checkpoint-diff.tscheckpoint-restore.ts
派生子 agent 工具sdk/packages/core/src/extensions/tools/team/spawn-agent-tool.tscreateSpawnAgentToolSpawnAgentInputSchema
委派子 agentsdk/packages/core/src/extensions/tools/team/delegated-agent.tscreateDelegatedAgent
组队/多 agentsdk/packages/core/src/extensions/tools/team/team-tools.tsmulti-agent.ts