Tools

工具速评:AGENTS.md 正在成为唯一指令层,但它接管不了全部场景

4 min read ·

如果你最近同时用两个以上的编码代理,大概经历过这种场面:在 Claude Code 里配好的项目约定,切到 Cursor 要重新写一遍;给同事推荐 Codex 时,又得解释一遍构建命令为什么是那个。

配置碎片化不是小麻烦。它意味着同一份知识要在多个文件里维护,每次修改构建流程都要同步好几处,漏掉一处就出现「这个工具里能跑、那个工具里跑不通」的灵异现象。

一、碎片化是怎么形成的

每个代理工具最初都定义了自己的指令文件,这在早期是合理的:

工具原生指令文件
Claude CodeCLAUDE.md
OpenAI CodexAGENTS.md
Gemini CLIGEMINI.md
Cursor.cursorrules,后改为规则目录
GitHub Copilot.github/copilot-instructions.md
AiderCONVENTIONS.md
Windsurf专属规则文件

七种工具七种约定。开源项目维护者被迫做选择:要么只服务一个工具,要么把同样的内容写七遍。多数人选择写两三份,剩下的靠用户自己填。

转折点是 AGENTS.md 作为开放约定的出现。它没有归任何一家厂商,本质只是一个约定俗成的文件名加 Markdown 内容。这个「没有所有者」的特性反而是它扩散最快的原因。

二、现在的支持现状

截至最近的公开资料,已经识别 AGENTS.md 的工具超过三十个,覆盖面相当广:

  • 原生采用:OpenAI Codex、Sourcegraph Amp、Google Jules、Aider、Zed、Factory、Devin、Windsurf、VS Code、Gemini CLI 等;
  • 兼容读取:Cursor 在规则目录之外也会识别 AGENTS.md;
  • 导入或回退:Claude Code 支持在没有 CLAUDE.md 时读取 AGENTS.md,也可以通过导入的方式把 AGENTS.md 的内容引入自己的指令链。

采用规模上,公开报道的数字是已有超过四万个开源项目引入 AGENTS.md,其中包括不少大型基础项目。这个量级意味着它已经从「某些工具的偏好」变成了事实标准。

值得单独提一句的是演进过程。Claude Code 的社区曾经长期提交支持 AGENTS.md 的特性请求,讨论持续了相当长的时间才落地。这个过程本身说明开放标准的普及通常滞后于社区共识——大家在讨论里都认同「应该统一」,但真正接入要等各家自己的排期。

三、一份能跨工具的 AGENTS.md 该写什么

通用文件的正确用法是只放所有工具都需要的项目知识

适合写进去的内容:

  • 环境与构建:包管理器、安装命令、构建命令、运行测试的命令;
  • 代码约定:语言版本、格式化工具、命名规则、目录职责;
  • 协作规则:提交信息格式、分支策略、PR 要求;
  • 已知陷阱:哪些命令不要跑、哪些文件是自动生成的不要手改。

不应该写进去的:

  • 密钥、token、内部地址;
  • 逐文件的目录树(会过期,且占上下文);
  • 只对单次任务有效的临时指令。

一个务实的结构长这样:

# AGENTS.md

## 环境
- 包管理器:pnpm,不要用 npm install
- Node 版本见 .nvmrc

## 常用命令
- 开发:pnpm dev
- 类型检查:pnpm check
- 测试:pnpm test

## 约定
- 组件文件用 PascalCase,工具函数用 camelCase
- 新增页面必须同时更新导航配置
- 不要手动编辑 src/generated/ 下的任何文件

## 陷阱
- 构建脚本会清空缓存目录,这是预期行为

💡 提示:写「不要做什么」比写「要做什么」更有价值。代理对否定式约束的遵循度更依赖具体的失败描述,所以把踩过的坑写清楚,比罗列一堆抽象原则有用得多。

四、工具专属能力仍然需要专属文件

通用约定解决不了所有问题。有些规则天然是和工具绑定的:

  • 某个工具支持自定义斜杠命令,另一个不支持;
  • 某个工具允许声明规则适用的路径 glob,另一个只能全局生效;
  • 某个工具的上下文预算更紧,需要更精简的表述。

这类内容应该留在工具专属文件里。推荐的做法是让专属文件引用而不是复制通用内容:

# CLAUDE.md

本项目通用约定见 AGENTS.md。以下为本工具补充:

- 生成新组件时使用项目内的脚手架命令
- 长文件读取优先使用分段方式

这样维护点只有一处,通用规则改一次,所有工具都跟着更新。而专属文件只承载真正无法共享的那部分。

五、monorepo 与作用域

单文件约定在 monorepo 里会遇到真正的麻烦:仓库根部的规则对某个子包不适用,或者子包有自己的构建流程。

解决方向有两个。一是嵌套指令文件——多数工具会从工作目录向上查找,子目录里的文件可以为该子树追加规则。二是规则目录加作用域声明,也就是 Cursor 那套演进方向的思路:每条规则一个文件,通过元信息声明适用路径。

选择哪种取决于你的工具组合。如果你的主力工具链都支持嵌套,嵌套文件最简单也最通用;如果需要在同一个包内按路径精细控制规则生效范围,就得用规则目录格式。

⚠️ 注意:不同工具对嵌套文件的合并语义并不完全一致,有的追加、有的覆盖、有的只取最近一层。关键约束建议在每一层显式写清,不要依赖继承行为。

六、结论

AGENTS.md 的价值不只是省掉重复劳动,更重要的是把「项目怎么构建、怎么测试、有哪些约定」这件事从工具附属品提升为仓库的一等资产。它用最朴素的形式——一个 Markdown 文件——做到了七种专有格式没做到的事。

但它接管不了全部场景。工具专属能力、精细的作用域控制、以及需要机器解析的规则声明,仍然各有自己的机制。务实的组合是:通用知识集中在 AGENTS.md,工具补充留在专属文件且只做引用,作用域敏感的部分交给规则目录格式。

判断标准很简单——如果一条规则换个工具依然成立,它就该住在 AGENTS.md 里。

Frequently asked questions

AGENTS.md 到底是什么,和 CLAUDE.md 什么关系?
AGENTS.md 是一个纯 Markdown 的开放约定,放在仓库根目录,用自然语言描述项目怎么构建、怎么测试、有哪些约定。它和 CLAUDE.md 不是竞争关系而是包含关系:工具专属文件通常支持导入或回退到通用文件。例如 Claude Code 在没有 CLAUDE.md 时读取 AGENTS.md,也可以在一个很薄的 CLAUDE.md 里引用共享内容。通用内容放 AGENTS.md,工具专属内容放各自的文件,是当前比较务实的做法。
为什么 .cursorrules 不再是首选?
因为它是单文件格式且没有作用域概念。项目一大,所有规则塞进一个文件,无法表达「这条规则只对前端目录生效」。Cursor 后来改成了规则目录格式,每条规则一个文件并带元信息,可以声明适用路径。老的单文件写法仍在向后兼容,但新项目没有理由再用它。这个演进本身说明了一件事:单文件约定在扩展到中大型仓库时必然遇到作用域瓶颈。
多工具协作时最容易踩的坑是什么?
规则冲突且没有优先级。当 CLAUDE.md、AGENTS.md 和规则目录同时存在且内容不一致时,不同工具按各自的发现顺序解析,得到的行为可能完全不同。你在 A 工具里看到代理正确遵循了约束,换到 B 工具却完全不生效。解决办法是避免重复描述:同一个约束只在一个文件里定义,其他文件做引用而不是复制。
monorepo 里怎么组织指令文件?
利用嵌套发现机制。多数支持该约定的工具会从当前工作目录向上查找指令文件,因此在子包目录再放一个 AGENTS.md,就能为那个包追加或覆盖规则。实践上把仓库根的文件写成全局约束(语言版本、提交规范、通用测试命令),把包级的文件写成该包特有的构建流程和目录说明。注意不同工具对嵌套的合并语义不完全一致,关键约束最好显式写清楚而不是依赖继承。
哪些内容不该写进 AGENTS.md?
三类。第一类是密钥和凭据,它在版本控制里明文存储,且会被自动送进模型上下文;第二类是能由工具自动推导的信息,比如逐文件列出的目录树,会快速过期还白占上下文预算;第三类是具体到某次任务的一次性指令,那属于对话内容而不是仓库约定。指令文件应当只放长期有效、对所有人都成立的规则。
// next.txt ›

Some outbound links in this post are affiliate links — see disclosure.