如何写好 AGENTS.md
引子:AGENTS.md 是什么
在仓库根目录放一个 Markdown 文件,告诉 AI Coding Agent 这个项目是什么、怎么构建、有哪些规矩。这个做法现在有了一个事实标准的名字——AGENTS.md。
它的角色是:README.md 给人类读者看,AGENTS.md 给 AI 读者看。前者聚焦快速开始与贡献指南,后者聚焦构建命令、编码约束、验证闭环、踩坑清单,覆盖任何会影响 Agent 产出正确性的上下文。
这个概念最初由 Anthropic 的 Claude Code 以 CLAUDE.md 形式普及。随后各家工具一度各走各路:Cursor 用 .cursorrules,Copilot 用 .github/copilot-instructions.md,Gemini CLI 用 GEMINI.md,Cline 用 .clinerules,Sourcegraph AMP 提议 AGENT.md(单数),OpenAI Codex 提议 AGENTS.md(复数)。最终以 OpenAI 的 AGENTS.md 胜出——AMP 主动把 agent.md 域名重定向到 agents.md,Linux Foundation 下属的 Agentic AI Foundation 托管标准,Cursor、Kiro、灵码、Qoder、Copilot 等主流工具先后支持。到 2026 年初,GitHub 上已有超过 6 万个开源项目使用这个格式。Claude Code 仍然读 CLAUDE.md,但内容完全通用,一条软链就能兼容:ln -s AGENTS.md CLAUDE.md。
历史脉络和段落顺序不是 AGENTS.md 真正值得讨论的地方。真正值得讨论的问题只有一个:为什么一份几百行的 Markdown,能显著改变 AI Coding 的产出质量? 答案藏在一条设计原则里:地图,而非手册。
核心设计原则:地图,而非手册
OpenAI 在 Harness Engineering 实践中把 AGENTS.md 的第一原则命名为「Map, not Manual」。Anthropic 的官方博客在 Skill 设计中也重复了同一条原则:渐进式披露(progressive disclosure)。两家把不相容的工具做到相容点上,背后的机制是同一个:大模型的注意力是有限资源,上下文窗口越大,注意力被稀释得越严重。
一份 5000 行、事无巨细的 AGENTS.md,和一份 200 行、只标注导航的 AGENTS.md,对 Agent 的实际帮助往往是后者更大。前者让模型淹没在细节里,关键约束和普通说明被同等对待;后者只告诉模型「要做 X 就去看 Y 文档,要写 Controller 就去看 Z 目录」,模型按需跳转,注意力花在真正当前任务相关的那一小块。
这条原则推导出了一个判断标准:
这条标准把「该写什么」和「不该写什么」一刀切干净。分层架构的依赖方向、异常处理的强制约定、响应体由框架统一包装,违反就直接跑不通或留下隐患,必须进 AGENTS.md。某个 Service 内部的调用顺序、某个组件 prop 的推荐写法,错了可以改,属于详细文档的领域。
一组先行的场景
在展开具体实践之前,先看一组没有 AGENTS.md 时 AI Coding 的典型失败模式。它们解释了为什么 AGENTS.md 不是可有可无的装饰,而是工程化使用 AI Coding 工具的基础设施。
上下文割裂。前后端分属两个 Git 仓库时,AI 工具一次只能看到一半。改一个前后端联动的功能,比如后端新增接口、前端调用这个接口,需要在两个窗口之间来回切换。每次切换,模型就丢掉上一轮的上下文。
私域组件不可见。训练数据里没有的闭源组件(内部组件库、私有 SDK、商业框架),AI 既不认识也查不到文档。写出来的代码要么编译不过,要么 prop 传错,要么漏掉必要配置。
规矩活在人脑里。每个项目都有自己的潜规则:异常必须通过 BusinessException 抛出、响应体禁止手动构造、Controller 不得直接注入 Repository。这些规矩写在团队成员的默契里,不写下来 AI 就反复违反,每次纠正完下次还犯。
验证闭环断裂。AI 改完代码不知道怎么构建、怎么启动、怎么自测。本地环境配置、启动命令、验证方式散落在聊天记录和个人脚本里。AI 只能把代码改完就停下,剩下的人来接手。这意味着 Agent 无法夜间自主执行:连项目都启动不起来,谈不上自主闭环。
这四种失败模式背后是同一个根因:项目的知识与约束存在于人脑,不存在于 AI 能读到的地方。AGENTS.md 就是把这些隐性知识外化成可读文本的那个载体。
五类实践:让 AGENTS.md 真正起作用
AGENTS.md 自己一份是不够的,它需要周边基础设施配合。下面五类实践来自在多个真实项目(Spring Boot + React 的全栈管控系统、C++ 内核引擎、产品基线、文档系统)里收敛出的共同经验。
实践一:仓库聚合,消除上下文割裂
前后端分仓的项目,最直接的改造是把前端仓库放进后端的子目录下,或者进一步重构为 monorepo。两种方案的代价不同,收益方向一致:让 AI 在一个窗口里同时看到 Controller 定义和对应的前端调用。
脚本聚合是成本较低的折中:一个 setup-repos.sh 把前端仓库 clone 到 frontend/ 下,.gitignore 里把 frontend/ 屏蔽掉,不影响后端 CI/CD,不用 AI 工具的同事完全无感。monorepo 是更干净的选择:前后端代码、用户手册、参考项目、构建脚本、文档在同一棵目录树下。
1 | |
把用户手册也放进来有个副作用:AI 改完功能代码后可以顺手把对应的用户文档也更新掉。文档和代码在同一次 commit 里共进退,文档滞后问题自然消失。
实践二:环境配置归一,让 AI 能启动项目
AI 无法验证产出的根本障碍往往不在于 AI 不会验证,而在于验证所需的环境配置散落在每个人的 .bashrc、IDE JVM 参数、临时 export 里。AGENTS.md 只要无法指向一个明确的配置文件,Agent 就没法自主启动项目。
可行的约定是:所有本地环境变量统一写在 ~/.<project>_env,纯 KEY=VALUE 格式,启动脚本自动 source。放在 ~ 下而不是项目目录的理由是避免误提交到 Git。AGENTS.md 明确写清楚优先级:
1 | |
配套一键启动脚本:
1 | |
JDK 检测、优雅关闭旧进程、健康检查轮询这些细节被封装在脚本里,AGENTS.md 只暴露命令。Agent 的认知负担被压到最低:不需要理解 nvm、fnm、JAVA_HOME 的关系,只需要知道「要启动后端就跑这个脚本」。
实践三:验证闭环,改完代码不算完
验证闭环是 AGENTS.md 实践里最容易被低估的一环。它直接决定了 Agent 的产出是「看起来做完」还是「真的跑通了」。
后端的验证主力是 curl。一个可靠的 curl 验证规范有几条硬约束:每个 curl 独立执行,不串联;响应写到 /tmp/ 下的临时文件,后续用 python3 独立解析;token 获取模板化,登录写文件、提取、后续请求携带。这套啰嗦是有原因的。Agent 在 shell 里执行命令时容易踩到兼容性坑,例如 zsh 下管道加方括号 glob 会炸,curl | python3 -c "print(data['key'])" 直接报错。临时文件中转多一步,稳定性高一个量级。
1 | |
前端的验证则要靠 Agent Browser。curl 看不到页面渲染、交互、布局问题,调试前端疑难杂症时需要让 Agent 自己打开浏览器、操作页面、截屏对比(Qoder 的 agent-browser、Claude Code 接入的 computer use 都提供这个能力)。这比让 Agent 凭空猜 CSS 问题要可靠得多。
验证闭环的完整形态是:lint 和格式检查在每次代码变更后自动触发,启动脚本把应用真正拉起来,curl 或 Agent Browser 跑接口/页面验证,Spec 的 Design 文档里明确写入验证方案。最后这一点尤其关键,它告诉 Agent「写完代码不算完,自测过功能才算完」。这套端到端验证是夜间自主执行能跑通的前提。睡前设计好 Spec 提交给 Agent,第二天早上验收结果,是只有在闭环完整时才成立的工作模式。
实践四:自动化检查,给规则装上执行力
AGENTS.md 里写的规则,如果没有自动化检查,AI 和人都会违反。规则的优先级天然是:能自动化检查的 > 写在 AGENTS.md 中的 > 口头约定的。
典型例子是分层依赖检查。项目里定义严格的层级约束:
1 | |
光把这段贴进 AGENTS.md 是不够的。需要一个 shell 脚本扫描所有 Java 文件的 import 语句,按包路径判断层级,检测是否违反依赖方向。违规时输出的错误信息必须按 WHAT / WHY / HOW 三段式组织:
1 | |
这三段不只是给人看的,更是给 AI 看的。Agent 读到这条错误信息后可以直接按 HOW 的指引去修,不需要额外上下文。集成到 make lint-arch,一条命令完成检查。改完代码 Agent 自己跑一遍检查,形成「改 → 检 → 修」的闭环。
通过 Makefile 把质量检查命令收敛成统一入口:
1 | |
Agent 不需要记住每个检查命令的具体写法,AGENTS.md 只暴露 make lint-arch 和 make lint-format。
实践五:引入参考项目源码,替代永远滞后的文档
这一条是反直觉但效果最显著的一条。AI 不认识的东西——闭源私域组件、内部网关内核、公有云项目、竞品架构——靠写使用文档补上,成本高、覆盖不全、还总是滞后于实现。换一个思路:不写文档,直接把源码引进来。
1 | |
每个参考项目通过 git submodule 引入,配合 ignore = all 避免影响 CI/CD。本地按需拉取:
1 | |
源码永远不会过时,它本身就是最准确的文档。 AI 不会写私域组件时,直接读源码里的 TypeScript 定义和实现;要对接网关内核时,直接查看路由和插件的实际代码。代价是仓库体积变大和 submodule 的管理负担,换来的是 Agent 写代码的准确性。对于训练数据中不存在的内部项目,这个交易划算。
仅有源码还不够。每个参考项目配一份架构说明文档(docs/design-docs/ref-*.md),作为参考项目的地图:
| 文档 | 说明 |
|---|---|
ref-higress.md |
网关内核:路由模型、插件机制、CRD 结构 |
ref-nacos.md |
Nacos:配置中心对接、服务发现集成 |
ref-teamix-pro.md |
Teamix Pro:ProTable/ProForm 使用模式、TS 类型速查 |
ref-apigo.md |
公有云后端:目录结构、分层架构、核心模块 |
ref-apigw.md |
公有云前端:页面结构、组件体系、路由设计 |
ref-himarket.md |
HiMarket:多模块结构、领域模型 |
ref 文档告诉 Agent「这个参考项目的整体结构和关键模块在哪」,reference-projects 提供细节。这些 ref 文档本身也可以由 AI 基于参考项目源码生成,又一个「代码生成文档」的闭环。
引入这么多参考仓库会不会让 Agent 无所适从?实测下来不会。AGENTS.md 的项目结构树标注了每个目录的用途,ref 文档提供架构概览,参考优先级规则明确「什么时候该看哪个项目」。现在的大模型知道什么时候该去参考项目里翻实现,什么时候该在本项目里改动,不会因为仓库里多了几个参考项目就迷失方向。
AGENTS.md 的骨架
把上面五类实践沉淀成一份 AGENTS.md,大致的章节结构是这样的:
1 | |
控制在 200 行以内。超过这个范围说明有细节该拆到 docs/ 下的专题文档里。
怎么开始写
从零写一份 AGENTS.md 的门槛比想象中低。
第一种起步方式:大多数 AI Coding 工具提供 /init 或等价命令(Claude Code 的 /init、Qoder 的 qoder init),扫描项目结构生成初始版本。自动生成的版本覆盖项目概述和基本构建命令,作为骨架够用。
第二种起步方式:用更完整的 Skill 起步。Qoder 社区开源的 harness-creator 会一并生成 AGENTS.md、分层架构约束的 lint 脚本、Makefile、验证脚本、参考文档,相当于把本文提到的实践打包成一键产出。
起步之后的迭代是 bad case 驱动 的:
- 某次 AI 用了错误的命名风格 → 思考「如果 AGENTS.md 里多一条 XX 规则,是不是就不会犯」→ 补一条
- 某次 AI 在错误的层级引入了依赖 → 是全局规则,加到 AGENTS.md;或者补一个 lint 脚本自动拦
- 某次 AI 在某个模块用错了某个 prop → 是模块细节,补到对应的
docs/文档里
判断改哪里的标准始终是一条:全局规则进 AGENTS.md,模块细节进 docs。如果所有细节规则都往 AGENTS.md 里怼,上下文会膨胀到重要规则被淹没。
谁来读这些文件
推广 AGENTS.md 时,明确标注每个文件的读者有助于降低团队的理解成本:
| 文件 | 读者 | 说明 |
|---|---|---|
README.md |
人 | 项目介绍、快速开始,人类入口 |
AGENTS.md |
AI 为主,人可浏览 | AI 工具自动读取的项目指令 |
docs/*.md |
AI 为主,人可参考 | 各模块的开发手册 |
scripts/*.sh |
人和 AI 共用 | 构建、启动、部署脚本 |
setup-repos.sh |
人执行 | 一键环境搭建 |
README 和 AGENTS.md 是互补的。README 聚焦快速开始和贡献指南,AGENTS.md 聚焦构建命令、编码规范、验证流程。内容可能有少量重叠(比如项目概述),侧重点不同,不需要合并。脚本是人和 AI 共用的部分,因此脚本本身的可读性和健壮性格外重要,其中的每一行注释都可能成为 Agent 决策的依据。
为什么是 AGENTS.md
工具不统一的现状下,AGENTS.md 作为核心入口的价值来自几个方面:
- 足够通用:被大多数主流工具识别,一份文件覆盖多数场景
- 零配置成本:工具打开项目自动读取,不需要安装插件或配置 hook
- 维护负担低:不用为每种工具维护一份规则文件
- 兼容性好:不识别 AGENTS.md 的 Claude Code 可以通过
ln -s AGENTS.md CLAUDE.md接入
和特定工具绑定的 rules、hook、Skill 作为补充,核心规则全部收敛到 AGENTS.md 一个入口。换工具时迁移成本趋近于零。
作为知识沉淀的副作用
AGENTS.md 的初衷是给 AI 看,它的维护过程本身是一次团队知识梳理。过去散落在 Wiki、聊天记录、口头约定里的编码规约,现在被结构化地写进了一份 Markdown。新人入职读完 AGENTS.md,就能拿到过去需要摸索很久的「潜规则」。给 AI 写 AGENTS.md 的过程,客观上也是给人写了一份项目使用手册。
这和 Code as Documentation 的思路一脉相承:隐性知识外化成可执行、可校验的文本,才能跨越时间和人员传承。AGENTS.md 加上 lint 脚本、启动脚本、验证规范,本质是在构建一个反馈回路:Agent 读 AGENTS.md 理解项目,写代码,自动检查,启动验证,根据结果修正。人类的角色从回路中的每一步执行者,变成回路本身的设计者。




