最近我经常在技术群里看到同一个问题为什么 AI 编程工具在别人手里又快又稳到自己项目里就频频翻车很多人的第一反应是“模型不行”但等你换了好几个模型之后就会发现问题往往出在它根本不了解你的项目。编译命令是什么、测试怎么跑、代码风格怎么约定、哪个目录绝对不能碰——这些信息你心里清楚AI 完全不清楚。每个会话它都像第一天入职的实习生而且还没有人给它做入职培训。AGENTS.md 就是为这种情况准备的一份放在仓库根目录、专门写给 AI 编码代理看的项目说明书。这篇文章不讲概念直接讲怎么把一份 AGENTS.md 写得有用、可控、省 token。如果你正在用 Claude Code、Codex、Cursor 这类工具或者打算在团队里推广 Agent 辅助开发这份参考应该能帮你少走不少弯路。1. 先搞清楚 AGENTS.md 到底解决什么问题1.1 README 为什么管不住 AI 编码助手很多项目有 README而且写得非常详细。但只要你拿同样的 README 去问 AI“这个项目怎么跑起来”它大概率还是会给出一份通用答案。原因很简单README 的读者是人类。人类看 README 需要的是项目亮点、安装方式、使用截图、贡献指南。AI 干活需要的是另一类信息构建命令、测试入口、代码风格、目录职责、禁止事项。这两种信息在目标和颗粒度上完全不同。README 里常写“本项目使用 FastAPI 构建提供高效的 REST API”AI 真正想知道的是“路由文件应该放在 app/routers/ 下新接口必须写 Pydantic schema”。更关键的是 token 消耗。AI 编码工具每次会话都要把关键文档加载进上下文一份面向人类的 README 动辄几千字有效信息密度却很低。把完整 README 喂给 AI浪费上下文窗口还会让它把注意力放在无关的功能介绍上。AGENTS.md 在这个背景下出现的逻辑就很顺了它是一份“给程序读的说明书”用最精简的文字、最明确的指令把人类在做 code review 时才会告诉新人的那些约定提前写给 AI 看。它不替代 README而是和 README 分工一个负责给人看一个负责给 AI 看。1.2 各家 AI 工具对 AGENTS.md 的共识AGENTS.md 这个命名其实还没有一个官方标准委员会来背书但社区和工具厂商已经逐步形成默契。Claude Code 默认读取项目根目录里的 AGENTS.md 和 CLAUDE.mdCodex 也支持 AGENTS.md 和 .agents.mdCursor 在较新的版本中也开始识别这类规则文件Gemini CLI 同样有对应的指令文件机制。这带来一个重要结论与其只依赖某一款工具私有的规则文件写一份通用的 AGENTS.md 放在根目录是收益最大、兼容性最好的做法。就算你的主力工具不支持自动加载你也能把 AGENTS.md 的核心内容复制到工具专用的规则文件里或者直接粘贴进自定义指令。子目录的处理也值得注意。部分工具支持在子目录放AGENTS.md负责该目录内的局部规则。实测下来我的建议是根目录文件管全局子目录文件只在“这个目录真的有很多独立约定”时才写否则文件一多AI 反而会混淆优先级。1.3 什么项目最需要 AGENTS.md不是所有项目都需要马上写 AGENTS.md。我个人的判断标准是这样的项目会长期维护新增代码的频率高值得花半小时沉淀规则你要经常用 AI 改代码而且对质量有要求不能接受“能跑就行”项目有清晰的架构约束不写下来 AI 就会破坏团队里有多人协作新人和 AI 都需要同一套“共同记忆”反过来如果只是一个一次性脚本、demo、或者纯模板项目写不写 AGENTS.md 都无所谓花那时间不如直接改代码。从我接触过的真实案例看最容易感知到 AGENTS.md 价值的是两类人一类是重度使用 AI 编程工具的独立开发者另一类是团队里负责维护核心库、经常被 AI 改动搞坏的资深工程师。前者的痛点是效率后者的痛点是秩序。2. 动笔之前先盘清这三件事很多人的 AGENTS.md 写不好不是因为文笔而是因为根本没想清楚。拿起模板就填填出来自然是四不像。我建议动笔前先做三件事。2.1 盘点项目的事实信息先把自己当成第一天入职的实习生在项目里走一圈。把以下信息收集齐项目用什么语言和框架入口文件在哪里怎么安装依赖、怎么跑本地开发环境怎么跑测试测试目录结构和命名规律是什么有没有 lint 和格式化工具配置文件是什么目录结构大致如何划分每个顶层目录负责什么有没有自动生成的文件、二进制文件、密钥文件哪些不能动收集这些信息最快的方式是看几个关键文件package.json、Makefile、pyproject.toml、docker-compose.yml、go.mod、requirements.txt以及已有的 CI 配置。CI 配置尤其重要因为里面写的命令往往就是“官方验证过的正确命令”直接用不会错。有一个小技巧先用一句话向另一个工程师介绍你的项目。写不出来的部分就是你还没想清楚的部分也是 AI 大概率会被卡住的部分。2.2 明确你希望 AI 做什么、不做什么这个步骤最容易被跳过但恰恰决定了 AGENTS.md 的质量。你可以按两类列出清单高频任务改 bug、加接口、写测试、补注释、重构小模块高风险动作改数据库 schema、升级依赖、动核心业务逻辑、重命名公共 API高频任务要在 AGENTS.md 里给出明确的执行路径高风险动作要明确写清楚“必须先征求人同意”或“需要额外写迁移脚本”。AI 本质上是个“过度配合”的执行者你划的线越清楚它就越不会越界。我建议给动作分三个等级可以直接做、需要先说明再同步做、绝对禁止。少用模糊的“根据项目情况自行决定”因为 AI 的“项目情况”和你脑子里的版本经常不是同一个。2.3 控制篇幅和指令强度一份 AGENTS.md 通常控制在 500 到 1000 词比较合理。太长会挤占上下文太短则覆盖不了关键约定。如果项目确实复杂宁可在 AGENTS.md 里写“完整架构见 docs/architecture.md修改核心模块前必须阅读”也不要事无巨细全塞进来。指令词的选择也讲究层级。用“必须”“禁止”表示硬约束用“优先”“推荐”表示倾向用“可以”“允许”表示授权。同一个文件里如果所有指令都是“必须”AI 无法区分轻重等于没有优先级。注意AGENTS.md 不是写给搜索引擎看的是写给执行者看的。写得像一篇散文没有意义每一行都应该能被 AI 翻译成具体动作。3. AGENTS.md 的核心结构六大板块逐个拆解结构没有绝对标准但我拆过几十个项目的 AGENTS.md 之后发现好用的文件几乎都包含下面六个板块。按顺序写下来逻辑自然。3.1 项目概览三句话讲清项目全貌这个板块的目的是让 AI 在读完三行字之后就知道“我在一个什么项目里”。不用写愿景不用写技术亮点写事实。## 项目概览 一个订单履约后端服务使用 Go 编写HTTP 框架用 Gin数据库用 PostgreSQL通过 Redis 做缓存。代码分成 cmd、internal、pkg 三层cmd 放入口internal 放业务代码pkg 放可复用的通用工具。对外接口遵循 REST 风格统一返回 JSON。注意几个要点第一句说清楚“这是个什么系统”第二句说清技术栈和分层第三句说清“别人看代码时最先要知道的约束”。如果在三句话内做不到说明你对项目的概括能力还需要练。不要在这个板块写“本项目致力于打造极致用户体验”这种话。AI 不需要被感动它需要知道“路由注册在哪个文件”。3.2 命令速查给 AI 一张快捷键表AI 干活时经常需要跑命令但猜测命令会浪费它的大量动作和你的时间。把常用命令列成清单是最能立刻提升体验的部分。## 常用命令 - 安装依赖pnpm install - 启动开发环境pnpm dev默认端口 3000环境变量见 .env.example - 运行全部测试pnpm test - 运行单个测试pnpm vitest src/utils/abc.test.ts - 类型检查pnpm typecheck - Lintpnpm lint --fix - 构建pnpm build命令清单还有一个隐藏用途它能间接告诉 AI“我默认你使用什么工具链”。比如你在命令里写pnpm而不是npmAI 就会知道这个项目用的是 pnpm不会自作主张换包管理器。我踩过的一个坑是只写命令不写结果预期。AI 跑完测试后不知道“通过”是什么样子。建议在命令后面补一句“全部通过时输出 x tests passed”这样 AI 就能自我判断是否成功。3.3 代码风格与约定把潜规则变成显性规则每个项目都有一些“代码规范里写不清但 review 时会抓狂”的潜规则。比如字符串永远用单引号、接口返回必须包一层{ code: 0, data: ... }、错误处理必须用自定义错误类型、导入顺序必须是“内置→第三方→本地”。AI 默认不会知道这些所以你要把最重要的几条写下来。不要事无巨细地去复述 ESLint 配置只写那些“工具没办法自动检查”的约定。## 代码风格 - TypeScript 代码统一使用严格模式禁止使用 any - 业务逻辑禁止写在 Controller 层必须抽到 Service 层 - 错误处理统一使用 AppError禁止直接 throw new Error - 新增接口必须携带 JSDoc 注释标明作者和用途 - 提交信息遵循 Conventional Commitsfeat/fix/refactor/docs这里我有一个建议每写一条约定自己先问一句“如果 AI 不遵守代码 review 时会打起来吗”如果不会打起来就先不写。AGENTS.md 的每一行都应该有存在的必要性。3.4 架构边界与关键模块AI 改代码最容易犯的错就是在一个“看起来应该在这”的地方写了不该写的代码。它不清楚模块间的依赖关系所以你需要把最重要的一两条架构边界说清楚。## 架构边界 - DAL数据访问层只负责 SQL 和数据映射禁止包含业务逻辑 - Service 层可以调用 DAL 和其他 Service禁止反向依赖 Controller - 跨模块调用统一走 Service 接口禁止直接访问其他模块的 Repository - 新增依赖前必须先确认禁止为一个小功能引入完整框架这段话的价值在于AI 拿到需求之后会先做“选址”。如果你告诉它 Service 层禁止反向依赖 Controller它就大概率不会在 Service 里importController 的代码。架构板块不用写完整设计文档只写“最容易踩的那条红线”。写得太多AI 会抓不住重点反而更容易触犯风险最高的那一条。3.5 约束与红线给 AI 划物理围栏红线是 AGENTS.md 里最有含金量的部分。人类的隐形约束要变成 AI 的显式禁令。## 约束与红线 - 禁止修改 migrations/ 目录下已执行的数据库迁移文件 - 禁止直接编辑 dist/、build/ 等构建产物目录 - 禁止将 secrets、token、密钥硬编码到代码中 - 禁止为了通过类型检查而使用 ts-ignore 或 any 绕过 - 修改公共 API 签名前必须同步更新调用方并跑全量测试写红线时可以用“为什么”加一句解释。比如“禁止修改已执行的迁移文件因为会导致生产环境数据不一致”。AI 理解原因之后更可能在自己的推理链条中主动遵守而不是只在看到那一行时才想起。不过要留意红线数量控制在 5 到 8 条以内。每增加一条都会分散 AI 对前面红线的注意力。如果红线超过 10 条说明你的安全感太差要么是重构的时候到了要么是你应该考虑给 AI 搭配人肉 review。3.6 工作流规则让 AI 按流程干活最后一块是“AI 改代码的步骤规范”。你可以告诉它完成一个任务时的操作顺序这能明显改善输出质量。## 工作流 1. 先阅读相关模块的现有代码理解现状后再动手 2. 修改完成后先跑 typecheck 和 lint再跑受影响模块的测试 3. 全量测试通过后使用 Conventional Commits 格式提交 4. 提交信息里附上变更范围和影响说明工作流规则的价值在于把“完成后自我检查”这一步制度化。实测中AI 完成代码后如果直接交差经常会出现类型错误、lint 报错、测试失败但如果你在 AGENTS.md 里写明步骤它为了满足流程就会主动执行验证。注意流程不要过长。顶级 AI 编码代理的上下文窗口虽然不小但每多一个步骤它的“自主性”就会被多束缚一层。四个以内的步骤最舒服。4. 从零写一份 AGENTS.md一个 FastAPI 项目实录前面说的是理论现在我拿出一个实际项目举个例子。这是我常用的一个内部工具项目技术栈是 FastAPI PostgreSQL SQLAlchemy代码量不大但对数据准确性要求很高。4.1 前期摸底我到底要写什么我打开项目后先做了三件事第一看pyproject.toml。发现项目用 Poetry 管理依赖工具链里有ruff、mypy、pytest。于是命令速查板块基本确定poetry install、poetry run uvicorn app.main:app --reload、poetry run pytest、poetry run ruff check .。第二看目录结构。项目分四块app/routers放 API 路由app/services放业务逻辑app/repositories放数据库访问app/schemas放 Pydantic 校验模型。架构边界就很清楚了路由不能写业务业务不能直接写 SQL。第三看 git 提交历史。我发现团队约定提交信息都用feat(scope): 描述格式而且习惯在 schema 变更后面附迁移说明。这些信息 README 里没有但 AGENTS.md 里必须写。4.2 第一版 AGENTS.md 全文摸底完成之后我写出的第一版文件长这样# AGENTS.md ## 项目概览 一个数据处理 API 服务使用 FastAPI 框架提供数据导入、查询、导出能力。代码分成 routers、services、repositories、schemas 四层禁止跨层直接访问。数据库使用 PostgreSQLORM 用 SQLAlchemy所有查询必须走 Repository 层。 ## 常用命令 - 安装依赖poetry install - 本地启动poetry run uvicorn app.main:app --reload默认端口 8000 - 运行全部测试poetry run pytest - 运行单个测试poetry run pytest tests/test_import.py::test_csv_import - 代码检查poetry run ruff check . - 类型检查poetry run mypy app ## 代码风格 - 路由文件只做参数解析和响应返回禁止写业务逻辑 - Service 层命名用动词短语如 import_data、export_report - Schema 统一使用 Pydantic v2 风格from_attributesTrue - 所有数据库查询使用 SQLAlchemy 的 TextClause 或 ORM禁止拼原生 SQL 字符串 - 新增字段时同步编写 Alembic 迁移脚本 ## 架构边界 - routers → services → repositories依赖方向只允许从上往下 - repositories 禁止向上层返回 ORM 实体统一返回 Pydantic 模型 - services 之间可以互相调用但禁止循环依赖 - 新增对外接口时必须附带 Pydantic 请求/响应模型禁止直接返回 dict ## 约束与红线 - 禁止修改 migrations 目录下已执行的迁移文件 - 禁止在代码中硬编码数据库连接信息和任何密钥 - 禁止通过 # type: ignore 绕过 mypy 检查 - 所有数据导入逻辑必须经过事务处理失败时回滚 ## 工作流 1. 修改前先阅读目标模块和相邻模块的代码理解现有抽象 2. 修改完成后按顺序执行 ruff、mypy、pytest 3. 全量测试通过后使用 Conventional Commits 格式提交 4. 提交信息末尾注明影响的 API 范围如 feat(import): 支持 CSV 批量导入写完后我自己看了一下600 词左右信息密度很高没有任何一句废话。这份文件里每一行都能被 AI 直接翻译成动作而不是“参考话术”。4.3 实测反馈和迭代第一版投入使用后AI 的行为有了明显变化。最直观的感受是之前让它加一个分页参数它会在routers里写 SQL 查询之后它会规规矩矩地去找repositories层还知道在schemas里加一个分页响应模型。但实测也发现了一个问题我写了“所有数据库查询使用 TextClause 或 ORM禁止拼原生 SQL”可 AI 时不时会把一个灵活查询写成text(SELECT * FROM ... WHERE id :id)。它的确没有“拼原生 SQL”但这种方式在项目里其实并不受欢迎。于是我在下一版里把它改成了更精确的表述- 数据库查询优先使用 SQLAlchemy ORM 的 select() 构造方式TextClause 仅限动态排序等 ORM 难以覆盖的场景指令越精确AI 的发挥空间越受控。这是一份好 AGENTS.md 的常态写完只是开始要在实际使用中不断校准。5. 常见问题与排查技巧实录任何规则文件都会遇到“写了没用”的情况。这些年我见过和踩过的问题基本集中在下面几类。我尽量把症状和解法都说清楚。5.1 文件太长AI 反而变笨了症状加了 AGENTS.md 之后AI 的反应变慢而且开始出现莫名其妙的错误——明明不需要动的地方它也去动。原因文件太长挤占了上下文窗口AI 的注意力被稀释。尤其是那种“把 OpenAI/Anthropic 的官方提示词模板整段抄进来”的文件看起来全面实际是灾难。解法把 AGENTS.md 压缩到重点。我通常采用“两层结构”根目录的 AGENTS.md 只写全局事实和红线更细的模块约定放在子目录的 AGENTS.md 或docs/里通过链接引用。让 AI 只在需要时才读取细节而不是一开始就被海量规则淹没。5.2 指令写得模棱两可症状你写“代码风格保持简洁”AI 交回来的代码依然冗长。你写“遵循项目现有架构”AI 照旧乱放文件。原因这两句话缺乏可执行性。什么问题算简洁什么样的架构算“现有架构”AI 只能靠猜。解法把模糊词换成可检验条件。“保持简洁”换成“单函数不超过 50 行超过则拆成多个私有函数”“遵循现有架构”换成“新增代码必须放到 app/services 下禁止在 routers 里写业务逻辑”。5.3 用了模板却没效果症状从网上找了一份看起来很专业的 AGENTS.md 模板填完却发现 AI 依然我行我素。原因模板帮你搭了框架但没帮你思考。很多模板强调的是“角色设定”“做事原则”这些内容相对空泛AI 顶多是在口头上演得更像了实际动作没有变化。解法把模板里的“原则”全部改成“动作”。“遇到冲突先沟通”改成“修改前先列出改动文件清单”“注重代码质量”改成“提交前必须跑 lint 和全量测试”。5.4 文件长期不更新症状项目代码已经改了架构AGENTS.md 还写着老目录结构。AI 照着旧约定写代码结果代码风格和实际项目完全脱节。原因AGENTS.md 没有负责人也没有 review 机制。它和 README 一样属于“文档债”。解法把 AGENTS.md 的更新绑定到代码变更的关键节点。比如架构调整、依赖升级、工具链切换时强制同步修改这一份文件。我在团队里一般让每次重构的 PR 里附带更新 AGENTS.md 的改动否则 review 不通过。5.5 常见问题速查表我把最容易出现的几个问题整理成了表格方便你对照排查。症状更可能的原因处理方式AI 频繁问重复问题AGENTS.md 没有覆盖高频任务信息补充命令速查和高频约定文件太长导致反应慢内容过度冗余精简到 500~1000 词拆分细节到子文档AI 不遵守红线表述过于抽象无法执行把“禁止随意修改”改成“禁止修改某目录下已执行的文件”改动方向正确但风格不对缺少代码风格清单补充格式化工具、命名规则、提交信息格式每次会话仍然像失忆工具没有自动加载根目录文件检查工具配置或把 AGENTS.md 核心内容复制到专用规则文件6. 我长期维护 AGENTS.md 的几个习惯最后分享几个我在实际维护过程中觉得最有用的习惯没有章法想到哪写到哪。第一个习惯是“用 git log 当参考书”。写“代码风格”和“架构边界”的时候与其凭记忆不如直接翻最近 20 条提交记录看看团队实际是怎么写代码、怎么起名字的。AI 会学习你写的规则而你的规则应该来自真实历史而不是理想假设。第二个习惯是“每次 AI 表现不好的时候先去查 AGENTS.md”。这句话听起来像是给自己的失败找借口但实际情况确实如此。AI 发生行为偏差大概率不是模型变笨了而是项目里多了一些它不知道的约束。把这次偏差写进 AGENTS.md下一次它就能避开同样的坑。第三个习惯是“把 AGENTS.md 当成 code review 的一部分”。我会在 CI 或 PR 描述模板里加一个检查项如果本次改动涉及架构、命令、代码风格或约束请同步更新 AGENTS.md。这样文件就不会烂尾也不会变成一纸空文。第四个习惯是“定期重读并删减”。每过一两个月我会重新看一遍这份文件删掉那些已经通过工具配置、模板代码自动满足的条目。AGENTS.md 的重点永远是那些“软件工具管不了、只能靠人约定”的部分保持精简它才有力量。如果你现在正准备写第一份 AGENTS.md我建议不要追求一步到位。先把命令、红线、工作流三块写出来用一周再根据 AI 的实际表现去补代码风格和架构边界。写规则文件这件事边用边改远比一次性写完更能贴合你项目的真实需求。