我的 Codex 最佳实践:把一句需求变成可验收的工程结果
从任务契约、Plan、AGENTS.md、Skills、线程与 Worktree,到 Goal、Review 和 Automation,整理一套适合日常开发的 Codex 协作方法。
我最早使用 Codex 时,习惯把它当成一个更能干的聊天框:描述需求,等它生成代码,哪里不对再补一句。简单修改通常没有问题,任务一复杂,结果就开始不稳定。它可能正确地修改了错误的模块,也可能完成主要逻辑,却漏掉构建、移动端和旧数据兼容。
后来我用 Codex 搭建并持续修改这个博客。从项目初始化、页面布局、文章专栏、域名部署,到长文写作和图片制作,同一个项目里既有代码任务,也有内容任务和浏览器操作。这段过程让我意识到,代码生成能力很少成为限制。结果更多取决于工作环境:它这一轮能看到什么,哪些决定已经确定,哪里不能动,以及用什么证据判断完成。
我现在使用 Codex 的基本方法可以压缩成一句话:
先把任务变成一份可执行的契约,再让 Agent 在真实反馈中循环,直到证据说明它已经完成。
这篇文章记录我的具体做法。它不是一套必须照抄的仪式。小改动直接做,复杂任务才增加 Plan、状态文件、Worktree 或 Goal。流程的重量应当跟着不确定性增长。
一、先写任务契约,不追求万能 Prompt
我以前会花时间润色 Prompt,希望靠措辞让模型一次答对。现在我更关心五件事:
Outcome 最后要得到什么结果
Context 这次优先看哪些事实
Boundaries 哪些地方不能动
Evidence 用什么证明已经完成
Escalation 遇到什么情况必须停下来问我
例如,“把文章页优化一下”几乎把所有决定都留给了 Codex。更可执行的版本会像这样:
目标:调整文章页的桌面布局,让正文保持主视觉中心。
上下文:
- 页面模板在 src/layouts/PostLayout.astro;
- 左侧是专栏目录,右侧是文章目录;
- 参考当前 RAG 文章的实际页面。
边界:
- 不改移动端结构;
- 不改变文章 Markdown 格式;
- 不引入新的 UI 依赖;
- 保留目录滚动高亮。
完成条件:
- 1440px 和 1920px 下两侧留白更均衡;
- 目录与正文不重叠;
- npm run build 通过;
- 打开一篇长文,检查顶部、正文中段和文章末尾。
如果需要重写整个布局组件,先说明原因和影响,不要直接实现。
这类任务描述没有什么神奇句式。它只是把隐含信息搬到了 Codex 能读到的地方。目标控制方向,上下文减少无效搜索,边界避免顺手重构,完成条件给出停止标准,升级条件保留需要人判断的决策。
我不再要求每条 Prompt 都覆盖整个项目。当前模型已经能主动浏览仓库,重复塞入大量背景会挤占有用的上下文。只提供本次任务最可能需要的入口,其余部分让 Codex 按证据继续查找。
二、复杂任务先 Plan,但不要为了 Plan 而 Plan
以下任务适合先规划:
- 需求有多种合理解释;
- 会修改多个模块或公共接口;
- 需要兼顾兼容、迁移或回滚;
- 我还不确定根因,只知道现象;
- 执行时间会跨越多个检查点。
Plan 阶段我希望 Codex 回答四个问题:
- 当前系统实际上怎样工作?
- 哪些事实已经确认,哪些仍是推测?
- 有哪些实现选择,需要我决定什么?
- 每一步如何验证,失败后如何退回?
我常用的起手式是:
先不要改代码。
读取相关实现,梳理当前链路,并列出仍然影响方案的不确定项。
给出一个推荐方案和必要的备选方案,说明改动范围、兼容风险、
验证方式和回滚路径。只有会显著改变行为或范围的问题才问我,
其余问题基于仓库证据给出默认判断。
“先不要改代码”只适合尚未完成方案对齐的阶段。计划已经清楚后,我会明确让它继续实现和验证,避免 Codex 把每个安全的小决定都重新抛回来。
小任务则直接做。改一个错别字、调整一个已确定的 CSS 值、补一条原因明确的测试,不需要生成一份正式计划。OpenAI 在近期 Codex 指南里也反复强调精简上下文:更强的模型并不需要在每次修改前阅读全部架构资料,也不需要为局部改动执行一整套重型流程。
三、AGENTS.md 只放长期有效的协作规则
Prompt 只负责本次任务,AGENTS.md 保存反复出现的仓库约定。例如:
# Repository guide
## Structure
- src/content/posts/:文章正文
- src/config/sections.ts:专栏和二级分类的唯一配置入口
- public/images/posts/:文章配图
## Validation
- 修改代码或内容后运行 npm run build
- 改动文章布局时检查一篇短文和一篇长文
## Boundaries
- 不改写已有文章,除非任务明确要求
- 不覆盖用户未提交的修改
- 不新增依赖,除非现有方案无法完成任务
## Context routes
- 涉及部署时读取 docs/deployment.md
- 涉及文章排版时读取 docs/article-layout.md
它更像仓库里的路由表和协作协议,不是知识百科。适合写进去的内容包括:
- 目录职责和权威配置入口;
- 常用构建、测试、Lint 命令;
- 不能轻易跨越的系统边界;
- 代码风格之外的工程习惯;
- 不同任务应该读取哪份专题文档。
不要把一次需求的实现细节永久写入 AGENTS.md,也不要强制所有任务阅读全部文档。OpenAI 近期对 AGENTS.md 的建议很直接:说明文档在什么场景下需要读取,比要求每次都完整读取更节省上下文。
我的维护规则很朴素。如果 Codex 因为缺少同一条仓库事实连续犯错,我才考虑把它写进 AGENTS.md。如果某条规则已经过期,或者模型通过代码就能轻易判断,我会删掉它。规则数量不是成熟度指标。
四、Skills 保存方法,项目文档保存事实
我一开始很容易把 Skill 理解成“更长的 Prompt”。使用一段时间后,两者的边界越来越清楚。
项目文档记录这个仓库的事实,例如模块结构、业务约束和部署方式。Skill 记录一类任务应该怎样完成,例如:
- 技术文章如何调研、写作和检查引用;
- UI 修改如何截图、比较断点并做视觉验收;
- 故障排查如何收集证据、定位根因和验证修复;
- 数据库迁移如何检查兼容性并准备回滚。
一份实用 Skill 通常不只有 SKILL.md:
article-writing/
├── SKILL.md
├── references/
│ ├── style-guide.md
│ └── source-policy.md
├── scripts/
│ └── check-links.sh
└── assets/
└── article-template.md
主文件只说明触发条件和流程路由,需要时再读取 reference、运行 script、复用 asset。这种渐进式加载比一个塞满所有细节的 Skill 更稳定。
我判断一个流程是否值得做成 Skill,会看三个条件:它是否重复出现,步骤是否已经跑通,结果能否验证。还在探索的方法先留在普通线程里。没有验证过的流程过早封装,只会让错误变得更容易重复。
五、一个线程只承载一个可以收口的目标
线程不是越长越有上下文。长线程会同时积累有效决定、废弃方案、临时猜测和已经修复的错误。当任务目标变化后,这些历史内容仍可能影响下一次判断。
我现在按“可验收结果”划分线程,而不是按项目划分线程。同一个博客项目可以有这些独立线程:
调整文章页三栏布局
撰写 SDD 文章并加入 AI Coding 专栏
接入自定义域名
审查本轮改动并修复移动端回归
它们共享仓库,却有不同的完成条件。混在一起后,UI 讨论、文章素材和部署状态会互相污染。
以下信号出现时,我倾向于新开线程或从当前线程 fork:
- 目标从分析变成实现,或者从实现变成独立 Review;
- 改动文件集合明显变化;
- 原有边界被推翻,需要重新做方案;
- 连续几轮都在解释“不是这个意思”;
- 已经无法用一句话说明当前完成条件。
线程切换前,把仍然有效的信息写进仓库。需要保存的是结论和当前状态,不是完整聊天记录。
六、长任务把状态写到线程之外
普通任务依靠 Git diff、测试和任务列表已经足够。跨越多轮、多个里程碑的任务,需要一份可以重新进入的状态记录。
我会使用轻量的 STATUS.md:
# 当前状态
## 已完成
- 确认文章目录由 IntersectionObserver 驱动高亮
- 修复点击标题后 URL 锚点不随滚动更新的问题
## 验证
- npm run build 通过
- RAG 和 Harness 两篇长文完成滚动检查
## 风险
- Safari 上尚未检查快速连续滚动
## 下一步
- 补充移动端目录折叠测试
状态文件只保留当前有效事实。过程流水账、已经否定的猜测和大段命令输出没有必要长期留在这里。
对于路径不确定、需要持续实验,但完成条件可以量化的任务,我会考虑 Codex 的 Goal。普通 Prompt 描述下一步,Goal 描述最终必须成立的状态。例如:
/goal 将文章页 Lighthouse accessibility 提升到 95 以上,
以桌面端和移动端两次报告为证据,同时保持 npm run build 通过。
只修改文章布局和公共样式。每轮记录分数变化与下一项实验;
如果三轮修改没有改善,停止并列出证据与阻塞点。
Goal 适合性能优化、迁移、偶现测试排查和多轮研究。一次性编辑、简短解释或边界模糊的任务不适合。Goal 会让目标持续存在,却不能替代清楚的验收面。
七、Worktree 解决并行修改的隔离问题
如果两项工作会修改代码,我不会仅因为“它们可以同时做”就把它们放进同一个工作区。Git worktree 给每个任务独立目录和分支,Codex 可以并行读取、修改和测试,而不污染我正在使用的 checkout。
| 情况 | 使用本地工作区 | 使用 Worktree |
|---|---|---|
| 和我一起快速迭代当前页面 | 合适 | 没有必要 |
| 独立补一组测试 | 可以 | 适合后台执行 |
| 大范围重构或依赖升级 | 风险较高 | 更容易审查和丢弃 |
| 两个任务会修改同一批文件 | 不宜并行 | 仍需调整任务边界 |
| 纯调研或代码解释 | 合适 | 通常没有必要 |
Worktree 解决文件和 Git 状态隔离,无法解决逻辑冲突。两个 Agent 同时重新设计同一接口,即使分支不同,最后合并仍然困难。并行前要先按模块、文件所有权或交付物切开任务。
我把本地工作区留给需要频繁看页面、即时纠偏的前台任务。边界清楚、可以独立验证的工作交给 Worktree,例如补测试、整理文档、做只读审查或尝试一个可丢弃的方案。
八、实现完成后,让 Codex 换到 Reviewer 视角
“代码写完”只说明生成阶段结束。验收阶段我会把 Codex 当成 Reviewer,要求它重新读取任务目标和 diff:
现在不要继续扩展功能。请以 reviewer 视角检查当前 diff:
1. 是否完整满足原始目标和完成条件;
2. 是否有超出范围的修改;
3. 是否存在兼容、性能、安全或可访问性风险;
4. 测试是否覆盖最可能回归的路径;
5. 哪些部分仍需要人工检查。
发现确定问题可以直接修复并重新验证;
涉及产品取舍或扩大范围时先列出来,不要自行决定。
Reviewer 视角仍然可能继承作者的盲点,所以证据必须来自仓库和运行结果。我至少会检查:
git diff是否只包含预期文件;- 相关测试、类型检查、Lint 和构建是否通过;
- 用户可见行为是否真实打开过;
- 错误路径、空状态和边界输入是否覆盖;
- Codex 说的“已修复”能否由测试或页面证明。
界面任务尤其不能只看构建。构建成功证明代码能编译,不证明布局好看。需要打开页面、检查关键断点,有参考图时还要做视觉比较。
九、把权限边界写清楚,让它在边界内持续工作
过度放权会造成越界,过度确认也会把 Agent 退化成需要不断点击“继续”的脚本。我会把决定分成两类。
Codex 可以自行处理:
- 读取仓库和运行只读检查;
- 修改任务范围内的文件;
- 运行已有的本地测试和构建;
- 修复由本次改动引起的测试失败;
- 在不改变外部行为时做必要的小调整。
Codex 需要停下来确认:
- 删除数据或大批文件;
- 修改公共接口、数据库结构或线上配置;
- 安装生产依赖;
- 向外部服务提交信息;
- 发现原目标无法实现,需要扩大范围。
这份边界可以放在任务 Prompt,也可以把长期部分写进 AGENTS.md。清楚的授权比“凡事都问”更安全,因为 Agent 知道哪些路径可以持续推进,哪些动作必须由人拍板。
十、自动化只放大已经稳定的流程
Codex 的 Automation 很适合周期性工作,例如依赖风险扫描、CI 失败初步归因、每周文档链接检查和固定格式的状态汇总。但我不会把第一次尝试的任务直接设成 Automation。
我的顺序是:
普通线程手动跑通
↓
整理成可重复的 Skill
↓
连续几次得到稳定结果
↓
再交给 Automation 定期运行
进入自动化前,我会检查输入是否稳定、完成条件是否明确、失败是否能被发现,以及结果是否容易 Review。自动化应当输出可审查的报告或 diff,而不是静默地修改大量状态。
十一、按任务规模选择工作流
我不为所有工作套同一个模板。现在大致分成三档。
小任务:直接实现
适合局部且确定的修改:
任务契约
→ 修改
→ 运行相关检查
→ 汇报 diff 与证据
中型任务:Plan 后实现
适合涉及多个文件、存在少量技术选择的功能:
任务契约
→ 读取仓库并做 Plan
→ 确认边界
→ 分步实现与验证
→ Review diff
长任务:外化计划和状态
适合迁移、重构、性能优化或多阶段建设:
Spec / Goal
→ Plan 与里程碑
→ Worktree 隔离
→ 每个里程碑验证
→ 更新 STATUS
→ 收敛 Review
我根据不确定性、持续时间、修改冲突和验收成本,决定是否使用 Skill、Goal 或 Worktree。
十二、一套可以直接复制的 Codex 请求
下面这个模板覆盖了我最常用的信息。小任务可以删掉不需要的部分。
## 目标
<描述最终可观察的结果>
## 上下文
- <优先读取的文件、报错、页面或历史实现>
- <当前已经确认的事实>
## 范围与边界
- 允许修改:<目录或模块>
- 不要修改:<公共接口、数据结构或无关代码>
- 不新增:<依赖、服务或抽象>
## 工作方式
- 先检查现有实现,再决定修改点
- 复杂或高风险时先给计划
- 在范围内持续实现、测试和修复,不必逐步等待确认
- 需要扩大范围或做不可逆操作时停下来说明
## 完成条件
- <具体行为>
- <测试、构建或基准命令>
- <需要人工查看的页面或 diff>
## 交付
- 说明改了什么
- 列出验证结果
- 指出剩余风险和没有验证的部分
模板不必填满,完成条件却必须可以验证。“优化一下”“更合理”“最好看一点”都可以作为讨论起点,却不能作为 Agent 的终点。
十三、我的最终判断标准
我评价一次 Codex 协作,不看它写了多少代码,也不看对话持续了多久。我只看以下结果:
- 它是否正确理解了我要改变的行为;
- diff 是否保持在约定范围内;
- 关键判断是否来自代码、文档和运行结果;
- 测试、构建、页面或基准能否证明完成;
- 下一位接手的人能否理解改动和剩余风险。
Codex 会随着模型升级变得更能自主判断,旧的繁琐指令也需要持续清理。稳定的方法不会依赖某一句万能 Prompt。给出清楚的终点,提供与任务相关的上下文,保留需要人决定的边界,再让证据决定什么时候结束。这套方法既适用于十分钟的小修复,也能扩展到持续数小时的工程任务。
参考资料
- OpenAI Developers,Rethinking skills and prompts for GPT-6 Astra
- OpenAI Developers,Run long horizon tasks with Codex
- OpenAI Cookbook,Using Goals in Codex
- OpenAI Cookbook,Using PLANS.md for multi-hour problem solving(归档资料,适合参考执行计划结构)
如果这篇文章对你有帮助