写好 AGENTS.md,本质上是在给编码模型升级

本文结合一项针对 AGENTS.md 的实证研究,讲清楚什么样的代理文档能提升代码生成质量、什么内容会误导模型,以及如何把现有 README 和架构文档改造成真正对 AI 编码代理有用的上下文。

阅读时长: 15 分钟
共 7458字
作者: eimoon.com

写好 AGENTS.md,本质上是在给编码模型升级

很多团队开始给代码仓库补 AGENTS.md,希望 AI 编码代理更懂项目约束、更会复用已有模式。直觉没错,但结果并不稳定。

Augment 对自家 monorepo 中几十份 AGENTS.md 做了系统评估,结论很直接:好的 AGENTS.md,效果接近把模型能力提升一个档位;差的 AGENTS.md,表现甚至比完全没有文档更差。

这件事值得认真看待,因为它揭示了一个很容易被忽略的问题:影响编码代理表现的,并不只是模型本身,还包括你给它组织上下文的方式。

本文会把这项研究的核心发现拆开讲清楚:

  • 哪些 AGENTS.md 写法真的有效
  • 哪些内容会把代理带偏
  • 为什么同一份文档会在不同任务上产生相反效果
  • 已有 README、架构文档和设计说明,应该怎么迁移成对代理友好的文档体系

同一份 AGENTS.md,可能帮你提分,也可能让任务完成度下降 30%

先看这项研究里最有意思的发现:AGENTS.md 不是“有了就好”,它的效果高度依赖任务类型。

研究中,同一份 AGENTS.md 在一个常规 bug 修复任务上,把 best_practices 指标提升了 25%;可在同一模块里的复杂功能开发任务上,却让 completeness 下降了 30%。

原因不难理解。

在 bug 修复场景里,这份文档里有一个决策表,用来指导代理在两种相似的数据获取方式之间做选择。代理很快就能锁定正确模式,代码风格也能贴合现有约定。

但到了复杂功能任务里,情况变了。代理读到同一份文档后,被引用区和规则区牵着走,开始打开大量 Markdown 文档,试图逐条核对规范,结果引入了多余抽象,消耗了上下文窗口,最终方案还没做完整。

这说明一个关键事实:

AGENTS.md 不是静态说明书,而是在参与代理的推理路径。 文档里的不同部分,会直接改变代理“先看什么、怎么判断、什么时候开始写代码”。

所以,评价一份 AGENTS.md 不能只问“写得全不全”,而要问:

  • 它是否帮助代理更快做出正确决策
  • 它是否减少了无意义探索
  • 它是否把注意力放在与当前代码邻近、与当前任务相关的信息上

他们是怎么测的

Augment 使用的是内部评测套件 AuggieBench。方法不复杂,但很扎实。

他们从大型代码仓库里挑选高质量 PR,这些 PR 代表了真实的日常开发任务。然后:

  1. 还原任务环境和提示词
  2. 让代理执行相同任务
  3. 把输出和“黄金 PR”做对比

这里的黄金 PR,不是随便选的参考实现,而是已经经过多位资深工程师审阅并最终合入的版本。

为了更准确地评估 AGENTS.md 的作用,这项研究又加了两个筛选条件:

  • PR 必须基本落在单个模块或单个应用内
  • 任务必须是那种理论上能从 AGENTS.md 中获得帮助的类型

然后每个任务运行两次:

  • 一次带 AGENTS.md
  • 一次不带 AGENTS.md

最后比较两组分数差异。

这种设计有个好处:它测到的不是“模型喜欢不喜欢文档”,而是文档是否在真实编码任务里创造了净收益

真正有效的 AGENTS.md,通常有这 7 个特征

1. 渐进式披露,优于把所有东西堆进一个文件

研究里表现最好的 AGENTS.md,通常都不长,主文件大约在 100 到 150 行,外加少量范围明确的引用文档。

这种写法背后的思路很像 API 设计:主入口只给出高频路径和关键规则,细节按需展开。

为什么有效?

因为代理不是人在浏览网页,它读取文档是有代价的。主文件写得太长,代理就更容易:

  • 被低相关信息分散注意力
  • 把本来简单的任务做成“全面调研”
  • 在引用文档之间来回跳转,浪费上下文预算

研究中,这种“短主文档 + 少量聚焦引用”的结构,在大约 100 个核心文件规模的中型模块里,能稳定带来 10% 到 15% 的整体提升。一旦主文件继续膨胀,收益就开始反转。

一个实用判断标准是:

  • 主文档负责告诉代理“常见任务该怎么做”
  • 引用文档负责告诉代理“遇到某类特殊情况去哪里看”

如果主文档已经开始承担“百科全书”职能,通常就写过头了。

2. 流程化步骤,对代理帮助非常大

把任务描述成编号清晰的多步骤流程,是研究里最强的模式之一。

对人类开发者来说,“部署一个新集成”也许已经很熟;对代理来说,这种任务往往会漏接线、漏配置、漏注册。流程文档刚好能弥补这个短板。

研究里的一个例子是六步集成部署流程。代理按步骤执行后:

  • 缺少 wiring 文件的 PR 比例,从 40% 降到 10%
  • correctness 提升 25%
  • completeness 提升 20%
  • 平均完成速度也更快

这类内容适合写进 AGENTS.md 的前提是:流程本身是稳定的、可以操作的。

有效的流程通常具备这几个特点:

  1. 步骤顺序明确
  2. 每一步都有可验证产物
  3. 关键分支点有说明
  4. 不夹杂大段原理解释

代理最怕的是“看起来像流程,实际上是经验散文”。它需要的是操作指令,不是心得体会。

3. 决策表能在写代码前解决歧义

很多代码库都有这种问题:同一类需求,存在两三种都“看起来合理”的实现方式。

对人来说,这叫经验判断;对代理来说,这就是高风险歧义源。

决策表之所以有效,是因为它把“模糊偏好”改写成“显式路由规则”。例如状态管理到底选 React Query 还是 Zustand,可以用类似下面的规则收敛:

判断问题 选 React Query 选 Zustand
服务端是否是唯一数据源
是否有多条代码路径会修改状态
是否需要把乐观更新和本地状态混合处理

这种结构的价值不在于“讲清知识点”,而在于提前消除选择空间。代理不用先写一版再修,而是在下手前就被约束到正确轨道里。

研究里,这类文档让相关 PR 的 best_practices 提升了 25%。

如果你的项目里存在这些情况,就非常适合引入决策表:

  • 多个库并存,职责边界接近
  • 新老模式混用,迁移未完成
  • 某类问题历史上经常选错方案
  • 审查意见总在重复解释“这里应该用 A,不该用 B”

4. 少量真实代码示例,能显著提高复用率

研究发现,3 到 10 行的真实生产代码片段,比抽象原则更能帮助代理复用现有模式。

这个结论很符合编码代理的工作方式。代理并不缺“知道 Redux Toolkit 是什么”这样的知识,它缺的是“在你们代码库里,正确写法长什么样”。

例如提供几段现成模板:

  • 带类型初始状态的 createSlice
  • 带标准错误处理的 createAsyncThunk
  • 正确类型约束的 useAppSelector

代理就更容易沿用现有套路,而不是自己发明一套状态管理写法。

研究里,这类示例让 code_reuse 提升了 20%。

但这里有个边界:示例越多,不代表越好。 示例一旦过量,代理会错误模式匹配,学到不该学的细节。最好的做法是保留少量、最典型、最贴近当前模块的代码片段。

5. 领域规则仍然重要,但必须具体

很多人想到 AGENTS.md,第一反应就是“写规则”。这没有问题,问题在于规则常常写得太泛。

真正有效的是这种规则:

  • 所有金融计算必须使用 Decimal,禁止使用 float
  • 新增 HTTP 客户端必须走共享 apiClient
  • 涉及幂等写操作时必须包含请求去重键

这类规则有几个共同点:

  • 与业务或系统风险直接相关
  • 适用范围清楚
  • 是否遵守可以验证
  • 与任务一旦相关,价值立刻显现

研究里,这类规则在任务直接相关时,确实能明显改善 best_practices

但如果你把几十条异质规则塞进一个主文件里,问题就来了:代理会把每条规则都当成待核验条件,开始大范围搜索和自我审查,反而拖慢任务。

规则不是越多越安全。规则越多,越需要分层。

6. 每个“不要”,都应该配一个“应该怎么做”

这是一个很实用、也很容易被忽视的写法原则。

单独写“不要这样做”,对代理的效果往往不好。因为它会进入一种谨慎但低效的状态:先判断禁令是否适用,再搜索替代方案,再验证有没有触犯别的禁令。

例如:

  • 不要直接实例化 HTTP 客户端

这句话本身只会增加不确定性。更好的写法是:

  • 不要直接实例化 HTTP 客户端
  • 使用 lib/http 中共享的 apiClient,并启用重试中间件

后者给了代理完整动作闭环:避开什么、采用什么、去哪里拿。

研究里,那些包含 15 条以上连续“不要做什么”但缺少对应“应该怎么做”的 AGENTS.md,常常会诱发过度探索,代理更保守,实际完成的工作更少。

7. 文档的模块边界,最好和代码边界一致

研究里表现最好的 AGENTS.md,往往对应相对独立的子模块,而不是放在仓库根目录、面向全局的大而全文档。

效果最好的典型环境是:

  • 中等规模模块
  • 约 100 个核心文件
  • 一份 100 到 150 行的 AGENTS.md
  • 少量配套引用文档

例如客户端 UI 组件区、一个独立服务模块,通常都适合这种组织方式。

相反,放在仓库根目录、覆盖多个横切领域的大型 AGENTS.md,表现明显更差。更重要的是,文档入口本身不是全部,周围的文档环境同样决定结果。

研究里最差的一些案例,不是因为 AGENTS.md 本身特别糟,而是因为它周围堆满了文档:

  • 一个模块有 37 份相关文档,总计约 50 万字符
  • 另一个模块有 226 份文档,总计超过 200 万字符

在这种环境里,即便移除 AGENTS.md,代理行为也几乎不变,因为它仍然会被海量周边文档吸进去。

这点很重要:如果模块附近有一大片规格说明、架构设计和历史文档,代理读到的常常是那片文档森林,而不是你精心打磨的入口文件。

AGENTS.md 最常见的失败方式

失败一:过度探索,文档把代理拖进“上下文腐化”

作者把这个问题称为 overexploration,本质上就是上下文被无关信息稀释。

架构总览写太多

很多团队喜欢在 AGENTS.md 里放完整架构说明:事件总线、消息队列、网关路由、中间件层、设计取舍理由,一个不落。

对人类读者,这可能是“系统全貌”。 对代理来说,这常常是误导。

研究里的例子很典型:任务只是一个两行配置修改,但文档里写了完整服务拓扑和架构决策背景。代理为了“理解架构”,先后读了 12 份文档,加载了约 8 万 token 的无关上下文,最后连配置归属的服务都判断错了,提交的修复也不完整,completeness 下降了 25%。

问题不在于架构信息不重要,而在于放错了层级。

更合理的做法是:

  • 主文件只写清组件边界和职责
  • 尽量描述“是什么”
  • 少解释“为什么当年这么设计”
  • 复杂背景放到单独引用文档里

代理做任务需要的是定向约束,不是系统史。

警告太多,代理会逐条核对,最后越做越慢

另一种常见失败模式,是在 AGENTS.md 里塞满风险提示:

  • 不要破坏数据库迁移
  • 不要影响 API 版本兼容
  • 不要绕过认证边界
  • 不要触发部署风险
  • ……

如果只有少量关键规则,问题不大;如果有 30 到 50 条,代理很可能会把每一条都当作检查项,逐一搜索相关代码,再试图证明自己没违规。

研究中的一个案例是简单 CRUD 接口任务,但文档里有 30 多条“不要”规则,覆盖迁移、版本、部署、安全等多个维度。结果代理为了逐条核验相关性,去看了许多完全不需要触及的代码,PR 耗时翻倍,平均完成度下降 20%。

解决办法也很直接:

  • 主文件只保留最核心的坑
  • 其他规则移到引用文档
  • 尽量给每条禁令配一个明确替代方案

失败二:新模式出现时,旧文档会把代理带回老路

这是很多团队会踩的另一类坑:代码库正在引入新架构或新范式,但 AGENTS.md 记录的还是旧世界。

研究中的例子是,文档强调现有 REST + polling 模式,而任务要求实现基于 WebSocket 的实时协作编辑。代理很忠实地遵守文档,最终做出了一个“能工作但方向错了”的轮询方案;而真实合入的黄金 PR 采用的是完全不同的 WebSocket 数据流设计。

这里的教训很明确:

如果你在做代码库里前所未有的新模式,AGENTS.md 往往不是最佳载体。

因为 AGENTS.md 擅长的是:

  • 收敛已有实践
  • 强化既有约束
  • 指导代理复用现有路径

它不擅长定义尚未落地的新架构。遇到这类任务,更合适的是规格驱动开发,也就是给出明确 spec、接口契约、数据流约束和验收标准,而不是指望代理从旧文档里“悟出新范式”。

你要先知道自己在优化什么

这项研究还有一个很有价值的地方:它没有把所有收益混成一个“整体变好了”的结论,而是拆成不同指标来看。

因为不同文档模式,改善的是不同问题。

你想改善的问题 更适合的写法
提高现有代码复用率 放几个清晰且贴近场景的真实代码示例
提高对代码库既有实践的遵守程度 用决策表说明组件或库的选择规则
减少大型功能开发时漏接线、漏注册 写成编号明确的流程化 AGENTS.md
处理高风险坑点 每个“不要”都配一个“应该怎么做”
缓解上下文腐化 用渐进式披露,把细节移到引用文档
降低代理无目的扩展阅读 明确区分每个引用文档的范围和用途
避免代理吸收无关规范 主文件只保留与周围代码直接相关的指导

这张表背后的含义是:不要把 AGENTS.md 当成统一解决方案。 先识别你们代理最常见的失败模式,再选对应的文档策略。

如果代理总是“写得不像你们项目”,优先补决策表和代码示例。 如果代理总是“做一半漏一半”,优先补流程化步骤。 如果代理总是“先查半天资料再动手”,先清理文档环境和规则密度。

代理究竟怎么发现你的文档

这部分很关键,因为它直接决定迁移优先级。

研究追踪了数百次代理会话中的文档发现路径,结果非常不均衡。

发现率最高的文档位置

  • AGENTS.md:几乎 100% 会被自动发现。大多数运行框架都会从当前工作目录一路向上查找层级中的 AGENTS.md
  • AGENTS.md 里直接引用的文档:只要代理有理由加载,在 90% 以上的会话里都会被读到
  • 当前工作目录层级的 README.md:虽然不会自动加载,但代理在该目录工作时,80% 以上场景会主动去读

发现率急剧下降的位置

  • 当前任务无关子目录里的嵌套 README:发现率大约只有 40%
  • _docs/ 这类没人引用的孤立文档:会话中被读到的比例低于 10%

研究里有个例子,一个服务在 _docs/ 下放了 3 万字符的协议设计、限流规则和安全说明,但在几十次会话里,代理几乎没打开过其中大部分内容。

这带来一个很现实的结论:

如果某些信息必须让代理看到,要么放进 AGENTS.md,要么从 AGENTS.md 直接引用。 把重要内容继续藏在无人引用的角落里,实际效果通常很差。

怎么把现有 README 和设计文档迁移成代理可用的体系

几乎没有公司是从零开始写文档的。多数仓库里已经散落着:

  • README.md
  • 架构设计说明
  • 历史迁移文档
  • 协议规范
  • 各种临时总结

真正的问题不是“要不要新建 AGENTS.md”,而是怎么把这些已有材料整理成代理能高效消费的结构。

该不该直接把 README.md 改名成 AGENTS.md

可以复用,但不要直接改名了事。

README.md 的默认读者是人,常常包含这些内容:

  • 面向新人浏览的背景介绍
  • 较长的概念解释
  • 偏宣传或偏概览的章节
  • 与当前目录代码没有直接关系的扩展阅读

这些内容对代理帮助有限,甚至可能有副作用。

更务实的做法是:

  1. 先拿现有 README.md 做底稿
  2. 大幅裁剪
  3. 只保留与该目录编码任务直接相关的内容
  4. 把面向人类浏览的章节删掉或移走
  5. 补上决策表、流程、真实代码示例和明确引用

不是把文件名改了就完成迁移,而是把文档目的从“供人阅读”切换成“供代理执行”。

什么样的旧文档值得保留

如果一份旧文档具备这些特点,就值得保留并被引用:

  • 内容准确且仍然有效
  • 文字简洁,不绕
  • 有示例
  • 作用范围明确
  • 与某个模块或子目录强相关

这类文档可以挂在模块级 AGENTS.md 下,按需引用。

作者给出的建议是:单个 AGENTS.md 不要挂太多引用,最好控制在 10 到 15 个以内。

原因很现实。引用越多,代理越容易进入“我是不是都该看看”的模式,结果主文档又变成索引入口,而不是高效路由器。

另外,迁移时别只盯着 AGENTS.md 本身,还要审计周围环境。假如这个模块周围已经堆着几十份设计文档和规格说明,那么哪怕你的 AGENTS.md 很精炼,代理仍可能被周边材料吸走。

AGENTS.md 不是唯一入口

研究也提到一个容易忽略的事实:代理不只靠 AGENTS.md 找资料,它也会通过 grep 和语义搜索发现内容。追踪数据显示,大约一半搜索命中来自这些工具,而不是来自 AGENTS.md 的直接引用。

这意味着,如果你要保留一部分历史文档,至少应该保证两件事:

  • 文档里有可搜索的描述性文本
  • 文档里有真实、贴近实现的代码示例

这样即便代理不是从 AGENTS.md 进入,也有机会通过搜索命中真正有价值的参考内容。

但话说回来,搜索发现和入口发现不是一回事。搜索更像“碰运气”,AGENTS.md 更像“可控分发”。如果你希望上下文稳定,后者仍然更可靠。

我对这项研究的几个判断

这篇研究最有价值的地方,不是告诉你“要写 AGENTS.md”,而是把很多团队对 AI 编码代理的误解拆穿了。

第一,文档不是静态资产,而是推理控制面

传统工程文档默认是给人看的,人会跳读、会过滤、会根据经验忽略废话。

代理不是这样。你给它的文档,实际上在重塑它的注意力分配、搜索路径和决策顺序。写得不好,等于主动给模型注入噪声。

所以,AGENTS.md 的设计目标不该是“全面”,而该是“高信号密度”。

第二,很多团队缺的不是文档,而是文档分层

不少仓库的问题,并不是没有规则,而是规则、架构背景、历史说明、迁移备注全堆在一起。人类工程师靠经验还能分辨主次,代理做不到这么稳。

如果想让编码代理表现稳定,文档结构最好能回答三个问题:

  • 当前目录最常见的任务是什么
  • 遇到歧义时该怎么选
  • 哪些信息必须看,哪些信息按需加载

这比“再补一份更全的说明文档”重要得多。

第三,AGENTS.md 更像推理时的轻量微调

原文标题说得很形象:好的 AGENTS.md,相当于一次模型升级。

这当然不是参数层面的微调,但在实际效果上,确实很像“面向代码库局部语境的推理期调优”。你没有改模型权重,却通过精确组织上下文,让它更像一个理解你们项目习惯的工程师。

换个角度看,这也是上下文工程比很多人想象中更重要的原因。模型能力在提升,但能不能把能力稳定释放到具体代码库里,往往取决于文档入口设计。

给团队落地的实用建议

如果你准备在项目里系统整理 AGENTS.md,我建议按下面的顺序做。

1. 先挑一个中等规模、边界清晰的模块试点

不要上来就在 monorepo 根目录写总纲。 先找一个满足这些条件的模块:

  • 边界清楚
  • 日常任务较集中
  • 现有模式比较稳定
  • 文件规模中等

这类区域最容易看到改进,也最适合提炼模板。

2. 主文件控制在 100 到 150 行左右

优先放这些内容:

  • 模块职责边界
  • 常见任务流程
  • 决策表
  • 少量真实代码示例
  • 高风险规则及对应替代方案
  • 明确的引用文档入口

删掉这些内容:

  • 长篇背景介绍
  • 历史设计原因
  • 与当前目录不直接相关的广域规则
  • 面向人类读者的概览性段落

3. 每写一条规则,都问一句:代理下一步该做什么

如果规则只是在告诉代理别犯错,那通常不够。 更好的写法应该能让代理立即行动。

例如:

  • 不要直接访问数据库连接
  • 使用 db/session.ts 暴露的事务包装器

这种规则对代理最友好,因为它既减少试错,也减少搜索。

4. 用审查意见反推应该补什么

看最近一批 AI 生成 PR 的 review comment,找出高频问题:

  • 总是选错库
  • 总是漏改某几个文件
  • 总是写出不符合本项目风格的实现
  • 总是去读太多无关文档

这些问题基本就对应了前文几种高价值模式:

  • 选错库:补决策表
  • 漏改文件:补流程
  • 风格不一致:补真实代码示例
  • 读文档过多:清理主文件和引用结构

5. 把文档环境一起治理,不要只改入口文件

如果模块周围已经有大量陈旧、重复、互相冲突的说明,单靠一份新的 AGENTS.md 很难扭转局面。

需要一起做的事情包括:

  • 删除无人维护的旧文档
  • 合并重复规则
  • 给保留文档补清晰标题和适用范围
  • 让真正重要的内容可以被搜索到,也可以被明确引用到

入口文件决定代理“先看到什么”,周边环境决定代理“还会被什么吸走”。两者都得管。

结语

这项研究给出的结论并不复杂,但很有分量:对编码代理来说,文档质量本身就是模型能力的一部分。

好的 AGENTS.md 不是多写一点说明,不是把 README 改个名字,也不是把所有经验法则堆进去。它更像一份为代理设计的操作手册,目标很明确:

  • 缩短判断路径
  • 消除实现歧义
  • 减少无关探索
  • 把代理稳定地引向代码库已有的正确模式

如果你的团队已经在使用 AI 编码工具,这件事值得投入。因为模型再强,进了一个信号密度很低、组织混乱的文档环境,表现照样会漂。

而一份写对的 AGENTS.md,往往就是让代理“终于像自己人一样写代码”的起点。

关于

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计