第 5 章 / 共 10 章
AGENTS.md:把"我们这儿的规矩"写成文件
5.1 同一句话说第三遍,就该落盘
回想第3章那条纪律:跨会话反复出现的纠正,说明缺文件。
典型的例子:
- “这个项目用 pnpm,不要用 npm”
- “改完必须跑
make lint” - “
legacy/目录不要动,那是待删除的旧代码” - “所有数据库查询都要走 repository 层,不要在 handler 里直接写 SQL”
这些都是只有你知道、代码里看不出来的信息。每个新会话都重说一遍,既浪费上下文额度,也一定会有忘记说的时候。AGENTS.md 就是这些信息的落脚点。
最快的起步方式是在项目根目录的会话里执行:
/init
它会扫描仓库并生成一份初稿。初稿只是起点——它能写出的都是从代码里能推断的东西,真正有价值的是你补进去的那些”代码里看不出来”的约定。
5.2 文件放哪、怎么叠加、谁优先
Codex 在启动时会构建一条指令链,按这个顺序查找并拼接:
- 全局:Codex 主目录(默认
~/.codex)下的AGENTS.override.md,若无则AGENTS.md - 仓库根目录的
AGENTS.override.md,若无则AGENTS.md - 从仓库根到当前工作目录之间,每一级目录的同名文件
- 当前工作目录的同名文件
规则有三条:
- 从根往下拼接,越靠后的文件在提示里出现得越晚,冲突时后者生效。所以越靠近你当前目录的规则优先级越高。
- 同一级目录下,
AGENTS.override.md优先于AGENTS.md,只取第一个非空文件。 - 拼接总量有上限,由
project_doc_max_bytes控制,默认 32 KiB。超过就会被截断。
第三条是很多人踩过的坑:把所有规则堆进根目录一个巨大的文件,写到后来发现底部的规则”好像不生效”。正确做法是分层——通用约定放根目录,某个服务特有的约定放那个服务的子目录。

5.3 一份能用的模板
一份好的 AGENTS.md 应该覆盖:仓库结构、怎么运行、构建/测试/lint 命令、工程约定、约束、以及”什么叫做完”。
# 项目说明
## 仓库结构
- `api/`:HTTP 层,只做参数校验和响应组装
- `service/`:业务逻辑
- `repo/`:所有数据库访问,唯一允许写 SQL 的地方
- `legacy/`:待删除,不要修改
## 如何运行
- 安装依赖:`pnpm install`(本项目用 pnpm,不要用 npm 或 yarn)
- 本地启动:`pnpm dev`
- 需要先启动本地 Postgres:`docker compose up -d db`
## 构建、测试与检查
- 单元测试:`pnpm test`
- 类型检查:`pnpm typecheck`
- 代码风格:`pnpm lint --fix`
- 提交前这三条都必须通过
## 工程约定
- 新增接口必须同时补对应的集成测试
- 错误一律返回结构化响应,不要直接抛原始异常给客户端
- 数据库迁移文件只增不改,改动已发布的迁移会破坏线上环境
## 完成的定义
- 相关测试通过
- 类型检查和 lint 通过
- 改动摘要里说明了影响范围和回滚方式
## Code Review Rules
- 标记任何在 `api/` 层直接访问数据库的代码
- 标记任何新增的环境变量没有同步更新 `.env.example` 的情况
最后那个 ## Code Review Rules 小节有特殊用途:GitHub 上的 Codex 代码评审会专门读它(详见第9章)。规则应该写在离被管辖代码最近的那个文件里。
5.4 让规则真正生效的三条写法纪律
第一,写可执行的指令,不写价值观。
“遵循最佳实践”是噪音。“提交前运行 pnpm lint --fix”是指令。判断标准很简单:这句话能不能被验证做没做到?
第二,写代码里看不出来的东西。
目录结构、依赖列表、脚本命令,Codex 自己能读出来。真正值钱的是:为什么这么设计、哪些地方有历史包袱、哪个坑踩过、什么改动会导致线上事故。
第三,规则要有边界和例外。
“不要修改 legacy/”比”尽量少动老代码”好,因为前者有明确边界。如果确实有例外,写清楚:“legacy/ 只在修复安全漏洞时可以改,且必须单独提 PR”。
5.5 动手:把初稿改成真正有用的项目说明
广告位 · Multiplex 关联广告