原文出处:Using PLANS.md for multi-hour problem solving 原作者:OpenAI · 许可证:MIT License 中文译本由诸葛AI学院整理,仅供学习参考,版权归原作者与 OpenAI 所有。
用 PLANS.md 驱动数小时的复杂任务
Codex 搭配 gpt-5.2-codex 模型(推荐),可以完成那些需要花大量时间调研、设计和实现的复杂任务。本文介绍的这套做法,讲的是怎么用提示词让模型承接这类任务,并把它引向项目的成功交付。
这些计划文档既是详尽的设计文档,也是"活的文档"。作为 Codex 的用户,你可以在它开始漫长的实现过程之前,用这些文档检查它打算走的路子对不对。下文这份 PLANS.md,与那份让 Codex 凭一条提示词连续工作超过七小时的计划几乎一模一样。
要让 Codex 能用上这类文档,先更新 AGENTS.md,写清楚什么时候该用 PLANS.md,然后把 PLANS.md 文件加进仓库。
AGENTS.md
AGENTS.md 是一种简单的格式,用来给 Codex 这类编码智能体(coding agent)指路。这里我们定义一个用户可以当简称用的词,再配一条什么时候使用计划文档的简单规则。我们把它叫作"ExecPlan"(执行计划)。注意这是个随口的叫法,Codex 并没有针对这个词做过训练。给 Codex 写提示词时用这个简称,就能把它指向计划的某个特定定义。
下面是一段写在 AGENTS.md 里、告诉智能体什么时候该用计划的指令(原文为英文,供直接取用):
```md
ExecPlans
When writing complex features or significant refactors, use an ExecPlan (as described in .agent/PLANS.md) from design to implementation. ```
中文意思是:编写复杂功能或做重大重构时,从设计到实现都要使用 ExecPlan(定义见 .agent/PLANS.md)。
PLANS.md
下面是这份文档的全文。文中的提示词措辞是经过仔细挑选的,目的是给用户足量的反馈,并引导模型精确地按计划落实。你可以按需定制这个文件,增删必填章节。
~~~md
Codex 执行计划(ExecPlans):
本文档规定执行计划(简称 ExecPlan)的要求。执行计划是一份设计文档,编码智能体照着它做,就能交付一个可用的功能或系统改动。请把读者当成对这个仓库一无所知的人:他手里只有当前的工作目录,加上你提供的这一份 ExecPlan 文件。他没有以前任何计划的记忆,也没有外部上下文。
如何使用 ExecPlans 和 PLANS.md
撰写可执行规格(ExecPlan)时,逐字逐句遵守 PLANS.md。如果它不在你的上下文里,把整份 PLANS.md 重读一遍来唤起记忆。写规格时要 thoroughly(彻底)地阅读原始材料,反复读也无妨。创建规格时,先搭骨架,随着调研的深入再往里填肉。
实施可执行规格(ExecPlan)时,不要问用户"下一步做什么",直接推进到下一个里程碑。让所有章节保持最新,在每个停手点都增补或拆分列表条目,明确写出已经取得的进展和接下来的安排。遇到含糊的地方自己拿主意解决,频繁提交。
讨论可执行规格(ExecPlan)时,把决策记进规格里的日志,方便日后查考。要让人一眼看清楚规格为什么改。ExecPlan 是活的文档,同时任何时候都应当能做到:只凭这份 ExecPlan、不靠别的工作成果,就能重新开工。
当设计方案要求苛刻、未知因素很多时,借助里程碑去做验证用的小样,比如"玩具实现",用来检验用户的提议可行不可行。把依赖库的源代码找到或装来读,做深入调研,把原型一并收进来,为更完整的实现提供参照。
要求
不可妥协的要求:
- 每份 ExecPlan 必须完全自包含。自包含的意思是:以它现在的样子,就装下了新手成功干活所需的全部知识和指令。
- 每份 ExecPlan 都是活的文档。贡献者有义务随进展修订它:取得进展时要改,有新发现时要改,设计决策定案时也要改。每次修订后,它仍须完全自包含。
- 每份 ExecPlan 必须能让一个对本仓库毫无先验知识的完全新手,从头到尾把功能实现出来。
- 每份 ExecPlan 必须产出可演示、真正能用的行为,而不是只产出"满足定义"的代码改动。
- 每份 ExecPlan 里每个术语都要用大白话定义清楚,定义不了就别用它。
目的和意图先讲。开头用几句话,从用户的视角说明这件事为什么重要:改动完成之后,谁能做到什么以前做不到的事,怎么看出来它真的能跑。然后再带读者走一遍达成这个结果的确切步骤,包括改什么文件、跑什么命令、该看到什么现象。
执行计划的智能体能列文件、读文件、搜索、跑项目、跑测试。它不知道任何此前的上下文,也没法从早先的里程碑里猜你的意思。你依赖的每个假设都要重述一遍。不要指向外部的博客或文档;需要什么知识,就用自己的话写进计划里。如果一份 ExecPlan 建立在先前某份计划之上,而那份文件已经签入了仓库,就以引用的方式带进来;如果没签入,你必须把那份计划里所有相关的上下文都抄进来。
格式
格式和封装的规则简单而严格。每份 ExecPlan 必须是单独一个标注 md 的围栏代码块,以三个反引号开始和结束。块内不得再嵌套三个反引号的围栏;需要展示命令、终端记录、diff 或代码时,在这个围栏内用缩进块呈现。计划内部用缩进区分层次,别用嵌套围栏,以免提前关闭 ExecPlan 自己的代码块。每个标题后面空两行,层级用 # 和 ## 表示,有序和无序列表都要用正确的语法。
如果把 ExecPlan 写进一个 Markdown(.md)文件,且这个文件的内容只有这一份 ExecPlan,那就把外层三个反引号去掉。
用朴素的散文写作。能写句子就别列清单。避免清单、表格和长篇列举,除非求简练会丢掉意思。勾选清单只在 Progress(进展)一节允许使用,在那里还是强制要求的。叙述性章节必须以散文为主。
指南
自包含和大白话至高无上。引入一个不是日常英语的词(比如 "daemon"、"middleware"、"RPC gateway"、"filter graph")时,立刻定义它,并提醒读者它在这个仓库里以什么形式存在(例如点名它出现在哪些文件或命令里)。别说"如前文所定义"或"按架构文档说的办"。解释写在这里,哪怕重复。
避开常见的失败模式。不要依赖没定义的行话。不要把功能的"字面要求"抠得太死,以致代码能编译却什么都干不了。不要把关键决策外包给读者。存在歧义时,就在计划里把它解决掉,并说明你为什么选这条路。对用户可见的效果宁可解释过度,对无关紧要的实现细节宁可规定不足。
用可观察的结果锚定计划。写清楚实现之后用户能做什么、跑什么命令、应该看到什么输出。验收要写成人都能核实的行为("启动服务器后,访问 http://localhost:8080/health 返回 HTTP 200,响应体为 OK"),而不是内部属性("新增了一个 HealthCheck 结构体")。如果改动纯粹是内部的事,说明它的影响还能怎么演示出来,比如跑一个改动前失败、改动后通过的测试,再比如演示一个用上新行为的场景。
明确交代仓库上下文。文件用仓库相对路径的完整路径点名,函数和模块要指名道姓,新文件建在哪里也要说清。要动好几个区域时,加一小段导览,说明这些部分怎么衔接,让新手能自信地找到路。写命令时,标出工作目录和完整的命令行。结果依赖环境时,写清楚假设,合理的话给出替代方案。
步骤要幂等、安全。写出来的步骤要能在不造成破坏或漂移的前提下反复执行。某一步可能半途失败,就附上重试或变通的办法。非做不可迁移或破坏性操作时,把备份或安全回退写明白。优先做可测试的增量改动,边做边验证。
验证不是可选项。要包含跑测试的说明、(如果适用)启动系统的方法,以及观察系统做出有用之事的步骤。任何新功能或新能力,都要写全测试方案。给出预期输出和预期报错,让新手分得清成败。尽可能展示怎么证明改动有效,而不只是"能编译":一个小的端到端场景、一次命令行调用、一份 HTTP 请求/响应记录都行。写清楚与本项目工具链匹配的确切测试命令,以及怎么解读结果。
留下证据。步骤产生了终端输出、简短 diff 或日志时,把它们作为缩进示例放进那个唯一的代码块里。要精简,只留能证明成功的内容。需要放补丁时,优先用限定到单个文件的 diff 或小片段;读者照你的说明能自己复现的,就不要粘贴大块内容。
里程碑
里程碑是叙事,不是官僚流程。把工程拆成里程碑时,每个里程碑先用一小段开场:范围是什么,这一段做完会多出什么此前没有的东西,跑什么命令,你预期达到什么验收。让它像故事一样可读:目标、干活、结果、证明。Progress(进展)和里程碑是两回事:里程碑讲故事,进展记细账,两者都得有。绝不为了简短而砍掉里程碑内容,对未来实现可能关键的细节不许省略。
每个里程碑必须能独立验证,并且整体目标的推进要靠它一点点完成。
活文档与设计决策
- ExecPlan 是活的文档。做出关键设计决策时,更新计划,把决策和背后的思考一起记下来。所有决策都记入
Decision Log(决策日志)一节。 - ExecPlan 必须包含并持续维护四个章节:
Progress(进展)、Surprises & Discoveries(意外与发现)、Decision Log(决策日志)、Outcomes & Retrospective(成果与复盘)。这四节不是可选的。 - 实现过程中发现了优化器行为、性能取舍、意外 bug,或影响你方案的反向/撤销语义,把这些观察记进
Surprises & Discoveries一节,配上简短证据(测试输出最好)。 - 如果在实现中途改变方向,把原因写进
Decision Log,并把由此产生的影响一并写进Progress。计划既是给你自己用的清单,也是给下一位贡献者用的指南。 - 完成一个大任务或整份计划时,写一篇
Outcomes & Retrospective:做成了什么、还欠着什么、学到什么。把结果对照最初的目的。
原型里程碑与并行实现
在计划里安排明确的原型里程碑是可以的,常常还值得鼓励:它们能给大改动降风险。例子:给某个依赖库加一个底层算子来验证可行性,或者在测量优化器影响的同时探索两种组合顺序。原型保持增量、可测试。把范围标明是"原型"(prototyping),写清怎么运行、怎么看结果,并说明把它转正或丢弃的判据。
优先做加法式的代码改动,之后再做减法,全程保持测试通过。并行实现(比如迁移期间让一个适配器与旧路径并存)在能降低风险、或能让测试在大迁移期间持续通过时完全可行。写清楚两条路径各自怎么验证,以及怎么安全地用测试护送旧路径退役。涉及多个新库或新功能区域时,可以考虑做若干独立的技术探针(spike),让它们彼此独立地评估可行性:单独验证外部库表现符合预期、单独验证它实现了我们需要的功能。
一份好 ExecPlan 的骨架
# <简短、以动作导向的标题>
这份 ExecPlan 是活的文档。`Progress`、`Surprises & Discoveries`、`Decision Log`、`Outcomes & Retrospective` 四个章节必须随工作推进保持更新。
如果 PLANS.md 文件已签入仓库,在这里写上它从仓库根算起的路径,并注明本文档须按照 PLANS.md 的要求维护。
## 目的 / 全景(Purpose / Big Picture)
用几句话说明这次改动之后能收获什么、怎么看它在工作。写出你要解锁的用户可见行为。
## 进展(Progress)
用带勾选框的列表归纳细粒度步骤。每个停手点都必须记在这里,哪怕要把一个没做完的任务拆成两条("已完成"与"未完成")。这一节必须始终是工作的真实现状。
- [x] (2025-10-01 13:00Z) 已完成步骤的示例。
- [ ] 未完成步骤的示例。
- [ ] 部分完成步骤的示例(已完成:X;未完成:Y)。
用时间戳来度量推进速度。
## 意外与发现(Surprises & Discoveries)
记录实现过程中发现的意外行为、bug、优化点或洞见。附上简短证据。
- 观察:…
证据:…
## 决策日志(Decision Log)
按计划工作时做出的每个决策都按下面的格式记录:
- 决策:…
理由:…
日期/作者:…
## 成果与复盘(Outcomes & Retrospective)
在重大里程碑或完工时,总结成果、差距与教训。把结果对照最初的目的。
## 背景与导览(Context and Orientation)
假设读者一无所知,描述与本任务相关的现状。用完整路径点名关键文件和模块,定义你会用到的每个不言自明的术语。不要引用先前的计划。
## 工作方案(Plan of Work)
用散文描述编辑与新增的先后顺序。每次改动,点明文件、位置(函数、模块)以及要插入或修改什么。具体、精简。
## 具体步骤(Concrete Steps)
写出要跑的确切命令和运行位置(工作目录)。命令会产生输出的,附一段简短的预期记录供读者比对。这一节必须随工作推进更新。
## 验证与验收(Validation and Acceptance)
说明怎么启动或操练系统、观察什么。验收写成行为,带上具体的输入和输出。涉及测试的话,写"运行 <项目的测试命令>,预期 <N> 条通过;新测试 <名称> 在改动前失败、改动后通过"。
## 幂等与恢复(Idempotence and Recovery)
步骤能安全重复的,直说。哪一步有风险,给出安全的重试或回滚路径。完工后让环境保持干净。
## 工件与备注(Artifacts and Notes)
把最重要的终端记录、diff 或片段作为缩进示例附在这里。精简,只留能证明成功的内容。
## 接口与依赖(Interfaces and Dependencies)
要给出明确规定。点名用哪些库、模块、服务,以及为什么。指定里程碑结束时必须存在的类型、trait/接口和函数签名。优先使用稳定、可寻址的名字和路径,如 `crate::module::function` 或 `package.submodule.Interface`。例如:
在 crates/foo/planner.rs 中定义:
pub trait Planner {
fn plan(&self, observed: &Observed) -> Vec<Action>;
}
照着上面的指南写,一个没有记忆的单一智能体,或者一个人类新手,就能从头到尾读完你的 ExecPlan,做出一个能工作、可观察的结果。标准就是这个:自包含、自给自足、新手可照做、以结果为导向。
修订计划时,必须确保改动在所有章节都得到全面的落实,包括那几个活文档章节,并在计划末尾写一条说明,讲清改了什么、为什么改。ExecPlan 几乎对每件事都要写清楚"是什么"之外的"为什么"。 ~~~