04 · 为什么 AGENTS.md 能改变 Codex 行为
任务都是一句话:"给登录页加一个忘记密码链接"。看 Codex 在两种条件下的差别:
⏱️ 预计阅读 12 分钟 | 🎯 目标:把"每次都要重复交代"换成"项目自己会说话"
上一篇讲了
AGENTS.md怎么被 Codex 加载(instruction chain,指令链)。 这一篇展开方法层:怎么写、写什么、什么不该写、什么时候改。
🎬 加规则前 vs 加规则后:同一个任务两种行为
任务都是一句话:"给登录页加一个忘记密码链接"。看 Codex 在两种条件下的差别:
| 维度 | ❌ 没有 AGENTS.md | ✅ 有 AGENTS.md |
|---|---|---|
| 包管理器 | 它跑 npm install,污染了 lock 文件 | 规则写明 用 pnpm,它自动用 pnpm add |
| UI 组件 | 自己写一个 <a> 标签链接 | 规则写明 优先复用 components/ui,它直接用 <Link variant="text"> |
| 测试 | 不跑测试就交付 | 规则写明 改完跑 pnpm test,它跑了并附结果 |
| 验收交付 | "完成了" | 列出 diff + 验证命令 + 桌面/移动端截图清单 |
| 结果 | 你重新审查 + 回滚 + 重做,多花 30 分钟 | 5 分钟看 diff 通过 |
🤔 同一个 Codex、同一个任务,结果完全不同。 差别不在它聪不聪明,在你有没有把项目规则放它脚下。
🤖 AGENTS.md = 项目与 Agent 的「接口」
写代码的人最熟悉接口(interface,定义两方协作的契约)。函数有签名,API 有协议,模块之间有依赖边界 —— 接口让不同部分以稳定方式协作。
AGENTS.md 也是接口。它连接的是「项目」和「AI Agent(智能代理)」:
flowchart LR
subgraph Project["📁 项目侧"]
Code[源码]
Config[配置文件]
Tests[测试]
end
subgraph Interface["📜 AGENTS.md(接口)"]
Facts[事实层<br/>命令 / 目录 / 技术栈]
Rules[约束层<br/>不能做什么]
Verify[验收层<br/>怎么算完成]
end
subgraph Agent["🤖 Agent 侧"]
Codex[Codex]
Cursor[Cursor]
Other[其他 Agent]
end
Code -.读取.-> Interface
Config -.读取.-> Interface
Tests -.读取.-> Interface
Interface --> Codex
Interface --> Cursor
Interface --> Other
style Interface fill:#dcfce7,stroke:#22c55e,stroke-width:2px
和 README 的分工:
| 维度 | 📖 README | 📜 AGENTS.md |
|---|---|---|
| 主要读者 | 人类开发者 | AI Agent |
| 重点 | 项目是什么、怎么用 | Agent 怎么干活、不能动什么 |
| 例子 | "这是一个开源教程网站" | "修改教程时保留中文标题、改完检查链接" |
| 写得长不长 | 可以详细 | 必须短(32 KiB 上限) |
💡 README 解释项目给人看,AGENTS.md 约束 Agent 怎么做事。两者互补,不互相替代。
🧱 一份合格的 AGENTS.md:3 层结构
把 AGENTS.md 切成三层来写。任何一层缺,规则就失效:
flowchart TB
subgraph L1["1️⃣ 事实层 · 项目真实状态"]
F1[技术栈]
F2[包管理器]
F3[目录职责]
F4[启动 / 测试命令]
end
subgraph L2["2️⃣ 约束层 · 不能做什么"]
C1[不新增依赖]
C2[不改生成文件]
C3[不动部署配置]
C4[不直接执行高危命令]
end
subgraph L3["3️⃣ 验收层 · 怎么算完成"]
V1[改 UI 看桌面 + 移动]
V2[改逻辑跑测试]
V3[改类型跑 typecheck]
V4[无法验证须说明原因]
end
L1 --> L2 --> L3 --> Done[✅ Codex 行为稳定]
style L1 fill:#dbeafe,stroke:#3b82f6
style L2 fill:#fef3c7,stroke:#f59e0b
style L3 fill:#dcfce7,stroke:#22c55e
| 层 | 缺它会怎样 |
|---|---|
| 缺 事实层 | Codex 不知道用什么命令工作 |
| 缺 约束层 | Codex 可能做过头(顺手重构 / 装新依赖) |
| 缺 验收层 | "完成了"无法证明 |
🎯 三层都齐 = 协作协议。只有事实没有约束 是说明书;只有约束没有事实 是清规戒律;没有验收 是甩手交付。
✍️ 先写一行:6 个必备模块
第一次写 AGENTS.md,按下面 6 个模块短、明确、可执行地填:
| # | 模块 | 该写什么 | 不该写什么 |
|---|---|---|---|
| 1 | 📋 项目概况 | 一句话项目定位 + 主要技术栈 | 商业目标、长篇愿景 |
| 2 | 📁 目录职责 | 关键目录分别放什么 | 每个文件的注释 |
| 3 | ⚙️ 开发命令 | 启动 / 测试 / 构建 / lint | 每个 npm script 都列 |
| 4 | 📐 编码规则 | 命名 / 组件复用 / 错误处理约定 | 抽象口号("代码要优雅") |
| 5 | 🚫 禁止事项 | 哪些文件 / 操作不能默认做 | 未来某天可能要禁止的 |
| 6 | ✅ 验收要求 | 改完必须跑哪些检查 | 一次性任务的临时步骤 |
💡 判断口诀(最实用): "下个月还有效的,写 AGENTS.md。只对这次任务有效的,写提示词。"
🌰 真实案例:前端项目的合格 AGENTS.md
下面这份 100 行不到,但已经能显著降低 Codex 乱改概率:
# 项目协作规则
## 项目概况
这是一个 Next.js 前端项目,承载产品官网和用户控制台。
## 技术栈
- Next.js(App Router)
- React + TypeScript(严格模式)
- Tailwind CSS
- pnpm(统一包管理器)
## 目录职责
- `app/`:页面和路由(App Router)
- `components/`:可复用 UI 组件
- `components/ui/`:基础组件(Button、Input、Link 等)
- `lib/`:工具函数和 API client
- `tests/`:单元测试和组件测试
## 常用命令
- 安装依赖:`pnpm install`
- 本地启动:`pnpm dev`
- 测试:`pnpm test`
- 类型检查:`pnpm typecheck`
- 构建:`pnpm build`
## 工作规则
- 修改前先阅读相关页面 / 组件 / 测试
- 优先复用 `components/ui/` 现有组件,不新增组件库
- 默认只改与任务直接相关的文件
- 跨目录修改先说明原因
## 禁止事项
- ❌ 不新增 UI 组件库(已有 components/ui)
- ❌ 不修改全局主题(除非任务明确要求)
- ❌ 不修改部署配置(vercel.json / Dockerfile)
- ❌ 不提交调试日志(console.log / debugger)
- ❌ 不改 generated/ 目录(自动生成)
## 验收要求
- 改 UI 后检查桌面端 + 移动端(375px / 1440px)
- 改逻辑后跑 `pnpm test` 和 `pnpm typecheck`
- 无法运行验证时,在最终回复里说明原因
- 最终回复列出:修改文件 + 验证命令 + 剩余风险🎯 核心特征:每条规则都可执行、可检查。没有"代码要优雅"这种空话。
🚫 写 AGENTS.md 的 3 个常见错误
错误 ① · 写成价值观宣言
❌ 反例:
- 代码要优雅
- 架构要清晰
- 体验要好这些无法执行也无法检查,对 Codex 没有约束力。
✅ 正例:
- 函数超过 80 行时优先拆分为独立 helper;不拆需说明理由
- 修改 UI 时优先复用 components/ui 内已有组件,不新增组件库具体、可执行、可检查。
错误 ② · 只写禁止,不写做法
❌ 反例:
- 不要乱改代码
- 不要做无关修改太空。Codex 不知道"乱"和"无关"的边界。
✅ 正例:
- 默认只改与任务直接相关的文件
- 需跨模块修改时,先说明原因和影响把"不要"翻译成"默认怎么做"。
错误 ③ · 把临时需求写成长期规则
❌ 反例(写进 AGENTS.md):
- 本周不要改导航栏(新版正在评审)
- 这次发布前先冻结表单 schema这些只对这一次有效,混进 AGENTS.md 会让其他任务跟着受限,甚至忘了删。
✅ 正例:临时要求写进当次提示词,AGENTS.md 只放下个月仍有效的规则。
🔄 长期规则 vs 临时规则:怎么分?
这是写 AGENTS.md 最关键的边界。一图看清:
flowchart LR
Q{这条规则<br/>下个月还有效吗?}
Q -->|是| L[📜 AGENTS.md<br/>长期规则]
Q -->|否| T[💬 当次提示词<br/>临时规则]
Q2{影响每次任务执行吗?}
L --> Q2
Q2 -->|是| Keep[✅ 保留]
Q2 -->|否| Delete[❌ 删除/移走]
style L fill:#dcfce7,stroke:#22c55e
style T fill:#fef3c7,stroke:#f59e0b
style Delete fill:#fee2e2,stroke:#ef4444
| 类型 | 适合放 | 例子 |
|---|---|---|
| 📜 AGENTS.md | 长期规则 | 包管理器用 pnpm / 测试命令 / 不改部署配置 |
| 💬 当次提示词 | 临时要求 | 这次只改首页 / 本轮先冻结某个文件 |
🌐 全局 ~/.codex/AGENTS.md | 跨项目偏好 | 中文回复 / 默认要求列 diff |
| 🛠️ Skill | 重复多步流程 | "做 PR review" 这种 5 步以上工作流 |
⚠️ 临时覆盖长期是允许的,但必须显式声明:
这次任务允许新增依赖(覆盖 AGENTS.md 的"不新增依赖"规则), 因为现有库无法满足 XXX 需求。
🎓 持续维护:什么时候该改?
AGENTS.md 不是一次写完就不动。下面 4 种情况触发更新:
触发 ① · 项目真实工作方式变了
包管理器 npm → pnpm
测试框架 jest → vitest
目录重构 pages/ → app/➡️ 立刻同步,否则规则误导 Codex 用错命令。
触发 ② · 某类错误反复出现
Codex 经常忘记跑 typecheck
反复改了 generated/ 目录
总是新增不必要的依赖➡️ 说明规则没写清楚或漏了。补一条具体规则到对应模块。
触发 ③ · 团队协作方式升级
个人项目 → 多人协作
开始要求 PR / CI / review
新增敏感信息扫描➡️ 在「工作规则」和「验收要求」加协作边界。
触发 ④ · 出现新的高风险区
新增支付 / 权限 / 数据库迁移 / 生产发布脚本➡️ 在「禁止事项」标清"不能默认操作",需显式确认才能动。
💡 不该改的情况:一次性临时需求 ❌。比如"今天先不要跑全量测试",这种永远只放当次提示词。
🚫 常见误解 → ✅ 正确理解
| ❌ 误解 | ✅ 正解 |
|---|---|
| AGENTS.md 越长越好 | 越短越好(重要规则会被淹没;32 KiB 也是物理上限) |
| 有了 AGENTS.md 就不用写提示词了 | AGENTS.md 写长期,提示词写本次;两者互补 |
| AGENTS.md 让 Codex 突然变聪明 | 它不增加能力,只是把正确行为的概率提高 |
| 规则越严,Codex 越听话 | 过严反而互相冲突;规则要短、明确、可检查 |
| AGENTS.md 写完就不动 | 项目变 / 同类错反复 / 团队升级 / 新风险区 → 同步更新 |
🔍 想再深一层(点击展开)
🗺️ AGENTS.md vs README vs 提示词 vs Skill:四者边界
复杂项目里这四样常被混淆。一张表分清:
| 形态 | 主要读者 | 生命周期 | 触发时机 | 典型内容 |
|---|---|---|---|---|
| 📖 README | 人 | 项目级长期 | 主动阅读 | 项目是什么、安装、运行、FAQ |
| 📜 AGENTS.md | Agent | 项目级长期 | Agent 启动自动加载 | 命令、目录、禁止事项、验收要求 |
| 💬 提示词 | Agent | 单次任务 | 你打字时 | 本次目标、临时边界、特定验收 |
| 🛠️ Skill | Agent | 跨项目长期 | Agent 主动调用 | 多步可复用工作流(如 PR review) |
💡 判断流:
- 这事写一次给所有人看?→ README
- 这事让 Agent 进项目就知道?→ AGENTS.md
- 这事只对这一次有效?→ 提示词
- 这事5 步以上、跨项目反复用?→ Skill
🤖 让 Codex 帮你起草 AGENTS.md(提示词模板)
第一次写不知道从哪开始?把下面这段交给 Codex:
请帮我为当前项目起草一份 AGENTS.md。
要求:
- 先阅读项目结构、package.json、README,不要修改文件
- 只写长期稳定规则,不写临时任务
- 每条规则要短、明确、可执行 / 可检查
- 按 6 个模块组织:项目概况 / 目录职责 / 开发命令 / 编码规则 / 禁止事项 / 验收要求
- 无法确认的命令标注「待确认」,不编造
输出前先说明:
1. 你发现的项目技术栈
2. 关键目录职责
3. 现有 README 里哪些规则可以复用
4. 哪些是你的推断(需我确认)起草完成后,再用下面提示词审查:
请审查刚起草的 AGENTS.md,按下面维度给出修改建议:
- 是否有空泛规则(如"代码要优雅")
- 是否有过期 / 编造的命令
- 是否有无法执行的要求
- 是否缺少测试或构建命令
- 是否把临时需求写成长期规则
- 是否能帮助新加入项目的 Agent / 人快速工作👥 团队协作下的演进:嵌套 AGENTS.md 怎么用
大型仓库里,根目录一份 AGENTS.md 不够用。Codex 支持嵌套加载:
仓库根/
├── AGENTS.md ← 全仓共享规则(包管理器、CI、PR 流程)
├── packages/
│ ├── api/
│ │ └── AGENTS.md ← 后端独有规则(数据库迁移禁止事项)
│ └── web/
│ └── AGENTS.md ← 前端独有规则(组件复用约定)
└── docs/
└── AGENTS.md ← 文档目录规则(Markdown 链接检查)Codex 的合并逻辑:从根开始往下串,越靠近 cwd 优先级越高(因为追加在最后)。
💡 团队建议:
- 全仓共享的写根目录
- 子模块独有的写子目录
- 子目录可覆盖父目录的同类规则(追加在后面会胜出)
📖 术语速查表
| 英文 / 缩写 | 中文 | 一句话解释 |
|---|---|---|
| AGENTS.md | — | 项目级 Agent 协作规则文件,开放标准 |
| AGENTS.override.md | — | 优先级高于 AGENTS.md 的覆盖文件 |
| instruction chain | 指令链 | Codex 把多份 AGENTS.md 串联成一份指令的机制 |
| interface | 接口 | 两方协作的稳定契约 |
| App Router | — | Next.js 13+ 的新路由系统 |
| typecheck | 类型检查 | TypeScript 编译期类型扫描 |
| lockfile | 锁文件 | 锁定依赖版本的文件(pnpm-lock.yaml 等) |
| generated 目录 | 自动生成目录 | 由工具生成、不应手改的文件 |
📖 官方文档来源:
📝 本章自检
| # | 问题 | 对应章节 | 自检 |
|---|---|---|---|
| 1 | AGENTS.md 的 3 层结构是什么?少哪一层会怎样? | 🧱 3 层结构 | ☐ |
| 2 | 怎么判断一条规则该写 AGENTS.md 还是写当次提示词? | 🔄 长期 vs 临时 | ☐ |
| 3 | 看到 AGENTS.md 里写「代码要优雅」,你应该怎么改?为什么? | 🚫 错误 ① | ☐ |
✅ 过关标准:能用一句话说清 —— "AGENTS.md 是项目和 Agent 的接口,把每次都要重复交代的规则沉淀成 项目自己会说的话。"
📚 下一篇
- ➡️ 05 · 为什么需要审批和沙箱 —— Agent 真的会动手,必须配边界
- 📖 编写项目规则文件
- ⚙️ 用 Rules 控制命令边界
- 🔄 用 Workflows 编排任务
🧭 一句话记住
AGENTS.md 不是文档,是协作协议。
把"每次都要重复交代"的规则,搬进项目,让项目自己说话。