写给 Spec-First 团队的 AGENTS.md:什么该写进去

加一份 AGENTS.md 大约花十分钟。让它保持为真则需要纪律——因为和代码不同,指令文件开始说谎时,没有任何测试会失败。我们自己那份声称技术栈是 React 和 Tailwind,整整五个月。而这个仓库从来没有过一行 React。

状态已复核发布2026-09-08阅读7 分钟作者编辑部政策编辑政策

AGENTS.md 是什么

这个格式对自己的定义是「写给 agent 的 README」:一个可预期的位置,用来放 coding agent 动你项目之前需要的上下文。它放在仓库根目录,没有必填字段,被二十多个工具读取,包括 Codex、Jules、Cursor、VS Code、Zed、Aider 以及 GitHub Copilot 的 coding agent。这个覆盖面就是使用它的全部理由:写一次的规则,团队里每个 agent 都继承,不管某个开发者今天用的是哪一个。

它是 README 的补充,不是替代。README 写给正在判断要不要用这个项目的人;AGENTS.md 写给马上要修改它的 agent。这个区别在细节上最明显:确切的测试命令、某个由生成器接管、人不能手改的目录、某个依赖被锁版本的原因——这些放进 README 会显得杂乱,对人类贡献者也没什么意义。

但以上都不是难点。难点在于「仓库级规则」和「单次改动的决策」之间的边界,而你的工具链对此不做任何强制。

我们自己那份错了五个月

这个站点是 219 个手写 HTML 页面、原生 ES 模块,加一组 Node 生成器。没有框架,没有打包器,没有 JSX。2026-04-07 我们提交了一份 AGENTS.md,它的 Tech Stack 一节写着:React、TypeScript、Tailwind CSS、shadcn/ui、Lucide 图标、Framer Motion。我们在 2026-09-08 写这篇文章时才改掉它,中间隔了五个月。

这份文件不是随手写的。它源自一个模板,写在技术栈还是「计划」而非「事实」的时刻,然后在没有任何人决定说谎的情况下,自己老化成了谎言。真正值得记住的是这个失效模式:指令文件会悄悄腐坏,因为没有任何东西执行它。写错的函数签名会让测试变红;写错的技术栈声明只会产生一个自信地为静态 HTML 页面提议 React 组件的 agent,以及一个从此默默忽略这份文件的开发者。

唯一的缓冲是同一节里恰好有一句对冲——「如果项目已有结构,遵循现有技术栈」——这也是损失止步于「无效建议」而没有变成「错误代码」的原因。这句对冲值得抄,但它是安全带,不是可以乱开车的理由。

判定标准:这条规则能活多久

大多数糟糕的 AGENTS.md 都栽在同一个问题上:下一个功能来的时候,这一行需要改写吗?如果需要,那它就是一条漏进错误文件的规格。

属于 AGENTS.md属于某次改动的规格
测试命令,以及什么算通过哪些测试证明这一条验收标准
由生成器接管、人不能改的目录本次任务的可写文件范围
提交与 PR 规范这次发布的回滚方案
哪些区域需要格外小心:支付、鉴权、迁移这次改动为什么碰了鉴权,以及意味着什么
技术栈,以及「不要引入新框架」这条指令决定加某个依赖,附带理由

由此得到一个实际结论:AGENTS.md 应该比团队预想的更短。仓库级为真的事实本来就不多。所有随改动变化的内容,都属于随改动产出的那份产物——一份规格包,或者当多个 agent 需要同一份事实来源时,一份仓库级的 spec.md

一份可以直接抄的 AGENTS.md

格式没有必填字段,所以结构靠约定。下面这些小节覆盖的是 agent 真正会搞错的东西,顺序也按它们需要的先后排列。

# AGENTS.md

## 这个仓库是什么
一段话。代码库的形态,以及新人最常搞错的那一点。

## 技术栈
如实写现在有什么。如果某个模板或兄弟仓库会让人误判,
就明确写出「没有什么」。

## 命令
build:  npm run build
test:   npm run check
serve:  npm run dev
说明提出改动前必须通过哪一条。

## 边界
- 生成产物:列出路径。改生成器,不要改产物。
- 没有批准的规格不要碰:数据库迁移、鉴权、计费。
- 不要为二十行的问题引入一个依赖。

## 约定
提交信息格式。PR 期望。测试放在哪、怎么命名。

## 收尾前
一次改动必须带上的证据:跑了哪条命令、输出了什么、
跳过了什么以及为什么。

关于上面两节的补充。技术栈一节应该写出「没有什么」,而不只是「有什么」——「没有 React,没有打包器,页面是手写 HTML」能挡掉一整类建议,而只写「原生 ES 模块」做不到。边界一节的价值在于点名生成产物:任何带生成器的仓库,早晚会收到一个改生成产物的 PR,而修复它只需要指令文件里的一行。

嵌套文件:就近生效

子目录里的 AGENTS.md 是格式的一部分。agent 会读目录树上最近的那份,所以最近的优先,每个子项目都可以给出与根目录不同、且不产生歧义的指令。据称 OpenAI 自己的仓库里就有 88 份。

对 monorepo 来说,这是「文件可用」和「文件不可用」的分界。一份试图描述五个不同技术栈的根文件,会变成一篇例外清单;在 packages/api 里工作的 agent 得先读完四段无关内容才能找到适用的那段。正确做法是每个包一份、各自简短、各自在自己目录里为真。根文件留给真正横跨全局的东西:提交规范、发布流程、以及哪些区域动手前必须先有规格。

AGENTS.md、CLAUDE.md 和 skill

同时用多个 agent 工具的团队,最后会有多份指令文件,而诱惑是复制粘贴。别这么做——两份陈述同一条规则的文件,一个季度内必然产生分歧,而且没人知道 agent 读的是哪一份。

文件谁读它该放什么
AGENTS.md二十多个工具,就近生效所有可迁移的内容:技术栈、命令、边界、约定
工具专属文件(例如 CLAUDE.md单个工具,每个会话都加载只放该工具独有的内容,其余指向 AGENTS.md
skill单个工具,按需加载流程:规格模板、评审清单,一切你本来要粘贴的东西
规格人和 agent,每次改动一份目标、非目标、验收标准、证据

第二行和第三行的区别在于成本。会话级文件每一轮都要付费,所以它该放事实,不该放流程。skill 在任务匹配时才加载,所以它可以写得长。规格每次改动写一份,像代码一样被评审。

它会怎么变质

症状根因修法
agent 提议代码库根本没用的模式文件描述的是设想中的技术栈,不是真实的照仓库今天的样子写,不要照计划写
开发者不再读它它长成了一篇风格随笔删掉 linter、formatter、测试已经强制的一切
各节之间自相矛盾单次改动的决策被逐渐追加进来套用判定标准,把会变的行挪进规格
没人发现它错了工作流里没有任何环节会重读它任何改动技术栈、命令或边界的 PR 都要顺带复核它

怎么让它保持为真

对付悄悄腐坏,唯一持久的办法是让文件里的主张可被验证,并且给某个人一个去验证的理由。三个习惯能解决大部分问题。写可以被一条命令证伪的主张——「npm run check 必须通过」可以验证,「我们重视质量」不能。把技术栈、命令、边界的变更,当成必须在同一个 PR 里更新 AGENTS.md 的变更,就像 API 变更要更新契约一样。以及每季度对着仓库从头到尾读一遍——我们那份就是这样被抓到的。

如果你的团队已经在写规格,这些都不是新流程,只是把同一套纪律往上提了一层:规格固定一次改动的意图,AGENTS.md 固定所有改动的上下文。失效模式也一样——没人拿去对照 diff 的规格,和没人拿去对照仓库的指令文件,最后都会退化成「主要用来引用」的文档。

参考资料

格式相关事实于 2026-09-08 对照上述来源核验。文中「五个月」来自本站仓库自身的提交历史:8be159c(2026-04-07)与 e7969a4(2026-09-08)。

关键词:AGENTS.md · agent 指令文件 · CLAUDE.md · monorepo agent 规则 · spec-first 流程 · AI 编码约定