给编码 agent 一份真正的项目说明书:把 AGENTS.md 写到能用
同一个 coding agent,在没配指令文件的仓库里像个新人,在配好的仓库里像熟手,差距往往只在一份文件。AGENTS.md 每次会话开始都会加载进上下文,它比任何一条聊天里的嘱咐都持久:你不在场时,它替你把项目的关键信息带进每一轮对话。[3] 这是投入产出比最高的 agent 提效手段之一,但多数人把它写成了又一份没人读的 README。
一份给机器的文件,不是给人类看的文档#
AGENTS.md 的定位很明确:README 是给人看的,写快速开始和贡献指南;AGENTS.md 补上 coding agent 需要的额外上下文,比如构建步骤、测试命令和项目约定,这些塞进 README 只会让它臃肿。[1] 它现在由 Linux 基金会旗下的 Agentic AI Foundation 维护,被 30 多个工具读取,包括 Codex、Copilot、Cursor、Gemini CLI、Aider 和 Zed。[1] 好处是只维护一份,所有 agent 通用。格式上没有任何强制字段,就是普通 Markdown,agent 直接解析文本;也没有所谓的最佳章节顺序,按项目实际需要写。[1]
好文件长什么样#
GitHub 的分析师扫过 2500 多个公开仓库的 agent 文件,结论很直接:大多数文件失败是因为太含糊,“你是一个乐于助人的编码助手”不工作,明确职责和边界的才工作。[2] 成功的文件有四个共同点。命令放前面且带全参数,npm test 要写成 npm test -- --watch=false,agent 会反复引用这些命令。[2] 一个真实代码片段胜过三段描述,直接展示好输出长什么样。[2] 边界要写死,“绝不提交密钥”是最常见也最有用的一条。[2] 技术栈要具体到版本,说”React 18 配 TypeScript、Vite、Tailwind”,别说”React 项目”。[2] 覆盖命令、测试、项目结构、代码风格、git 流程、边界这六个方面,文件就进入头部行列。[2]
Anthropic 的建议可以概括成一句话:短而具体。CLAUDE.md 是上下文而不是强制配置,写得太长,模型会忽略一半。[3] 官方给的目标是单文件 200 行以内,越长越消耗上下文、服从性越差。[3] 每加一条规则先自问:删掉它,agent 会不会犯错?不会就删。[4] 规则要具体到可以验证:“用两个空格缩进”好过”格式写整齐点”;“提交前跑 npm test”好过”记得测试”。[3] 什么时候加规则也有讲究:同一个错误第二次出现、你在聊天里重复输入同样的纠正、新同事需要同样上下文才能上手,这三种情况才值得写进去。[3]
快速上手:一份能直接改的模板#
对大多数中小仓库,根目录一份 20 行上下的文件就够。以下模板覆盖 GitHub 分析出的六个核心方面,按你自己的命令改即可:[2]
# AGENTS.md
## 构建与测试
- 安装依赖:pnpm install(勿提交 pnpm-lock.yaml 的手动改动)
- 单测:pnpm test -- --watch=false
- 类型检查:pnpm typecheck;提交前必须通过
- 改动涉及页面时:pnpm build 确认无报错
## 项目结构
- src/pages/ 放页面,src/components/ 放可复用组件
- API 层在 src/lib/api/,禁止在组件里直接 fetch
## 代码风格
- TypeScript 严格模式;组件用函数式写法
- 示例见 src/components/Button.tsx,新组件对齐它的结构
## 边界
- 绝不提交 .env、密钥或 node_modules/
- 不改公共 API 签名,除非先在 issue 里说明理由
文件里列出的命令,agent 会在完成任务前尝试执行并修复失败,所以命令必须真实可跑。[1] 写完先让 agent 按文件做一件小事,观察它是否真的用了这些命令,再逐步增补。
monorepo 和跨工具的两个关键模式#
大仓库把规则堆在根目录一份文件里,会越写越长。官方做法是按包嵌套:每个子项目放一份自己的 AGENTS.md,agent 自动读取目录树中最近的一份,就近优先。[1] 官方举例说 OpenAI 主仓库当时有 88 份 AGENTS.md。[1] 根目录只留全局约定,子包写自己的构建和测试命令。
跨工具的场景要处理一个兼容性差异:Claude Code 读的是 CLAUDE.md 而不是 AGENTS.md。[3] 官方推荐的衔接方式是在 CLAUDE.md 第一行写 @AGENTS.md 导入,这样两个工具读同一份指令,不重复维护;想加 Claude 专属内容就写在导入行下面。[3] 不想加专属内容时,符号链接 ln -s AGENTS.md CLAUDE.md 也能用。[3]
软约束和硬规则的分界#
写文件之前先想清楚一件事:指令文件是建议,不是执行。Claude Code 官方文档明确说,CLAUDE.md 是作为上下文加载的,不是强制配置;要无条件阻止某个动作,得靠 PreToolUse hook 这类机制。[3] 这意味着”提交前跑测试”写在文件里,agent 大概率会执行;“绝不碰生产配置”写在文件里,也可能在上下文紧张时被忽略。分界线只有一条:这条规则失效一次的代价你能不能承受。能承受就留在文件里,让模型判断;不能承受,比如密钥外泄、生产数据被改,就从文件升级成 hook,把规则变成必然执行的代码。[4] 文件负责方向,hook 负责底线,两者各管一段。
规则会过期,文件要常修剪#
AGENTS.md 是活文档,更新它没有任何心理负担。[1] 规则冲突比没有规则更糟:两条互相矛盾的指令,模型可能任意选一条执行。[3] 每过几周过一遍文件,删掉 agent 已经内化的、合并互相矛盾的、把”每次都必须做”的事交给 hook 强制执行。文件里的每条规则都应该回答一个问题:这条规则现在还在救你吗?不救就删,agent 会感谢你的上下文窗口。
Sources#
[1] https://agents.md — AGENTS.md 开放格式官方说明 (Agentic AI Foundation) [2] https://github.blog/ai-and-ml/github-copilot/how-to-write-a-great-agents-md-lessons-from-over-2500-repositories — GitHub Blog: How to write a great agents.md [3] https://docs.anthropic.com/en/docs/claude-code/memory — Claude Code Docs: How Claude remembers your project [4] https://docs.anthropic.com/en/docs/claude-code/best-practices — Claude Code Docs: Best practices