/ By 煎鱼 / #agent #Codex #SDD #Cookbook解读 / Markdown

Cookbook解读|Plan、Goal、Spec 为什么不能互相替代

结合 OpenAI Cookbook、Claude Code 与 GitHub Spec Kit 的官方资料,拆开 Plan Mode、执行计划、Goal、Spec、Skill 和仓库规则各自负责的工程边界。

给 Coding Agent 一个 Spec,让它先做 Plan,再开一个 Goal,最后还要准备 Skill 和 AGENTS.md——是不是把同一件事换了五种写法?

这个疑问很合理。它们都以自然语言出现,也都可能写着“必须运行测试”“不要改公共 API”。如果只看文件内容,确实像一叠互相抄作业的 Markdown。

问题在于,我们把不同层级的控制对象放进了同一个抽屉。OpenAI Cookbook 的 Using PLANS.md for multi-hour problem solvingUsing Goals in Codex,恰好从“路径”和“终点”两侧把这个抽屉拆开;GitHub Spec Kit 又补上了更上游的需求契约。

先说结论:

Spec 定义“要构建什么,以及不能破坏什么”;Goal 定义“当前任务凭什么可以停止”;Plan 记录“从现状走到目标的路径”;Skill 封装“同类任务以后怎样重复做”;AGENTS.mdCLAUDE.md 保存“在这个环境里长期遵守什么”。Validation 与 Eval 则提供证据,防止前面几份文档最后只剩下措辞正确。

它们会引用彼此,却不能互相替代。一个写得很细的 Plan 仍可能在实现错误需求;一个验收条件清晰的 Goal 也不会自动知道数据库迁移应该先做哪一步。

数据快照

  • 最后核验:2026-08-04
  • 主要对象:OpenAI Cookbook 的 ExecPlan 与 Codex Goal、OpenAI Codex 官方文档、Anthropic Claude Code 官方文档、GitHub Spec Kit 官方文档
  • 产品门槛:Codex Goals 从 0.128.0 起可用;Claude Code /goal 文档要求 2.1.139 或更高版本
  • 证据边界:本文比较公开的控制机制,不提供不同工作流的成功率、成本或质量排名

#第一个坑:Plan Mode、Plan 和 PLANS.md 不是一件事

讨论 Plan 之前,先要把三个同名对象分开。

#Plan Mode 是交互边界

Claude Code 的 Plan Mode 允许 Claude 读取文件、运行探索命令并提出修改方案,但不编辑源码;用户批准后才切换到实施阶段。Codex 的官方命令文档也把 /plan 描述为“在实现开始前提出执行计划”。

所以 Plan Mode 首先是一种交互与权限状态:先调查和设计,把修改推迟到审阅之后。它可以产出一份 Plan,但“现在处于 Plan Mode”和“仓库里存在一份长期计划文档”不是同一句话。

#Plan 是当前任务的路径

普通 Plan 回答的是:基于现在看到的代码,准备改哪些模块,按什么顺序推进,怎样验证,哪里有风险。

它可以很短:

1. 找出旧 OAuth 回调与 Session 写入位置
2. 增加 Provider Adapter,保留旧登录路径
3. 迁移 GitHub 回调并补集成测试
4. 运行认证测试与回归测试

路径依赖调查结果,因此允许改变。第二步发现用户表无法表达多个身份源,Plan 就应该更新,而不是为了证明自己“计划得很准”继续撞墙。

#PLANS.md 定义长期计划应该怎样写

OpenAI Cookbook 的 ExecPlan 又多了一层。PLANS.md 不是某个功能的具体计划,而是对计划文档本身的仓库级约定:什么时候需要 ExecPlan,它必须包含什么,执行过程中怎样维护。

Cookbook 要求 ExecPlan 自包含、面向不了解仓库的新手,并持续更新 ProgressSurprises & DiscoveriesDecision LogOutcomes & Retrospective。它既是设计文档,也是多小时任务的状态载体。文章甚至要求只拿到当前工作树和这一份 ExecPlan,也能继续推进。

这是一种适合长任务的 Cookbook 工作法,不是所有 Codex Plan 的强制格式。原文还带有当时的模型推荐;本文只采用它的计划模式,不把那条推荐当成 2026-08-04 的模型选择结论。

到这里可以先得到一个小结:Plan Mode 决定“现在先不修改”,Plan 决定“这次准备怎么改”,PLANS.md 决定“本仓库的长计划应该怎样写和维护”。三者相关,但作用域完全不同。

#Spec 与 Plan 的分界:先决定做对的东西,再决定怎样做

GitHub Spec Kit 的官方流程是 Spec → Plan → Tasks → Implement。它的命令定义也刻意把两步拆开:/speckit.specify 定义 Requirements 与 User Stories,/speckit.plan 才加入技术栈和实现方案。

这条边界比“Spec 更大、Plan 更细”准确:

  • Spec 约束产品行为、范围、非目标、兼容性和验收标准;
  • Plan 根据现有代码与技术约束,选择实现路径;
  • Tasks 再把路径切成可以执行和跟踪的工作单元。

例如“增加 GitHub OAuth 登录”,Spec 应该先回答:哪些用户能用,原有密码登录是否保留,账号冲突怎样处理,哪些场景不支持,什么行为算验收通过。至于使用哪一个 OAuth Library、用户表是否增加 Identity 表、Callback Route 放在哪个 Module,是 Plan 的问题。

如果把后者直接写进 Spec,技术方案一变,需求也跟着抖;如果把前者留给 Plan,Agent 可能交付一个实现精致、产品含义却完全不对的 GitHub 登录。

Spec 也不是越厚越好。一个只改错误文案的小任务,Prompt 里的两条约束已经可以充当 Spec-lite。只有当需求会跨团队、跨多轮或需要长期追踪时,独立 Spec 才开始值回维护成本。GitHub Spec Kit 展示的是一套完整 SDD 流程,不是每次提交都必须举行的开工仪式。

#Goal 与 Plan 的分界:一个固定终点,一个允许改路

Goal 最容易被误认为“更坚定的 Plan”。实际上,它不需要规定步骤。

OpenAI Cookbook 把 Codex Goal 定义为跨 Turn 持续存在的目标:结果应该是什么,用什么证据检查,哪些约束必须保持。路径不确定时,Codex 可以依据新证据继续选择下一步;完成条件成立、预算耗尽或遇到真实阻塞时,循环才结束。

因此,两者对变化的态度正好相反:

  • Goal 尽量稳定。测试失败不能靠降低门槛“解决”;
  • Plan 必须能变。新发现应该推动路线修订;
  • Evidence 每轮刷新。文件、测试、Benchmark 与产物决定离终点还有多远。

Claude Code 的 /goal 也体现了同一分工:当前 Agent 每完成一轮,独立的小模型根据 Goal 与对话证据回答 Yes 或 No,未满足就发起下一轮。它要求的不是步骤表,而是可验证的 Completion Condition。Claude 的 Plan Mode 则负责先研究和提出改法,二者可以同时使用,并不冲突。

Codex 与 Claude 的 Goal 如何判定完成,上一篇《Codex Goal 如何把“继续”变成完成协议》已经单独拆过。这里真正需要记住的是:Plan 可以因为证据改变,Goal 只能因为需求改变。 如果只是道路封闭,就换路线;如果连目的地都换了,那应该让用户重新确认任务,而不是悄悄更新计划。

#Skill 与仓库规则为什么放不进这条流水线

把 Spec、Goal 和 Plan 画成一条从需求到执行的链路还算自然,但 Skill 与 AGENTS.md 并不在链路的下一站。它们从侧面影响很多任务。

OpenAI 的 Codex 定制文档 将 Skill 定位为可复用能力:SKILL.md 可以带脚本、参考资料与资源,在匹配到某类任务时按需加载。一个“数据库迁移 Skill”可以规定先备份、再 Dry Run、记录 Schema Diff、执行迁移并检查回滚;下次迁移仍然能用。

AGENTS.md 则保存持久工作约定。官方的 AGENTS.md 文档 用包管理器、测试命令和添加生产依赖前确认等规则举例。这类约定会影响许多任务,却不描述某一个功能的需求,也不会因为某次任务完成而自动消失。Claude Code 里的 CLAUDE.md 在概念上承担相近的长期上下文角色。

一个简单判断是:

  • “这个 OAuth 功能必须保留密码登录”放进 Spec;
  • “所有认证改动必须运行 pnpm test:auth”放进 AGENTS.md
  • “以后做身份源迁移都按这套审计流程”做成 Skill;
  • “这一次具体修改哪些文件”写进 Plan;
  • “所有验收项满足且回归测试通过才停”写成 Goal。

如果同一句规则确实同时出现在两处,不一定是坏事。关键是确认它在每个位置承担什么责任:Spec 中的“不能改公共 API”是产品约束,Goal 中再次引用它是停止条件,Plan 中提到它是实施提醒,验证器则要真正检查它。

#六个对象如何在一次任务中配合

把这些对象放回一次真实工程任务,关系会比定义更清楚。

图 1:Spec、Goal 与 Plan 组成任务主循环;Skill 和仓库规则横向约束工作方式,Validation/Eval 把实现状态反馈给 Goal

flowchart LR
  S["Spec<br/>行为、边界、验收"] --> G["Goal<br/>当前完成条件"]
  S --> P["Plan<br/>实现路径"]
  G --> P
  P --> W["实施与调查"]
  W --> V["Validation / Eval<br/>测试、审阅、产物"]
  V --> D{"Goal 成立?"}
  D -->|"否"| P
  D -->|"是"| C["完成"]
  A["AGENTS.md / CLAUDE.md<br/>长期环境规则"] -.约束.-> P
  A -.约束.-> W
  K["Skill<br/>可复用工作流"] -.提供方法.-> P
  K -.提供方法.-> W

这张图不是强制流程。小任务可以把 Spec 和 Goal 压缩进一句 Prompt,也可以不创建持久 Plan。图里真正不能省略的是最后的证据回边:没有 Validation 或 Eval,Goal 只能听 Agent 自己描述进度,Spec 与 Plan 也无法知道实现是否偏离。

表 1:截至 2026-08-04 的职责对照;“生命周期”描述典型作用域,不代表所有工具都使用相同存储实现

对象核心问题典型生命周期OAuth 示例不能替代什么
Spec / SDD要构建什么,边界是什么功能或产品演进期间保留密码登录,不做账号自动合并实现路线、运行时续跑
Goal什么证据成立时才可以停当前 Task / Session认证验收与回归测试全部通过产品需求、详细步骤
Plan基于现状准备怎样实现当前任务,随发现更新Adapter、Migration、Callback、Test 的顺序需求决策、长期规则
Task List下一批可执行单元是什么一个 Milestone 或迭代拆出 Schema、Route、Test 工作项整体设计与完成协议
Skill同类任务以后怎样重复做跨 Task 复用身份迁移的审计与回滚流程本次功能需求与终态
AGENTS.md / CLAUDE.md在这个环境里长期守什么Repository、目录或用户范围包管理器、测试命令、禁改目录某个功能的 Spec

表里没有把 Validation/Eval 单列成一种文档,因为它更像证据层。测试、静态检查、人工 Review、Benchmark 和验收脚本可以被 Spec、Goal 与 Plan 同时引用,却不能被任何一段自然语言替代。

#不同规模的任务,最小组合也不同

这些对象不是集邮项目。更实用的选择方式,是从任务风险与反馈周期反推最小组合。

#一次性小改动:Prompt + 仓库规则 + 验证

改文案、修一个明确的 Null Pointer、补一条小测试,通常不值得先维护独立 Spec 与 ExecPlan。Prompt 说清楚预期和边界,Agent 遵守 AGENTS.md,最后运行对应检查即可。

#中型功能:Spec-lite + Plan + 验收

OAuth、缓存切换或一个跨模块 API,已经有多种合理实现。先写清用户行为、非目标和验收项,再让 Agent 在 Plan Mode 调查代码并提交方案。只要实现仍能由人掌控下一次决策,未必需要 Goal 自动续跑。

#长任务且路径不确定:Spec + Goal + Living Plan + Eval

大型迁移、性能调优、间歇性故障和研究复现,终点可以定义,路径却会被每轮证据改写。这正是 Goal 与 ExecPlan 同时有价值的场景:Goal 固定完成协议,Living Plan 保存当前路线、发现与决策,Eval 提供继续或停止的依据。

#反复出现的任务:把稳定部分提炼成 Skill

当第三次复制同一套发布、审计或迁移步骤时,再把稳定方法抽成 Skill。Skill 应复用流程,不应把上一次任务的业务目标一起封存。否则“可复用能力”很快会变成一份过期 Plan。

#最容易踩的四个替代错误

第一,用 Plan 代替 Spec。Agent 把文件、函数和步骤写得很具体,看起来已经想清楚了,但“用户到底要什么”仍然由实现者临场决定。

第二,用 Goal 代替 Plan。“所有测试通过”可以防止过早停止,却不会告诉 Agent 怎样迁移数据、怎样回滚,以及先验证哪个高风险假设。

第三,用 AGENTS.md 堆所有知识。长期规则会被一次性需求污染,真正每次都该遵守的命令反而淹没在大段功能背景里。

第四,把 Skill 当成完成证明。Skill 只能提高流程复用和执行一致性;它被正确调用,不代表本次产物已经通过验收。操作手册翻到了最后一页,机器不一定真的修好了。

#总结

Plan、Goal 与 Spec 看起来相似,是因为它们都需要描述目标、约束和验证;真正的区别不在 Markdown 语法,而在谁读取它、何时生效、允许怎样变化

Spec 是需求契约,应该在需求变化时更新;Goal 是当前任务的停止协议,应该在证据成立时完成;Plan 是可修订的路线,应该在新发现出现时改变。Skill 保存跨任务可复用的方法,AGENTS.mdCLAUDE.md 保存跨任务持续生效的环境规则。Validation 与 Eval 则负责让这些自然语言最终碰到现实。

下一次再遇到一个长任务,可以先问五个问题:用户行为是否已经写清,完成是否有可检查证据,路径是否需要先调查,流程以后会不会重复,哪些规则应该对整个仓库长期生效。答案会自然落到 Spec、Goal、Plan、Skill 和 AGENTS.md,而不是先建五个文件再往里填内容。

导航、终点、合同、操作手册和交通规则都很有用。麻烦通常不是缺少其中一个,而是拿着交通规则当地图,然后期待它告诉你什么时候已经到家。

#参考资料

Share this post

Diagram
100%