AGENTS.md 是什么,Codex 怎么用它
AGENTS.md 是给编码代理看的项目说明书:构建命令、测试命令、目录约定、代码风格、禁止改动的区域。它不是给人看的 README,所以可以写得更直接——短句、命令、明确的“必须 / 禁止”。
关键在于:Codex 每次运行只构建一次指令链。也就是说,启动时读哪些文件、按什么顺序拼起来,在这一次会话里就固定了。中途改文件不会自动重新加载,这一点决定了后面所有的排查思路。
发现顺序:全局 → 项目 → 合并
查找分成三段:先看全局目录里的一个文件,再从项目根一路走到当前工作目录逐层找,最后按顺序拼接。理解这三段,90% 的“规则没生效”问题都能自己定位。
- 01
全局层
在 Codex home 目录里找。默认是 ~/.codex,可用 CODEX_HOME 环境变量改。先看 AGENTS.override.md,没有再看 AGENTS.md,只取第一个非空文件。
- 02
项目层
从项目根(通常是 Git 根)往下走到当前工作目录,每个目录依次找 AGENTS.override.md → AGENTS.md → project_doc_fallback_filenames 里列的名字(例如 TEAM_GUIDE.md)。每个目录最多取一个文件。
- 03
合并层
按 root → cwd 的顺序拼接,空行分隔。越靠近当前目录的文件越靠后,因此它的内容会覆盖前面同名主题的规则。
~/.codex/AGENTS.md # 全局:个人偏好、提交信息习惯
repo/AGENTS.md # 仓库根:构建、测试、目录约定
repo/services/api/AGENTS.md # 子目录:这个服务的额外约束(cwd 在 api 下时它排最后,优先级最高)全局还是项目:规则该放在哪一层
判断标准很简单:换一个仓库还成立吗?成立就放全局,不成立就放项目。混放的后果是全局那层越写越长,最后把 32 KiB 的额度浪费在只对某个项目有意义的规则上。
| 规则类型 | 建议位置 | 例子 |
|---|---|---|
| 个人习惯 | 全局 ~/.codex | 提交信息用中文、改完先跑格式化 |
| 仓库通用约定 | 项目根目录 | 包管理器用 pnpm、不要动 migrations 目录 |
| 单个服务的约束 | 对应子目录 | 这个服务禁止直接读环境变量,必须走 config 模块 |
| 临时任务要求 | 不写进文件 | 直接在对话里说明,任务结束就失效 |
- 全局文件写“我这个人怎么协作”,项目文件写“这个仓库怎么运作”。
- 项目根目录的文件要短而硬:构建命令、测试命令、目录职责、禁止事项。
- 子目录文件只写差异,不要把根目录的规则抄一遍。
- 规则要可执行:写“测试用 pnpm test -- --run”,不要写“注意测试”。
override 与 fallback 文件名
同一层里,Codex 不是把所有候选文件都读进来,而是按优先级取第一个非空的。override 文件用来临时覆盖,fallback 列表用来兼容团队已有的文件名。
| 文件名 | 在同一层里的优先级 | 用途 |
|---|---|---|
| AGENTS.override.md | 最先查找 | 本地临时覆盖,通常不提交到仓库 |
| AGENTS.md | 其次 | 正式的团队约定,提交进仓库 |
| project_doc_fallback_filenames 里的名字 | 最后 | 兼容已有文件名,例如 TEAM_GUIDE.md、.agents.md |
# 允许 Codex 额外识别这些文件名
project_doc_fallback_filenames = ["TEAM_GUIDE.md", ".agents.md"]
# 默认 32 KiB,项目规则多的时候可以调大
project_doc_max_bytes = 6553632 KiB 上限与怎么拆分
拼接出来的总大小受 project_doc_max_bytes 限制,默认 32 KiB。到达上限后,后面的文件会被直接截断——不是报错,而是静默少读,表现为“最后写的规则好像没生效”。
- 先量体积:把参与拼接的文件加起来看,容易超的是根目录那份大而全的文件。
- 优先删掉过期规则,而不是继续调大上限:读得越多,模型抓重点越难。
- 规则按目录拆开:通用的放根,专属的放子目录,只在进入该目录时才被拼进来。
- 实在需要更多空间,再调大 project_doc_max_bytes,但要清楚这是在拿上下文换规则。
- 构建命令、测试命令这类高频信息放前面,长段的背景说明放后面或直接删掉。
怎么写 Code Review Rules
审查规则要写在“管辖这段代码的最近一层” AGENTS.md 里:仓库级约定放根目录,某个服务特有的放嵌套目录。写得太远,审到那块代码时根本读不到。
每条规则的结构建议是两句:要拦什么行为,以及安全的替代路径是什么。只写“不要 X”会让模型卡住,写清“遇到 X 时改成 Y”它才知道怎么继续。
## Code Review Rules
- 禁止在 handler 里直接拼接 SQL。所有查询必须走 repository 层的参数化方法。
- 禁止吞掉错误(catch 后只打日志再 return null)。要么返回错误,要么显式包装成业务错误。
- 新增外部请求必须设置超时和重试上限,默认 3 秒超时、最多 1 次重试。
- 改动 public API 的响应字段时,必须同时更新 openapi.yaml,否则视为未完成。
- 不要提交调试用的 console.log / print,日志统一用 logger。
- 格式化和 lint 由 CI 负责,不要在本文件里重复罗列风格细节。- 规则要短,一条一行,避免大段说明。
- 只写机器难以自动检查、但人能一眼判断的问题。
- 格式化、命名风格、行长度这类交给 lint 和 formatter,不要占用上下文额度。
- 规则会变,跟着事故复盘更新:每次线上问题后补一条能拦住它的规则。
验证到底加载了哪些文件
别猜。让 Codex 自己汇报它读到了什么,是最快的验证方式。三个命令分别对应“总结当前指令”“确认嵌套覆盖”“审计加载日志”。
# 让它总结当前生效的指令
codex --ask-for-approval never "Summarize the current instructions."
# 从子目录启动,确认嵌套覆盖是否生效
codex --cd services/api --ask-for-approval never "Show which instruction files are active."
# 审计:把日志落到本地目录,再看日志里记录了哪些文件
codex -c log_dir=./.codex-log "Refactor the parser"
# 然后查看 ./.codex-log/codex-tui.log(或对应的 session 日志)| 现象 | 可能原因 | 怎么处理 |
|---|---|---|
| 什么都没加载 | 启动目录不在项目里,或文件是空的 | 确认 cwd 在 Git 仓库内,检查文件是否真有内容 |
| 出现了不该有的规则 | 上层目录存在 AGENTS.override.md | 从根到 cwd 逐层查找 override 文件 |
| fallback 文件名不生效 | 文件名拼写不一致,或改完没重启 | 对照 project_doc_fallback_filenames 逐字检查,重启 Codex |
| 规则被截断 | 总大小超过 project_doc_max_bytes | 调大上限,或把规则拆到嵌套目录 |
| 配置像是别人的 | CODEX_HOME 指向了别的 profile | echo $CODEX_HOME 确认目录,再检查那里的配置 |
| 刚改完没反应 | 本次运行的指令链已经构建完了 | 重启 Codex,它会重新读取 |
- 写完先在目标子目录里跑一次验证命令,确认“最近的那层”确实被读到。
- 把 AGENTS.md 当代码管理:改它也要走 review,避免有人随手加一条互相冲突的规则。
- CI 里加一条检查:根目录文件超过约定行数就提醒拆分。
- 团队成员共用 fallback 文件名时,把配置写进文档,别靠口头传递。
常见问题
AGENTS.md 改了为什么没生效?
Codex 每次运行只构建一次指令链,运行期间改文件不会重新加载。重启 Codex 即可重新读取。另外确认文件不是空的,且当前工作目录在它管辖的范围内。
全局 AGENTS.md 和项目 AGENTS.md 冲突时听谁的?
按 root → cwd 的顺序拼接,越靠近当前目录的文件越靠后,因此会覆盖前面同主题的规则。想让某条全局规则绝对生效,就不要在项目层重复定义它。
为什么同目录的 AGENTS.md 没被读取?
同一层里按 AGENTS.override.md → AGENTS.md → fallback 文件名的顺序取第一个非空文件。存在 override 文件时,同层的 AGENTS.md 就会被跳过。
规则很多,是调大上限还是拆文件?
优先拆。默认上限是 32 KiB,到达后后面的内容会被静默截断。把只对子目录成立的规则挪到该子目录的 AGENTS.md,既省额度也更精准;确实不够再调大 project_doc_max_bytes。
官方文档与参考
本文依据上述官方文档整理;价格、额度与功能会随官方更新变化,第三方中转站的行为以其自身说明为准。