好 AGENTS.md 不让 Codex 更聪明,但少让它走偏

4106 字
21 分钟
好 AGENTS.md 不让 Codex 更聪明,但少让它走偏

一份好的 AGENTS.md,不会让 Codex 突然变得更聪明,却会显著减少它在错误方向上越走越远。

Claude Code 侧同类文件见 CLAUDE.md 模板专篇;四类 Loop 见 Claude Code 四类 Loop

一、真正解决的是什么

Codex 在陌生仓库里最容易遇到的,不是不会写代码,而是不知道团队的「默认答案」。

例如:

  • 这个项目用 pnpm、npm 还是 yarn?
  • 单元测试和集成测试分别怎么跑?
  • 改接口时,是否必须同步 OpenAPI 文档?
  • 数据库迁移能不能自动执行?
  • 前端应该复用哪个组件库?
  • 完成任务的标准是「代码写完」,还是「测试、文档和兼容性检查全部通过」?

这些信息往往散落在 README、CI 配置、团队 Wiki 和老员工的经验里。Codex 如果找不到,只能根据常见做法猜。猜对了是效率,猜错了就是返工。

AGENTS.md 的价值,就是把这些隐性的工程共识变成可重复加载的项目上下文。

按照 Codex 官方文档,Codex 会在开始工作前读取适用的 AGENTS.md。它可以同时使用三种层级:

  • ~/.codex/AGENTS.md:个人在所有仓库通用的习惯。
  • 仓库根目录的 AGENTS.md:整个项目共享的规则。
  • 子目录里的 AGENTS.mdAGENTS.override.md:某个服务、包或模块的局部规则。

Codex 会从项目根目录一路读取到当前工作目录,越靠近当前目录的规则优先级越高。换句话说,根目录负责「共同宪法」,子目录负责「地方条例」。

Codex 如何按层级加载 AGENTS.md
Codex 如何按层级加载 AGENTS.md

这也是写好 AGENTS.md 的第一个关键:不要试图用一份巨型文件解释整个世界,要让规则跟着代码的边界走。

二、六条原则

高质量 AGENTS.md 的六大原则
高质量 AGENTS.md 的六大原则

1. 写可执行事实,不写正确的废话

「保持代码简洁」「遵循最佳实践」「确保高质量」看起来没有错,但对 Codex 几乎没有约束力。

更有效的写法是:

- 修改 TypeScript 文件后运行 `pnpm lint``pnpm typecheck`
- 新增业务逻辑时,在同目录补充 `*.test.ts`
- 单个函数超过 60 行时,优先拆分;不要仅为满足行数机械拆分。

判断一句规则是否有用,可以问自己:任务结束时,我能不能根据它明确判断 Codex 做到了还是没做到?如果不能,它大概率只是一句口号。

2. 告诉它「怎么验证」,不只是「怎么修改」

编码智能体最危险的状态,不是写不出来,而是写完后误以为已经完成。

因此,AGENTS.md 至少要写清四件事:

  1. 最小检查命令是什么;
  2. 哪些改动需要扩大测试范围;
  3. 什么情况可以跳过测试;
  4. 无法验证时应该如何汇报。

例如:

## Verification
- 文档改动:运行 `pnpm lint:docs`
- 单个包改动:运行 `pnpm --filter <package> test`
- 共享类型或公共包改动:运行 `pnpm test:affected`
- 如果本地缺少依赖或服务,说明未运行的检查、原因和潜在风险;不要声称验证通过。

最后一句尤其重要。它把「诚实报告验证边界」也纳入了完成标准。

3. 写清边界和禁区

有些动作技术上可以执行,流程上却不应由 Codex 自行决定,例如升级生产依赖、重写历史迁移、提交密钥、删除兼容代码。

不要只写「谨慎操作」,而要明确触发条件:

## Guardrails
- 未经明确要求,不新增生产依赖。
- 不修改已经发布的数据库迁移;需要变更时创建新的迁移文件。
- 不读取、输出或提交 `.env`、密钥及真实客户数据。
- 不执行生产部署、数据删除、密钥轮换和远程 Git 推送。

好的边界不是让 Codex 什么都不敢做,而是把「可自主完成」和「必须停下来确认」分开。

4. 给地图,不要复制整本说明书

AGENTS.md 应该帮 Codex 快速找到重点,而不是把 README、架构文档和编码规范全部复制进去。

可以写:

## Repository map
- `apps/web/`:Vue 3 管理端。
- `services/api/`:Node.js API 服务。
- `packages/contracts/`:前后端共享类型,改动可能影响所有应用。
- `docs/architecture.md`:系统边界与关键设计决策。
- `docs/review.md`:代码审查清单。

官方文档提醒,Codex 合并加载的项目说明默认有 32 KiB 上限。文件越长,不仅越难维护,也越可能让真正关键的规则被噪声淹没。主文件保持短小,需要时指向更具体的文档,通常更可靠。

5. 用分层覆盖解决差异,不堆条件句

假设仓库里前端用 Vitest,支付服务用 pytest。如果所有规则都塞在根目录,最终会出现大量「如果在 A 目录就……如果在 B 目录就……」的条件。

更清楚的做法是:

repo/
├── AGENTS.md
├── apps/web/
│ └── AGENTS.md
└── services/payments/
└── AGENTS.override.md

根目录只写全局规则,apps/web/AGENTS.md 写前端规则,支付服务用 AGENTS.override.md 覆盖不适用的通用命令。局部规则越靠近代码,越不容易被误用。

需要注意:Codex 通常在一次运行或 TUI 会话开始时构建指令链。修改 AGENTS.md 后,如果当前会话没有体现新规则,启动一个新会话再验证。

6. 把它当成会演进的工程资产

不要试图第一次就写出完美版本。更实用的方法是:先覆盖高频任务,然后根据真实返工持续更新。

每当 Codex 重复犯错,可以追问三个问题:

  1. 它缺少的是项目事实、操作命令,还是决策边界?
  2. 这条信息只对当前任务有效,还是以后还会复用?
  3. 它应该放在根目录,还是某个子目录?

如果同类错误发生两次,就值得把修正写进 AGENTS.md。它不应成为愿望清单,而应成为项目经验的压缩包。

三、可直接改的通用模板

AGENTS.md 模板七段
AGENTS.md 模板七段

下面这份模板适合大多数中小型项目。复制之后,请删除不适用的内容,并把占位命令替换为仓库中真实可运行的命令。

(图卡把骨架收成七段:项目说明 / 仓库地图 / 命令 / 验证 / 边界 / 完成标准 / 审查规则。下面完整模板另含 Working rules、Coding conventions 等可删改栏目。)

AGENTS.md
## Project overview
- 本仓库用于:<一句话说明产品或服务>。
- 主要技术栈:<语言、框架、运行时>。
- 包管理器:<pnpm/npm/yarn/uv/poetry >。
- 修改前先阅读:`README.md``docs/architecture.md`
## Repository map
- `src/`:核心业务代码。
- `tests/`:自动化测试。
- `docs/`:架构与使用文档。
- `<关键目录>`:<职责及影响范围>。
## Working rules
- 修改前先阅读相关实现和测试,不根据文件名猜测行为。
- 优先做满足需求的最小改动,避免顺手重构无关代码。
- 遵循现有结构、命名和错误处理方式。
- 未经明确要求,不新增生产依赖,不改变公共 API。
- 发现需求与现有实现冲突时,先说明证据和影响,再决定是否继续。
## Commands
- 安装依赖:`<command>`
- 启动开发环境:`<command>`
- 代码检查:`<command>`
- 类型检查:`<command>`
- 单元测试:`<command>`
- 完整测试:`<command>`
## Coding conventions
- <语言或框架相关约定>。
- <文件命名、导入、异常处理约定>。
- 新增或修改公共接口时,同步更新类型、测试和文档。
- 不为了"更整洁"修改与任务无关的格式或代码。
## Testing and verification
- Bug 修复必须补充能够复现问题的回归测试。
- 新功能至少覆盖主路径和一个失败路径。
- 先运行受影响范围的测试;共享模块变更再运行完整测试。
- 无法运行检查时,明确列出未验证项、原因和风险。
## Guardrails
- 不提交密钥、令牌、`.env` 或真实用户数据。
- 不执行生产部署、远程推送、数据删除或不可逆操作。
- 不修改已发布的迁移文件;创建新的迁移。
- 发现疑似安全问题时停止扩散敏感信息,只报告必要细节。
## Definition of done
- 请求的行为已经实现,且没有夹带无关改动。
- 相关测试、lint 和类型检查通过。
- 必要的文档、示例、类型和迁移已同步。
- 最终说明包含:改了什么、如何验证、仍有哪些风险。
## Review guidelines
- 优先检查正确性、回归风险、安全性和兼容性。
- 指出问题时给出文件位置、触发条件和影响。
- 不把纯风格偏好当作阻塞问题。

这份模板最重要的部分并不是标题数量,而是每条规则都能落到一个动作、一个边界或一个验收结果上。

四、六个场景的局部规则

六场景局部规则
六场景局部规则

通用模板解决的是底座,真正让 Codex 变得稳定的,往往是与业务场景贴合的局部规则。

场景 1:在成熟项目里开发新功能

成熟项目最怕「功能完成了,但破坏了既有边界」。这时需要强调先找相似实现、控制改动范围,以及公共接口的同步责任。

## Feature development
- 实现前先查找同类功能,沿用现有分层和数据流。
- 优先扩展现有模块,不新建平行抽象,除非现有设计无法满足需求。
- 修改公共 API 时,同步更新 schema、客户端类型、测试和变更说明。
- 新功能必须覆盖成功路径、权限失败和无效输入。

这组规则能避免 Codex 在仓库里「另起炉灶」,尤其适合已经形成稳定架构的项目。

场景 2:修复一个难复现的线上 Bug

修 Bug 时,最大的诱惑是看见异常就直接改代码。但没有复现证据的修复,往往只是把症状移到别处。

## Bug fixes
- 修改实现前,先用现有日志、调用链或测试证明根因。
- 能稳定复现时,先添加失败的回归测试,再修改代码。
- 修复应针对根因,不通过吞掉异常、扩大重试或删除校验掩盖问题。
- 如果无法复现,列出已验证事实、假设和仍需观测的数据。

这里的重点,是强制把「事实」和「推测」分开。即便最终没能修复,也会留下可继续推进的诊断结果。

场景 3:Monorepo 中只修改一个包

Monorepo 的常见浪费,是一个小改动跑整库测试;常见事故,则是误以为只影响一个包。

## Monorepo scope
- 修改前检查目标包的 `package.json`、依赖方和局部 `AGENTS.md`
- 包内改动先运行 `pnpm --filter <package> test`
- 修改 `packages/contracts/``packages/config/` 或公共类型后,运行 `pnpm test:affected`
- 不修改无关包的锁文件、生成物或格式。

一份好的规则既要控制验证成本,也要指出哪些目录具有「爆炸半径」。

场景 4:数据库迁移和高风险操作

数据库相关任务不能只强调 SQL 是否正确,还要约束兼容窗口、回滚方式和执行权限。

## Database changes
- 不修改已经在任何环境执行过的迁移文件。
- 破坏性 schema 变更采用 expand-migrate-contract 三阶段,不在一次发布中删除旧字段。
- 迁移必须说明回滚或前向修复方案,并评估锁表和大表扫描风险。
- 只生成和测试迁移;未经明确授权,不连接生产库、不执行生产迁移。

这里要明确区分「编写迁移」和「执行迁移」。前者通常属于开发任务,后者可能是不可逆的生产操作。

场景 5:前端页面还原与交互开发

前端任务容易出现两个极端:只追求截图相似,忽略状态和可访问性;或者为了抽象组件,把一个页面改成半个设计系统。

## Frontend work
- 优先复用现有设计令牌和组件,不创建近似重复组件。
- 页面必须处理 loading、empty、error 和 disabled 状态。
- 交互元素支持键盘操作,并保留可见焦点状态。
- 至少检查 375px、768px 和 1440px 三个宽度。
- 视觉改动提供截图或明确说明人工检查路径。

这类规则把「看起来完成」变成「在真实状态和真实设备上可用」。

场景 6:让 Codex 做 Pull Request 审查

代码审查不是复述 diff,更不是罗列所有风格差异。它应该优先发现会造成实际后果的问题。

## Review guidelines
- 优先报告正确性、安全性、数据损坏、兼容性和明显性能回归。
- 每个问题说明触发条件、用户或系统影响,并标注具体文件位置。
- 检查新增行为是否有测试,测试是否真的覆盖失败场景。
- 不报告现有代码中的无关问题,不把个人风格偏好列为缺陷。
- 如果没有发现问题,明确说明仍未覆盖的测试或环境风险。

Codex 官方文档说明,代码审查会寻找仓库中的 AGENTS.md,并遵循其中的 Review guidelines。对于支付、鉴权、隐私等特殊目录,还可以在更深层放置专门的审查规则,让检查标准跟着风险走。

五、五个反模式

把临时需求写成永久规则
「这次不要改登录页」属于当前任务提示,不属于项目长期约定。把一次性的限制写进 AGENTS.md,几周后就会变成过期信息。

只写风格,不写命令
用了两页篇幅描述命名偏好,却没有一句告诉 Codex 如何运行测试。这类文件看似完善,实际无法支撑任务从输入到验证的完整流程。

命令已经失效
错误命令比没有命令更糟。CI、包管理器或目录结构变化时,应把 AGENTS.md 纳入同一个 Pull Request 更新。

根目录承载所有差异
当根文件充满目录条件和例外,说明规则应该下沉。利用子目录文件表达局部约束,比在一个大文件里维护复杂分支更稳。

把软要求写成绝对命令
「永远不要重构」「所有改动必须跑全量测试」可能让 Codex 在简单任务上付出巨大成本。更好的表达是说明触发条件、例外和优先级。

六、怎么确认它真的生效

不要凭感觉判断。可以在仓库根目录启动一次新会话,让 Codex 复述当前加载的规则:

Terminal window
codex --ask-for-approval never "Summarize the current instructions."

如果项目使用了子目录覆盖,再从目标目录检查:

Terminal window
codex --cd services/payments --ask-for-approval never \
"List the instruction sources you loaded and summarize the effective rules."

你需要确认三件事:

  1. 它加载了正确的文件;
  2. 局部规则覆盖了冲突的上层规则;
  3. 最关键的构建、测试和安全边界没有被遗漏或截断。

Codex CLI 也提供 /init 来生成初始的 AGENTS.md。它适合解决「从零开始」,但生成之后仍要根据项目真实的构建、测试、审查和发布流程进行删改。脚手架只能提供栏目,不能替团队补上工程事实。

短、准、可验证就够起步

高质量 AGENTS.md 的本质,不是写一份更复杂的提示词,而是把团队的工程判断变成 Codex 能稳定执行的上下文。

它应该短、准、可验证:告诉 Codex 项目在哪里,命令怎么跑,边界在哪里,以及做到什么程度才算完成。

如果你不知道从哪里开始,就先写下四项内容:仓库地图、常用命令、不可触碰的边界、完成标准。等 Codex 第二次犯下同一种错误,再把那次教训补进去。

时间久了,这份文件会变成项目里很特别的一类资产:它记录的不是代码本身,而是团队希望代码如何被理解、修改和交付。

评论区

像发消息一样写就好:点工具栏插入表情 / 图片,表情会直接显示。插图 ≤5MB。