《Claude Code 源码解析系列》第15章|业界 Plan(选修)
对比业界 Agent 的 Plan 设计,理解规划如何从提示词演进为执行控制面。
《Claude Code 源码解析系列》第15章|业界 Plan(选修)
上一节我们拆了 Claude Code 自己的 Plan Mode:EnterPlanModeTool 负责进入只读阶段,ExitPlanModeTool 负责提交计划和恢复权限,Plan subagent 负责把代码库研究隔离出去,验证 hook 再把计划变成执行后的检查基准。
这一节换一个角度:
跳出 Claude Code 来看,业界其他 Agent 系统是怎么设计 Plan 的?
这个问题很容易被讲成厂商功能对比:
- Claude Code 有 Plan Mode、Plan subagent、permission mode。
- Codex 有
/plan、Chat/Agent 模式、AGENTS.md、subagents、approvals 和 sandbox。 - Gemini Deep Research 有 collaborative planning,可以先返回研究计划,用户调整后再执行。
- Gemini ADK 还有 Sequential / Parallel / Loop / Graph workflow,把流程编排做成确定性工作流。
- OpenAI Agents SDK 有
Agent.as_tool()、handoffs,以及由代码编排 agent 的模式。
但如果只记这些名词,读完还是会糊。
因为 Plan 真正解决的不是:
模型能不能写一份计划?
而是:
在 Agent 动手之前,系统如何先界定范围、收集证据、暴露风险、获得批准,
并把后续执行约束在这份计划里?
这篇的核心观点是:
现代 Agent 里的 Plan,越来越不像“提示词里的先想想”,而像一层执行控制面。
为了不飘,我们继续沿用上一节的例子:
用户要求:给 REST API 加分页。
这个任务看起来不大。但真实项目里,它可能涉及路由层、ORM(对象关系映射,把数据库表映射成代码对象的层)、响应格式、参数校验、前端调用、测试、兼容策略和性能边界。
Agent 如果直接动手,很容易过早落到某个实现方案里。
Plan 的价值,就是在写代码之前,先把这些不确定性摊开。
一、先把问题链拉直
Plan 模块不是因为模型不会“列步骤”才出现的。
相反,模型太会列步骤了。你让它写计划,它几乎一定能写出:
1. 分析需求
2. 修改接口
3. 添加测试
4. 运行验证
这种计划没什么错,但也没什么用。
它没有回答真正危险的问题:
分页用 offset 还是 cursor?
项目已有分页约定吗?
响应结构能不能改?
旧客户端会不会受影响?
哪些查询必须加索引?
哪些测试能证明没有破坏兼容性?
所以 Plan 的问题演化链大概是这样:
单轮聊天可以直接回答问题
-> Agent 开始能读文件、改代码、跑命令
-> 过早执行会带来真实副作用
-> 于是需要执行前的只读研究阶段
-> 只读研究会产生大量上下文噪声
-> 于是需要隔离研究上下文或显式计划对象
-> 计划仍可能和用户预期不一致
-> 于是需要批准门和可修改的计划
-> 执行阶段可能偏离原计划
-> 于是需要验证、恢复和回滚依据
这条链说明,Plan 不是一个孤立模块。它天然会牵出五样东西:
只读工具
上下文管理
计划对象
人类审批
执行验证
业界差异主要不在“有没有 Plan”。
区别在于:各家把这五件事放在了系统的哪一层。
(有的放在 prompt 层,有的放在运行时权限层,有的做成 API 协议状态。后面会看到,这直接决定了一个系统的工程成熟度。)
二、共同结构:Plan 层通常夹在目标和执行之间
不管是 Claude Code、Codex,还是 Gemini,Plan 层大体都在做这件事:
用户目标
-> 计划层
-> 范围界定
-> 只读研究
-> 方案比较
-> 风险声明
-> 计划输出
-> 批准门
-> 执行层
-> 验证层
把它画成最小状态机:
Scope -> Research -> DraftPlan -> Review -> Execute -> Validate
其中 Review 是最容易被低估的一步。
很多 demo 里的 Agent 会直接:
目标 -> 计划 -> 执行
但真实工程里,中间必须有一层:
目标 -> 计划 -> 人类/策略批准 -> 执行
为什么?
因为 Plan 阶段经常会暴露取舍:
分页要不要兼容旧参数?
是否允许改响应字段?
是否要顺手重构查询层?
要不要同时补前端调用?
测试覆盖到什么粒度?
这些不是模型智力问题,是产品和工程边界问题。
说白了,一个好的 Plan 系统,应该把这些取舍显式摆出来,而不是替用户悄悄拍板。
(替用户拍板的后果:上线后前端炸了,产品经理问你“谁让改响应格式的”,你只能沉默。)
三、Claude Code:把 Plan 做成只读研究和权限边界
上一节已经拆过 Claude Code 的 Plan Mode。放到业界对比里看,它最鲜明的特点是:
Claude Code 把 Plan 放在运行时权限层和子 Agent 研究层。
它不是只靠 prompt 说“请先计划”。
而是把 Plan Mode 变成权限状态。进入 Plan Mode 后,写文件、编辑、危险命令这些动作会被限制;如果需要理解代码库,系统还可以把研究委派给内置 Plan subagent。
这套设计特别适合 coding agent。
因为写代码最大的风险就是:还没看清项目,就开始改项目。
用分页例子来看,Claude Code 的理想链路是:
用户:给 REST API 加分页
-> 进入 Plan Mode
-> Plan subagent 只读搜索已有接口、响应格式、ORM 写法、测试结构
-> 主线程综合研究结果
-> 提出 offset / cursor / 兼容策略
-> 用户批准
-> 恢复可写权限
-> 执行并验证
这里 Plan subagent 的价值不只是“并行搜索”。
更重要的是上下文卫生:大量搜索路径、无关文件、排除过程不会全部污染主线程。主线程拿到的是研究结论,而不是一大坨探索噪声。
所以 Claude Code 的 Plan 哲学可以概括成:
先把 Agent 关进只读房间里,让它看清楚,再放它出来干活。
优点是安全、克制、适合代码库探索。
它的边界是:公开资料里并没有看到一个固定的 plan schema 或中央 planner AST(抽象语法树,代码结构的树形中间表示)。
也就是说,Claude Code 更像是把 Plan 做成运行时阶段,而不是做成结构化计划协议。
四、Codex:把 Plan 做成交互控制面和工程工作流
Codex 的味道不太一样。
如果说 Claude Code 的重点是“只读研究 + 权限模式”,Codex 更像是把 Plan 放在:
交互模式
+ 项目指令
+ 任务清单
+ subagent 编排
+ approval / sandbox
Codex CLI 里有 /plan:切到 plan mode,让 Codex 先提出执行计划,再进入实现。
Codex 还会在开始工作前读取 AGENTS.md 指令链,把全局规则、项目规则、当前目录规则拼起来。
于是 Plan 阶段看到的不只是用户一句话,还有项目自己的工作协议。
这很关键。
同样是“给 REST API 加分页”,裸模型看到的是:
加分页。
Codex 的 Plan 阶段可能同时看到:
用户目标:给 REST API 加分页
AGENTS.md:所有接口必须保持 backward compatible
AGENTS.md:API 参数校验统一用 Zod
AGENTS.md:修改后必须运行 npm test 和 typecheck
当前目录规则:users service 不允许直接访问数据库
这时计划就不再是模型临时想出来的步骤,而是用户目标和项目制度合成后的执行蓝图。
Codex 的第二个特点,是把 Plan 和协作绑得很紧。
官方 subagents 文档说明,Codex 可以生成多个 specialized agents 并行工作,再把结果汇总到一个响应里。但它也强调,Codex 只会在用户明确要求时 spawn subagents。
这说明 Codex 的多 Agent 不是自由生长,而是受中心运行时控制的 fan-out / fan-in。
放到 Plan 里,就是:
用户目标
-> /plan 先确定大方向
-> 需要时显式派 explorer / reviewer / worker 并行研究
-> 子结果回流主线程
-> 主线程更新计划
-> 用户批准后执行
Codex 的第三个特点,是 approval 和 sandbox 很靠前。
Plan 不是写完就算,而是会继续受执行环境约束:
approval policy 决定哪些动作要问用户
sandbox 决定能读写哪些目录、能不能联网
subagent 继承父级的执行边界
非交互任务遇到无法批准的高风险动作,应失败并回传错误
所以 Codex 的 Plan 更像一个工程控制面:
先计划
-> 再按项目规则约束
-> 再决定是否分派子 Agent
-> 再经过审批和沙箱
-> 最后执行和汇总
优点是工程化强,适合长任务、PR 修改、代码审查和团队规范明确的项目。
边界同样存在:公开资料没有说明内部使用了什么符号规划器、树搜索或可复现的 planner 算法。我们能确定的是它的外部控制面,而不是隐藏推理机制。
一句话概括 Codex:
Codex 的 Plan 不是“先想完再做”,而是“先把目标、规则、权限、分工和验证方式装配好,再做”。
五、OpenAI Agents SDK:Plan 可以交给模型,也可以交给代码
Codex 偏产品和工程工作流。OpenAI Agents SDK 则把另一个问题暴露得更清楚:
Agent 的流程到底应该由模型决定,还是由代码决定?
Agents SDK 的 orchestration 文档把编排分成两类:
LLM orchestration:让模型自己规划、调用工具、handoff 给 specialist。
Code orchestration:由代码决定流程、顺序、并行、循环和终止条件。
这对 Plan 很重要。
很多人一说 Plan,就默认“让模型多推理”。但生产系统经常不能把所有流程都交给模型。
比如分页任务可以让模型研究方案,但下面这些控制点最好由代码或运行时掌握:
先读后写
必须先跑现有测试
必须等待用户批准
禁止同时修改 schema 和前端
失败时回到 plan review
Agents SDK 里的两个经典模式,也可以理解成 Plan 执行方式的分叉:
Agents as tools:
manager 保留控制权,把 specialist 当工具调用。
Handoffs:
triage agent 把控制权交给 specialist,让 specialist 接手下一段流程。
前者适合计划中的局部子任务。比如“让安全 reviewer 看一下分页参数有没有注入风险”。
后者适合真正换角色。比如“从需求澄清 agent 交给实现 agent”。
所以 SDK 层给我们的启发是:
Plan 不一定都要写在自然语言里。
能确定的流程,用代码固定;
需要判断的部分,交给模型规划;
高风险动作,放到人类审批门后面。
这也是很多 Agent 系统会从“一个大 prompt”演化到“LLM + workflow graph + guardrails”的原因。
(说白了,prompt 不够用了。真正管用的不是提示词写得长,而是运行时知道什么时候该拦、什么时候该放。)
六、Gemini:把 Plan 暴露成 API 状态机
Gemini Deep Research 的 collaborative planning,是目前公开资料里最像“Plan 协议”的设计之一。
它不是简单告诉模型“先计划”。它把计划拆成三个 API 阶段:
Step 1:设置 collaborative_planning=true,请求研究计划
Step 2:用 previous_interaction_id 继续 refine,仍停留在 planning mode
Step 3:设置 collaborative_planning=false 或省略,表示批准并开始执行
这很干净。
用户不是在一个聊天框里凭感觉说“可以了”。而是通过同一个 interaction 链条,把计划从“草案”推进到“批准执行”。
用分页例子类比一下:
第一次 interaction:
请研究 API 分页改造方案,只返回计划。
第二次 interaction:
计划里减少前端改动,优先兼容旧参数。
第三次 interaction:
计划确认,开始执行。
当然,Gemini Deep Research 主要面向研究任务,不是直接改代码的 coding agent。
但它对 Plan 模块的启发非常强:
Plan 可以成为协议级状态,而不是对话里的临时文本。
Gemini ADK 又补了另一层:workflow agents。
ADK 的 Workflow Agents 包括 Sequential、Parallel、Loop 等类型。它们不是靠 LLM 动态决定流程,而是用预定义逻辑控制子 agent 的执行顺序。
这说明 Gemini 生态把 planning 拆成两层:
模型层:负责理解、推理、生成或修订计划。
工作流层:负责把确定流程固化成顺序、并行、循环或图。
这非常适合生产系统。
比如分页改造可以这样拆:
Sequential:
inspect existing API conventions
draft migration plan
wait for approval
implement backend
run tests
Parallel:
reviewer checks compatibility
reviewer checks performance
reviewer checks API docs
Loop:
run tests -> fix failures -> run tests
until tests pass or retry limit reached
这时 Plan 不再只是一个 Markdown 列表,而是能驱动执行图的结构。
一句话概括 Gemini:
Gemini 的公开设计更强调把 Plan 变成可交互、可续写、可批准的 API 会话;ADK 则把确定流程从模型里拿出来,变成可预测的 workflow。
七、把三种设计放到一张表里
如果把 Claude Code、Codex、Gemini 放在一起看,差异就比较清楚了:
| 系统 | Plan 的主要落点 | 最强能力 | 适合场景 | 主要边界 |
|---|---|---|---|---|
| Claude Code | Plan Mode + Plan subagent + permission mode | 只读研究、上下文隔离、权限边界 | 代码库探索、复杂修改前的安全规划 | 公开层面更偏运行时阶段,不强调固定 plan schema |
| Codex | /plan / Chat / Agent 模式 + AGENTS.md + subagents + approvals/sandbox | 工程工作流、项目规则注入、中心化编排 | PR 修改、代码审查、长任务执行、团队规范项目 | 公开资料主要暴露控制面,不暴露内部 planner 算法 |
| Gemini Deep Research | collaborative planning + Interactions API | 计划、修订、批准三段式状态机 | 长研究任务、报告生成、需要人类调整研究范围的任务 | 主要面向研究 agent,不是直接 coding runtime |
| Gemini ADK | Workflow Agents / Graph workflow | 确定性流程、顺序/并行/循环编排 | 生产级 agent workflow、多步骤平台能力 | 开发复杂度更高,需要把流程显式建模 |
这张表背后有个更重要的结论:
Claude 把 Plan 做成权限边界。
Codex 把 Plan 做成工程控制面。
Gemini 把 Plan 做成 API 状态机和 workflow。
三者不是谁替代谁,而是在不同层解决同一个问题。
八、不要把 Plan 神秘化成隐藏算法
这里要特别补一个边界。
很多人会问:
这些系统是不是用了 MCTS?
是不是有符号规划器?
是不是有一套隐藏的 planner AST?
从公开资料看,最稳妥的说法是:不能这么假设。
Claude、Codex、Gemini 都强调 reasoning、thinking、agent loop、tool use、subagents、workflow,但公开文档并没有把它们的 Plan 模块描述成某个可复现的 classical planner。
所以我们在读这些系统时,不要把 Plan 想成:
一个神秘 planner 算法
更应该把它想成:
提示驱动的规划
+ 只读证据搜集
+ 显式状态
+ 工具权限
+ 人类审批
+ 执行验证
这反而更有工程价值。
因为你自己实现 Agent Harness 时,真正能复用的不是“猜厂商内部怎么想”,而是这些公开可观察的控制面。
九、如果自己实现 Plan,可以抽成四层
如果我们不照抄任何一家,只抽象业界共同设计,一个最小但靠谱的 Plan 系统可以拆成四层。
第一层,模式层。
mode = chat | plan | execute
小问题直接回答;复杂任务先进入 plan;用户批准后才 execute。
第二层,工具层。
plan mode:
allow: read, search, inspect, safe command
deny: write, edit, delete, mutating shell, external side effects
execute mode:
allow according to approval policy and sandbox
不要只靠 prompt 约束模型。运行时必须知道当前阶段能不能产生副作用。
第三层,计划对象层。
{
"goal": "给 REST API 加分页",
"assumptions": ["保持旧参数兼容"],
"evidence": ["已有列表接口使用 limit/offset"],
"steps": [
"确认响应格式",
"修改 users route",
"补参数校验",
"补测试",
"运行 test 和 typecheck"
],
"risks": ["响应结构变化可能影响前端"],
"validation": ["现有测试通过", "新增分页测试通过"]
}
计划对象不一定非要 JSON,也可以是 Markdown、任务表、ExecPlan 或 workflow graph。
关键是它要能被恢复、被审查、被执行阶段引用。
第四层,审批和验证层。
DraftPlan
-> 用户修改 / 批准
-> Execute
-> Validate(actual_diff, approved_plan)
-> 完成 / 回到 Plan
没有审批,Plan 容易变成模型自说自话。
没有验证,Plan 容易变成执行前的仪式。
十、回到 Claude Code:为什么这章放在 Plan 后面
理解业界做法以后,再回头看 Claude Code 的 Plan Mode,就更容易看出它的定位。
Claude Code 并没有把 Plan 做成最复杂的协议,也没有把它做成一张显式 workflow graph。
它选择的是 coding agent 里最关键的一刀:
执行前先只读。
这刀看起来朴素,但非常有效。
因为对代码工具来说,最大风险不是模型不会想,而是它太快开始改。只读 Plan Mode、Plan subagent、权限恢复、计划持久化、验证 hook,这些机制合起来,就是把“先理解,再行动”从模型自觉升级成运行时制度。
Codex 和 Gemini 则提醒我们:当任务从“本地代码修改”走向“团队工程流程”或“长时研究工作流”时,Plan 还会继续长出新的形态:
Codex:项目规则 + subagent 编排 + approval/sandbox
Gemini:collaborative planning API + workflow graph
所以,Plan 的终局不是“让模型写更漂亮的计划”,而是:
把不确定性前置,把副作用后置,把用户决策放回关键门口,把执行结果拉回计划验证。
这也是现代 Agent Harness 和普通聊天机器人的分界线之一。