外观
写好 AGENTS.md / CLAUDE.md
如果你用过 Claude Code、Codex 或 Cursor,大概率遇到过这种挫败:agent 每次开会话都像第一天入职——不知道测试命令是什么、不知道哪个目录不能碰、不知道团队用 pnpm 而不是 npm。你一遍遍在对话里纠正同样的问题,而这些问题本该写在一份文档里。
这份文档就是 AGENTS.md(或 CLAUDE.md)。它是代码库写给编码 agent 的入职文档:你教给新同事的那些"README 里放不下、但干活前必须知道"的东西,全部应该写在这里。写好它,是把编码 agent 从"聪明的实习生"变成"靠谱的团队成员"性价比最高的一步,没有之一。
一、定位:它到底是什么
AGENTS.md:跨工具的开放标准
AGENTS.md 于 2025 年 8 月发布,是一个为编码 agent 提供项目级指令的开放格式。它不是某一家厂商的私有设计——根据官方站点 agents.md 的说明,它来自整个 AI 编码工具生态的协作,参与方包括 OpenAI Codex、Amp、Google 的 Jules、Cursor、Factory 等。发布后被迅速采用:OpenAI 在 2025 年 12 月宣布共同发起 Linux 基金会旗下的 Agentic AI Foundation 时披露,AGENTS.md 已被超过 6 万个开源项目和 agent 框架采用,目前该格式由这个基金会托管维护。
它解决的问题很实际:在它之前,每个工具一套私有约定——Claude Code 读 CLAUDE.md,Cursor 读 .cursor/rules,Gemini 读 GEMINI.md。同一个仓库想让多个工具都"懂事",就得维护好几份内容几乎相同的文件。AGENTS.md 把这些收敛成一个公共文件:一次编写,多个 agent 通用。对于那些还没原生支持的工具,通常也有兜底配置(比如 Gemini CLI 可以在 .gemini/settings.json 里把 context 文件名指定为 AGENTS.md,Aider 可以在 .aider.conf.yml 里加 read: AGENTS.md)。
它和 README 的分工
README 是写给人的:项目简介、快速上手、贡献指南。AGENTS.md 是写给 agent 的:构建步骤、测试命令、代码规范、安全红线。官方的定位很直白——"AGENTS.md 是 agent 的 README"。两者刻意分开,是为了让 README 保持简洁、面向人类贡献者,而把冗长的操作性细节放到 agent 专属的地方。
CLAUDE.md:Claude Code 的对应机制
CLAUDE.md 是 Anthropic 的 Claude Code 读取的项目记忆文件。机制相同:每次会话启动时自动加载进上下文。值得注意的是,截至目前 Claude Code 官方文档明确表示它读取的是 CLAUDE.md 而非 AGENTS.md(社区关于原生支持 AGENTS.md 的 issue 已经挂了七个月以上没有官方回应)。实践中常见的折中是:以 AGENTS.md 作为单一事实来源,在 CLAUDE.md 里写一行 @AGENTS.md 把它 import 进来——CLAUDE.md 原生支持 @路径 的 import 语法。
关于 CLAUDE.md 的写法,Anthropic 工程博客给出的"黄金法则"是:保持简洁、人类可读(concise and human-readable),并强调这个文件值得像调 prompt 一样反复迭代打磨(tune it)。这条原则对 AGENTS.md 完全通用,本文后面的内容两者都适用。
二、它影响什么:为什么这个文件杠杆这么大
理解这个文件的价值,要从 agent 的上下文机制说起。如果你读过上下文工程一章,会记得一个核心事实:agent 的每次会话,能"看到"什么决定了它能"做对"什么。
AGENTS.md / CLAUDE.md 的特殊之处在于它的加载位置:
会话启动
│
├─ system prompt(工具厂商写的,你控制不了)
├─ AGENTS.md / CLAUDE.md ← 你的文件在这里,每次会话必进上下文
│ ├─ 根目录文件(始终加载)
│ ├─ 全局文件(如 ~/.claude/CLAUDE.md,跨项目生效)
│ └─ import 进来的其他文件
├─ 用户的对话输入
└─ agent 工具调用产生的上下文(文件内容、命令输出……)这意味着三件事:
- 它塑造每一次会话的行为基线。 不是某个任务的一次性指令,而是持久生效的"团队规范"。写进去一条"提交前必须跑
pnpm test",agent 每次收尾时都会去跑——AGENTS.md 官方 FAQ 明确说明,列在文件里的测试命令,agent 会主动执行并修复失败后再结束任务。 - 它占用 context window 的预算。 这是硬币的另一面:文件里的每个 token 每次会话都要付费,都在挤压真正干活所需的空间。一个 5000 字的散文式 AGENTS.md,不如一个 300 字刀刀见骨的。长度本身就是质量指标。
- 它的优先级低于用户的显式指令,高于 agent 的"默认猜测"。 官方 FAQ 说得很清楚:冲突时,离被编辑文件最近的 AGENTS.md 胜出,而用户在对话里的显式指令高于一切。所以它负责"默认值",不负责"铁律"。
一句话总结:这个文件是你对 agent 行为最便宜、最持久的干预点。不改模型、不写代码、不配 harness,只改一个 markdown 文件,就能系统性地减少一类重复错误。
三、结构模板:一份可以直接套用的 AGENTS.md
社区实践和官方示例收敛出的共识结构是这几块:项目概述、技术栈、目录约定、构建与测试命令、代码规范、禁区、工作流偏好。下面是一份完整模板,针对一个 pnpm + TypeScript 的 monorepo,你可以直接改造使用:
markdown
# AGENTS.md
## 项目概述
- 这是一个 VitePress 驱动的中文技术文档站,内容关于 AI Agent。
- 站点源码在 docs/,构建产物在 docs/.vitepress/dist/(不要手改)。
## 技术栈
- Node 20+, pnpm 9(不要用 npm/yarn,锁文件是 pnpm-lock.yaml)
- VitePress 1.x, Vue 3, TypeScript strict mode
## 目录约定
- docs/<栏目>/<页面>.md:内容页,栏目名固定,新增栏目需先改 config.mts
- docs/public/:静态资源,图片放这里,用 /xxx.png 引用
- 新增页面必须同时在 docs/.vitepress/config.mts 的 sidebar 里注册
## 常用命令
- 安装依赖:`pnpm install`
- 本地开发:`pnpm docs:dev`
- 构建:`pnpm docs:build`(提交前必须能跑通)
- 单测:`pnpm test`;只跑一个用例:`pnpm vitest run -t "<名称>"`
## 代码规范
- TypeScript strict,不允许新增 any
- 2 空格缩进,单引号,行尾不加分号
- markdown 正文用简体中文,技术术语保留英文
## 禁区(不要做的事)
- 不要修改 docs/.vitepress/theme/ 下的主题文件,除非任务明确要求
- 不要提交 package-lock.json 或 yarn.lock
- 不要在正文里编造 URL、版本号、benchmark 数字;不确定就标注
## 工作流偏好
- 改代码先跑测试再提交;测试红了不要提交
- commit message 用英文,格式:`<scope>: <what>`(如 `docs: add rag page`)
- PR 标题格式:`[<栏目>] <标题>`
- 改动超过 3 个文件时,先在回复里列出计划再动手几个写模板时的判断依据,比模板本身更重要:
- 只写"agent 不知道或会猜错"的东西。 "本项目用 TypeScript"这种 agent 扫一眼
package.json就知道的事实不用写;"必须用 pnpm 而不是 npm"这种会猜错的才值得写。 - 命令必须完整可执行。 写
pnpm test而不是"运行测试"。agent 会照着字面执行,模糊描述只会逼它瞎猜。 - 禁区要具体到路径和动作。 "注意安全"是废话;"不要修改
migrations/下已应用的迁移文件"才有约束力。 - 工作流偏好写"收尾标准"。 比如"提交前跑通构建""改动前列计划",这些定义了 agent 什么时候算"干完了",是减少返工的关键。
生成第一版,然后手动打磨
主流编码 agent(Claude Code 的 /init、Codex 等)都能扫描仓库自动生成初版 AGENTS.md/CLAUDE.md。这是很好的起点,但生成稿通常啰嗦且抓不住重点——它能看到代码,看不到你的偏好和痛点。正确姿势是:让它生成,然后你逐条删、逐条改,只保留那些"agent 曾经犯过的错"和"你确定会猜错的默认值"。这个文件值得花一小时认真打磨,回报是之后每次会话都受益。
四、正反例对照:三种典型的糟糕写法
看过几十份真实仓库里的 AGENTS.md / CLAUDE.md 之后,糟糕的写法基本逃不出三类。下面逐一给出反例和改写。
反例一:泛泛而谈,全是正确废话
markdown
## 代码质量
- 编写高质量的代码
- 保持良好的代码风格
- 注意性能和安全性
- 写必要的注释和文档问题:这些指令没有任何可执行的信息量。"高质量"对 agent 不构成约束,它自认为每一行都很高质量。这类内容唯一的作用是消耗 context 预算,还可能稀释真正重要的指令——上下文里无关内容越多,关键指令被遵循的概率越低。
改写:把形容词换成可验证的判断标准。
markdown
## 代码规范
- 函数超过 40 行必须拆分
- 所有对外 API 的入参用 zod schema 校验,校验失败返回 400 + 错误详情
- 禁止引入新依赖,除非任务明确要求;先用 `src/utils/` 里的现有工具函数反例二:过期或错误的命令
markdown
## 测试
- 运行 `npm run test:unit` 执行单元测试
- 用 `make build` 构建项目问题:项目半年前从 npm 迁到了 pnpm、从 Makefile 迁到了 turbo,但没人更新这个文件。后果比"没写"更糟:agent 会忠实地执行 npm run test:unit,报"命令不存在",然后开始自行发挥——瞎猜别的命令、甚至自己造一个测试脚本。一条过期的指令不是中性信息,是主动误导。
改写:只写你亲自验证过的命令,并给关键命令加上"如何验证"的线索。
markdown
## 测试(2026-06 验证过)
- 全量测试:`pnpm turbo run test`(约 2 分钟)
- 单个包:`pnpm test --filter @app/server`
- 如果以上命令报错,先查 package.json 的 scripts 字段,不要自行发明命令最后那行"报错时怎么办"是一个被低估的技巧:给 agent 一条明确的失败退路,能避免它在错误发生时自由发挥。
反例三:散文叙事,把规范写成博客
markdown
## 关于本项目的架构
我们最初在 2023 年选择了微服务架构,因为当时团队预计流量会快速增长。
后来实践证明单体更适合我们的规模,于是 2024 年开始了漫长的合并之旅。
目前我们处在一个过渡状态:大部分业务逻辑已经合并到了 apps/main,
但订单模块因为历史原因仍然独立部署。说起订单模块,它涉及到……问题:agent 需要的是"现在该怎么办",不是"我们是怎么走到今天的"。历史叙事没有操作性,agent 读完后依然不知道:改代码应该改哪里?订单模块能不能动?而且这种写法通常又长又绕,是 context 预算的最大浪费者。
改写:历史只保留影响当前决策的结论,一句话封顶。
markdown
## 架构现状
- 代码正在从微服务合并回单体。新业务逻辑一律写在 apps/main/,禁止新增独立服务
- apps/orders/ 是遗留的独立部署模块,只修 bug,不加功能,预计 2026 Q4 迁移
- 数据库访问统一走 apps/main/db/ 的 repository 层,禁止在业务代码里直接写 SQL三类反例的共同病根是一样的:作者把这份文件当成"写给人类的文档"而不是"写给 agent 的操作指令"。检验方法很简单——逐条问自己:删掉这一条,agent 的行为会变差吗?如果答案是否,就删掉。
五、分层与作用域:让对的指令在对的位置生效
真实的项目很少一份文件打天下。两套体系都支持分层,但规则不同,混用容易踩坑。
AGENTS.md 的嵌套规则
规则干净明了:agent 自动读取离被编辑文件最近的那个 AGENTS.md,就近者优先。这意味着 monorepo 里可以在每个子包放一份自己的 AGENTS.md:
repo/
├── AGENTS.md ← 全局约定:技术栈、提交规范、禁区
├── apps/
│ ├── web/
│ │ └── AGENTS.md ← 前端专属:组件规范、样式方案
│ └── server/
│ └── AGENTS.md ← 后端专属:DB 迁移流程、API 约定
└── packages/
└── ui/
└── AGENTS.md ← 组件库专属:发版流程这不是理论设计——官方站点提到,OpenAI 自己的主仓库在写作时就有 88 个 AGENTS.md 文件。分层的原则是:根文件写"全仓库恒真"的东西,子文件写"只有在这个目录才成立"的东西。子文件不该重复根文件的内容(重复意味着两处都要维护,必然漂移),只写增量。
CLAUDE.md 的层级与 imports
Claude Code 的体系稍有不同,它区分几种来源:
| 层级 | 位置 | 作用域 |
|---|---|---|
| 全局用户记忆 | ~/.claude/CLAUDE.md | 你的所有项目:个人偏好、通用习惯 |
| 项目记忆 | <repo>/CLAUDE.md | 当前项目,提交进 git,团队共享 |
| 项目本地记忆 | <repo>/CLAUDE.local.md | 当前项目,不入库,个人实验性偏好 |
| 子目录文件 | 子目录下的 CLAUDE.md | agent 访问该目录文件时按需加载 |
此外 CLAUDE.md 支持 @路径 的 import 语法,可以把规则拆到多个文件里再引入,比如:
markdown
# CLAUDE.md
@AGENTS.md
@docs/conventions/api-design.mdimport 是管理大文件的好手段:主文件保持精简的"骨架",细节文档按需引入。但注意别嵌套太深——每多一层间接,就多一分"你以为 agent 读了其实没读"的风险。Claude Code 里可以用 /memory 命令检查当前会话实际加载了哪些指令文件,写完规则后务必看一眼,"加载了吗"比"写得好吗"优先。
两套文件要不要并存?
如果团队只用 Claude Code,一份 CLAUDE.md 足够。如果工具链是混合的(这在 2026 年的团队里越来越常见),推荐的做法是:AGENTS.md 作为单一事实来源,CLAUDE.md 只写一行 @AGENTS.md 再加少量 Claude Code 专属的配置。千万不要维护两份内容平行、各自演化的文件——内容漂移是必然的,而 agent 不会告诉你它在哪一份里读到了旧指令。
旧文件的迁移陷阱
从 AGENT.md、.cursorrules 等旧约定迁移时,官方推荐的做法是改名后建符号链接(mv AGENT.md AGENTS.md && ln -s AGENTS.md AGENT.md)保持向后兼容。但要定期检查有没有工具还在读旧路径,链接只是过渡手段,不是长期方案——长期方案是所有工具都收敛到 AGENTS.md。
六、维护纪律:这份文件是活的
AGENTS.md 最大的失败模式不是写得差,而是写完就忘。代码在演进,文件不跟进,三个月后它就是反例二里那种"主动误导"的来源。几条可执行的纪律:
- 让"更新 AGENTS.md"成为某些 PR 的必选项。 迁移包管理器、改测试命令、调整目录结构、新增禁区——这类变更的 PR 模板里加一行 checkbox:"本 PR 是否改变了 AGENTS.md 里的任何事实?" 把维护成本摊到每次变更上,而不是攒到文件彻底过期。
- agent 每次"犯错"都是一次更新信号。 这是最重要的一条心法。当 agent 又用了 npm、又改错了目录、又忘了跑 lint——别只在对话里纠正,问自己:这个错误下次还会发生吗?会的话,把纠正写进 AGENTS.md。这份文件的内容应该主要由"agent 真实犯过的错"驱动生长,而不是你坐在椅子上空想它会犯什么错。
- 定期做减法。 每个季度通读一遍,删掉:模型已经能自动推断的(随着模型变强,很多早期需要显式写明的常识变得多余)、项目已经不再成立的、从来没起过作用的。文件变短通常是变好。
- 像 review 代码一样 review 它。 它进了 git、影响每次会话,就该走 PR 流程。团队里任何一个人随手往里加"我喜欢用 XXX 风格"而没有共识,这份文件就会变成噪音堆积场。
用 eval 验证效果
"写了 AGENTS.md 到底有没有用"不该靠感觉。严肃的做法是把它当成一次 prompt 变更,用评测验证——思路与进阶:Agent 评测一章一致:
- 攒一组 agent 在这个仓库里真实失败过的任务("用错了包管理器""改完没跑测试""动了不该动的文件"),作为回归集。
- 在有/无(或改前/改后)AGENTS.md 两种条件下各跑几遍,比较任务成功率和违规次数。
- 每次大改这份文件时重跑一遍。改动没有带来可测的行为改善,就回滚。
这听起来重,但实际上一个十几条 case 的回归集、半天就能搭起来,换来的是你对这份文件的每一次修改都有证据而非玄学。关于 eval 的落地细节,参见实战评测。
七、泛化:不止编码 agent
"给 agent 写入职文档"这个模式,早已溢出编码场景。理解它的本质——把持久的、跨会话的行为约定外化成一个可读可版本化的文件——你会发现它适用于几乎所有长期运行的 agent:
- 人格与语气文件。 个人 agent 框架 OpenClaw 用
SOUL.md定义 agent 的声音:语气、观点、幽默边界、默认的直白程度。官方文档的建议和本文如出一辙——只写能改变行为的东西,短胜于长,"别写成人生故事或没有行为效果的情绪墙"。除 SOUL.md 外还有USER.md(agent 服务的是谁)等分工文件。 - 团队约定文件。 研究类、运营类 agent 同样受益:一份
TEAM.md写清"产出格式、引用规范、什么算可信来源、哪些操作需要人工确认",效果等同于编码场景的 AGENTS.md。 - 你自己的系统提示词资产。 如果你在用 API 自己搭 agent,AGENTS.md 的思想对应的就是 system prompt 里"项目上下文"那一层——同样的纪律:简洁、具体、可验证、随代码演进。参见提示词工程和上下文工程。
甚至可以把这个模式推到极限:Claude Code 案例一章里讨论的 harness 设计,本质上就是"给 agent 的环境和文档"的系统工程,AGENTS.md 只是其中最轻量的一环。如果你在准备自己的项目集,一份被精心维护的 AGENTS.md 本身就是很好的作品——它展示的是你驾驭 agent 的元能力,这在面试里比"我用过 XX 框架"有说服力得多,参见作品集项目。
最后给一个判断标准收尾:一份好的 AGENTS.md,读起来应该像你们团队最好的那位工程师花 15 分钟给新人做的入职 briefing——没有废话,全是"不告诉你你就会踩的坑"。如果你的文件读起来像公司 Wiki 的"关于我们"页面,重写它。
参考资料
- AGENTS.md 官方网站 —— 格式的权威定义、FAQ、嵌套规则与各工具配置方式,本文大量事实来源于此
- OpenAI co-founds the Agentic AI Foundation under the Linux Foundation —— 2025 年 12 月,披露 AGENTS.md 已被 6 万+ 项目采用并移交 Linux 基金会托管
- Claude Code Memory / CLAUDE.md 文档(社区镜像) —— Anthropic 关于 CLAUDE.md 层级、import 语法与"concise and human-readable"黄金法则的官方文档内容
- CLAUDE.md Best Practices: What the Evidence Supports (2026) —— 对 CLAUDE.md 各类写法的证据导向梳理,含
@AGENTS.mdimport 的推荐做法 - Anthropic Claude Code issue #31005 —— 社区要求原生支持 AGENTS.md 的长期 issue,反映 Claude Code 当前只读 CLAUDE.md 的现状
- OpenClaw: SOUL.md personality guide —— 非编码场景的人格文件实践,"只写有行为效果的内容"原则与 AGENTS.md 一脉相承
- agents.md: The Complete Guide to the Open Standard (PRPM) —— 对 AGENTS.md 生态与采用现状的第三方深度梳理