Harness 工程里的 AGENTS.md 应该怎么写
配套 Prompt:生成并验证 AGENTS.md 的 Prompt。
很多团队第一次写 AGENTS.md,很容易把它写成一份“项目知识大全”:技术栈、目录树、编码规范、测试命令,能想到的都放进去。这样看起来很完整,却不一定真的能帮助 Agent。
我更愿意把 AGENTS.md 理解成 Coding Agent 进入仓库后的操作地图。 它要解决的不是“怎样让 Agent 知道更多”,而是让 Agent 在有限上下文里尽快判断:
- 从哪里开始;
- 哪些文件承载事实;
- 应该修改什么;
- 改完运行什么;
- 哪些边界不能自行越过。
Harness 工程围绕 Coding Agent 设计上下文、工具、约束和反馈回路。在这个系统里,AGENTS.md 位于“行动之前”:先把必要的仓库知识和操作边界送进上下文。测试、lint、类型检查和结构检查则位于“行动之后”:它们负责告诉 Agent 刚才的修改究竟对不对。
两边缺一不可。只有 AGENTS.md、没有可运行的验证,规则最终只能靠 Agent 记住;只有 CI、没有清楚的任务入口,Agent 又会在仓库里反复试错。真正有效的 Harness,应该让路线和反馈形成闭环。
为什么要写 AGENTS.md
Coding Agent 知道怎样写 TypeScript、Go 或 Python,但这不等于它了解你的项目。它无法仅凭语言能力判断:哪个目录才是修改入口,哪些旧代码不能作为正例,哪个检查才是交付门禁,某个看起来过时的兼容选择是不是故意保留的,以及遇到生产、迁移或历史重写时什么时候必须停下来。
这些答案通常散落在人脑、事故记录、CI、脚本和专题文档里。AGENTS.md 不需要把它们全部复制一遍,只需要提取那些会改变下一步行动的信息,再把 Agent 带到正确的事实来源。更准确地说:
AGENTS.md是仓库与 Coding Agent 之间的协作接口,用来暴露代码本身无法充分表达的操作契约。
一份写得好的 AGENTS.md,通常会减少三类成本:
- 探索成本:把任务连接到事实来源、主要路径和最低检查,减少无关文件读取;
- 误判成本:说明生成文件、架构边界、兼容约束和高风险动作的停止条件;
- 验收分歧:把“代码已经改完”改成可由测试、diff 和运行结果证明的完成标准。
但这并不意味着每个仓库都需要一份很长的文件。准备写下一条规则时,可以先看看它是否同时满足下面几个条件:
- Agent 难以从代码、配置和相邻文档自行推断;
- 内容相对稳定,适用于一类任务而不是单次 issue;
- 猜错会造成明显返工、兼容问题或安全风险;
- 读到后会改变 Agent 的下一步行动;
- 暂时无法由类型、lint、测试、脚本或权限机制强制执行。
这里还有一条很重要的边界:AGENTS.md 不能弥补功能设计、模式选择和具体实现能力不足。 后文会看到,多项研究对 context file 的效果给出了并不一致的结果。它最适合解决的是“缺少仓库上下文”造成的失败,而不是替模型能力兜底。
所以,真正的目标从来不是“仓库必须有一份 AGENTS.md”。 我们想要的是 Agent 少猜、少走错路,知道怎样证明完成,也知道什么时候应该停下来。如果文件做不到这些,宁可让它保持简短,甚至暂时不写。
题外话:AI 没有创造这个问题
AI 没有创造仓库知识问题,它只是把过去被人的社会协作遮住的问题暴露了出来。
没有 AI 时,开发者同样应该知道:从哪里开始,哪些代码不能照抄,架构边界是什么,修改后运行哪些检查,以及什么操作需要审批。 只是这些信息未必写在仓库里。它们可能存在于老成员的记忆、代码评审、口头沟通、入职培训、群聊和事故经验中。人遇到不确定时会问同事,也会随着长期参与逐渐形成项目直觉。
Coding Agent 不具备这层稳定的组织记忆。每个任务都更像一个刚进入项目、权限却可能很高的临时协作者。因此,它迫使团队回答一个过去可以回避的问题:
如果没有熟悉项目的人在旁边解释,仅凭仓库本身,一个新的执行者能否安全完成任务?
所以,AGENTS.md 不应只被理解成“写给 AI 的说明书”。更准确的定位是:
AGENTS.md是面向上下文不足的执行者的启动协议。
这个执行者可以是 Coding Agent,也可以是新人、外部贡献者、临时支援者、值班工程师,甚至是半年后重新回到这个模块的自己。
进一步看,仓库里的知识其实分为三个层次:
| 层次 | 作用 | 例子 |
|---|---|---|
| 仓库事实 | 对人和 Agent 都成立的真实契约 | 架构、兼容范围、发布流程、数据所有权 |
| 使用入口 | 针对不同读者组织事实 | README.md、CONTRIBUTING.md、AGENTS.md、runbook |
| 执行机制 | 不依赖任何人记忆来强制约束 | 类型、lint、测试、CI、权限、hook |
这样看,AGENTS.md 不应该成为另一份事实来源。它更像一个针对 Agent 使用方式优化的视图:把任务路由、相关文档、命令和停止条件组合起来,但底层事实仍然属于代码、配置和专题文档。
AI 带来的新变化主要有四个。
- 使用方式变了。 人通常会慢慢浏览文档,Agent 则需要在有限上下文内快速选择下一步,因此信息需要更像一张路由表。
- 记忆方式变了。 人会积累长期的项目经验,Agent 的会话通常是短暂的,所以每次都需要一个稳定的启动入口。
- 执行速度变了。 人一天可能完成几次高影响修改,Agent 可以快速、并行地执行很多次。同一个模糊规则造成的错误会被更快放大。
- 遵守规则的机制变了。 人可以理解组织语境并承担责任;Agent 对自然语言规则的遵循是概率性的,因此必须结合工具反馈、权限门禁和执行记录。
AGENTS.md 的质量,最终反映的不是团队多会写 Prompt,而是仓库是否具有可操作性。
如果很难为仓库写出一张清晰的任务地图,往往说明项目本身存在问题:事实来源分散、命令不稳定、架构边界只存在于人脑、完成标准不一致,或者安全边界依靠口头提醒。从这个意义上说,AI 是一种“仓库可操作性压力测试”。它让原本隐藏的知识债务变得可见。
理想状态甚至不是 AGENTS.md 越写越完整,而是它逐渐变薄:架构约束进入静态检查,生成一致性进入 CI,危险操作进入权限系统,复杂流程进入脚本和 runbook,仓库事实进入结构化文档;AGENTS.md 最后只留下启动、路由、少量隐性契约和停止条件。
所以,我们不是因为有了 AI 才需要治理仓库知识;AI 只是让过去依赖熟人、记忆和口头协作的方式无法继续隐藏。AGENTS.md 既服务 Agent,也反过来帮助团队检查:这个仓库是否真的能让任何上下文不足的新协作者独立、安全、可验证地工作。
先看真实项目怎么写
讨论“应该怎么写”之前,最好先看看真实项目已经写成了什么样。否则很容易把个人偏好整理成模板,再给它贴上“最佳实践”的标签。
这次我先用 GitHub 公开代码搜索找出根目录包含 AGENTS.md 的仓库,使用下面的筛选条件:
可以直接打开 GitHub 的 AGENTS.md 公开代码搜索,查看仍在维护的非 fork 仓库如何编写这类文件。搜索结果会随开源项目持续更新,比任何固定模板都更适合作为长期候选库。
path:/^AGENTS\.md$/ NOT is:fork NOT is:archivedGitHub 对新版 Code Search 的介绍 只说明默认把最相关的结果放在前面,并没有公开完整的排序公式;它支持的 查询限定词 中也没有 stars:。对于这个精确路径查询,每个结果满足的条件近似相同,因此搜索顺序既不代表仓库更流行,也不代表其中的 AGENTS.md 写得更好。
为了让样本更有说服力,我没有直接截取搜索结果的前几页,而是先收集候选仓库,再读取仓库元数据,筛选调研时约 1 万 Stars 以上的项目并按 Stars 降序整理,同时尽量覆盖编辑器、语言工具链、Web 框架、基础设施、数据平台和 AI SDK。Code Search 负责发现候选仓库,Stars 负责筛选样本,内容分析负责判断质量。 Stars 在这里只是一道影响力门槛,不是质量评分;进入样本后,仍然要逐条判断文件是否真的减少了 Agent 的猜测。
样本概览
| 项目 | Stars | 行数 | 值得借鉴的部分 | 明显边界 |
|---|---|---|---|---|
| VS Code | 188k | 5 | 根文件只负责指向已有的权威指令,避免维护两份事实 | 本身几乎没有工程信息,完全依赖被链接文件 |
| LangChain | 144k | 364 | 把 monorepo 的包、测试和发布差异写得很具体 | 内容接近完整贡献指南,首次加载成本较高 |
| Next.js | 142k | 512 | 目录、测试、调试和常见失败路径都能直接行动 | 信息量很大,已经接近仓库操作百科 |
| Kubernetes | 124k | 36 | 用很短篇幅说明生成文件、vendor 和 staging 的事实来源 | 大量细节仍需继续查阅链接和相邻文档 |
| TypeScript | 110k | 30 | 明确项目生命周期、可接受改动和需要停下确认的范围 | 内容服务于特殊维护阶段,不能直接套用到普通项目 |
| OpenAI Codex | 104k | 322 | Rust 约定、测试层级、评审和上下文预算都很具体 | 子系统细节较多,根文件偏长 |
| PyTorch | 102k | 319¹ | 构建、测试、生成文件和基础设施副作用解释充分 | 通过符号链接复用长篇指令,治理与工程信息较重 |
| Neovim | 102k | 6 | 极简地定义 AI 辅助贡献的披露要求 | 只解决贡献治理,不能单独指导代码修改 |
| Bun | 95k | 239¹ | 明确正确的调试构建和测试入口,避免误用常见命令 | 通过符号链接复用,且大量内容与自身工具链绑定 |
| uv | 88k | 21 | 用 21 行说明目标测试、lint、lockfile 和平台差异 | 假定读者会继续阅读贡献指南和相邻代码 |
| Zed | 84k | 188¹ | 用同一份规则服务多种 Agent,并写清 Rust/GPUI 约定 | 框架专属规则较多,跨项目复用价值有限 |
| Grafana | 76k | 169 | 为大型 Go/TypeScript monorepo 提供分层规则和目录入口 | 根文件仍包含一些通用开发原则 |
| Ruff | 49k | 168 | 测试、snapshot 更新和评审要求精确到命令 | 命令与环境细节占比较高 |
| Apache Spark | 44k | 267 | 工作树预检、golden file 和测试基类选择非常具体 | 流程规则较多,部分约束可能限制 Agent 自主性 |
| Nushell | 40k | 21 | 紧凑记录 Rust 与 Nushell 的具体陷阱 | 个别措辞带有情绪,不适合作为团队规则范本 |
| OpenAI Agents Python | 28k | 278 | 把任务路由到 Skills,并解释翻译生成与验证流程 | 强依赖该仓库的 Skills 和内部工作方式 |
| radare2 | 24.5k | 112 | 路径、C 语言陷阱、构建和提交规则非常具体 | 编码规则占比高,只适用于该代码库 |
| Google Benchmark | 10.3k | 45 | 清楚定义 AI 贡献披露和人工责任 | 几乎不提供工程导航 |
¹ PyTorch、Bun 和 Zed 的根 AGENTS.md 是符号链接,表中统计的是链接目标的有效行数,而不是符号链接本身。
这 18 个样本的有效行数中位数约为 169 行,其中 8 个不超过 120 行,7 个超过 200 行。它们并没有共同收敛到某个“最佳长度”:同样是高影响力项目,VS Code 只用 5 行做入口转发,Next.js 则写了 500 多行。长度本身不能证明好坏,真正要问的是:这些内容是否需要在每个任务开始时进入上下文。
这当然不是统计意义上的全量调查。GitHub 搜索排序、索引时间和公开可见性都会带来偏差,Stars 也与文件质量没有必然关系。这些样本适合帮助我们归纳工程模式,却不足以证明整个生态的采用率,更不能单独证明某种写法会提高任务成功率。后面谈有效性时,还需要回到实验研究。
优秀样本的共同点
把这些文件放在一起看,会发现优秀样本并不共享某种固定目录,也没有统一的章节顺序。它们真正相似的地方,是都在努力减少 Agent 最容易做错的判断。 下面七点,比复制任何一份完整模板更值得复用。
1. 写“Agent 猜不对的事实”
技术栈当然有用,但如果仓库里已经有 go.mod 或 package.json,再写一句“这是 Go 项目”或“这是 React 项目”,并不会改变 Agent 的行动。优秀样本更在意那些代码表面看不出来、猜错以后又确实会出问题的事实。
例如,TypeScript 没有重复语言和构建常识,而是先告诉 Agent 一个更关键的事实:当前 JavaScript 编译器处于维护阶段,大型新功能应该转向 typescript-go,超出维护范围的请求需要停下来确认。
PyTorch 写下的也是代码表面很难看出的操作语义:.pyi 文件可能由 .pyi.in 生成,修改 .ci/docker/ 会改变 Docker build context hash,并触发镜像重建。这类信息不一定适用于其他仓库,却会直接改变 Agent 在当前仓库里的下一步行动。
关键不只在于它们写了“不能改”,还在于说明了项目当前的真实状态、影响范围和替代路径。 Agent 因此能判断,哪个看似合理的现代化修改其实会越过项目边界。
radare2 也采用同样思路:它没有泛泛要求“注意内存安全”,而是写明不能使用 alloca() 和变长栈数组、何时使用项目宏、JSON 解析函数的所有权差异,以及为什么不能直接运行某些格式化命令。
所以,当你犹豫一条规则是否值得进入根 AGENTS.md 时,可以问三个问题:
- Agent 能否仅从相邻代码和配置推断出来?
- 猜错后是否会造成返工、兼容性问题或安全风险?
- 这条事实是否仍然稳定,能否给出来源或验证方式?
越难猜、猜错代价越高、同时又足够稳定的事实,越值得占用根文件的上下文。
2. 给路线,不复制整本手册
OpenAI 在 Harness 工程实践中有一个很形象的总结:给 Agent 一张地图,不要给它一本千页说明书。OpenAI 团队也曾维护过巨大的 AGENTS.md,后来把入口缩到大约 100 行,再让结构化 docs/ 承担详细事实。
公开样本也能看到两种相反写法:
这并不是说长文件里的内容不好,问题在于它什么时候被加载。Agent 只是修一个文档链接时,并不需要同时把所有子系统的调试和测试细节装进上下文。详细知识应该存在,但不必在每个任务开始时一次性出现。反过来,极短的入口也只有在它指向的文档足够准确、工具确实会继续读取时才有效。
更合适的分工是:
| 文件 | 应解决的问题 |
|---|---|
README.md | 项目是什么,怎样安装和使用 |
ARCHITECTURE.md | 系统如何拆分,依赖方向是什么 |
docs/ | 设计、流程、运维与排障的详细事实 |
AGENTS.md | 当前任务从哪里开始,怎么修改和验证 |
AGENTS.md 应提供渐进式入口:
- 修改模块边界前,先读 `ARCHITECTURE.md`。
- 修改认证流程前,先读 `docs/security/authentication.md`。
- 发布任务遵循 `docs/releasing/README.md`,不要在本文件复制完整步骤。3. 把任务类型连接到路径和验证
目录说明回答“仓库里有什么”,任务路由回答“我现在应该做什么”。 对 Agent 来说,后一个问题通常更重要。
Grafana 在根文件中列出不同目录中有明确作用域的 AGENTS.md,让 Agent 根据改动位置继续读取更具体的规则。OpenAI Agents Python 则把特定任务路由到对应 Skill,并单独说明翻译生成、文档和测试的处理方式。
这种分层路由通常会同时回答:
- 负责什么;
- 主要改哪里;
- 本地怎样工作;
- 提交前怎样验证。
这种结构可以压缩为一张表:
| 任务 | 先读 | 主要位置 | 最小验证 |
|---|---|---|---|
| API 行为 | docs/api.md | src/api/、src/services/ | 目标测试 + 契约测试 |
| 数据库变更 | docs/database.md | db/migrations/ | 迁移测试 + 集成测试 |
| 前端交互 | docs/frontend.md | src/pages/、src/components/ | typecheck + UI 验证 |
| CI/CD | docs/releasing.md | .github/workflows/ | 构建 + workflow 检查 |
一张这样的表同时回答“看哪里、改哪里、跑什么”。 它不追求描述整个仓库,却更接近 Agent 拿到任务之后真正需要做的决策。
4. 命令需要适用条件,不只是清单
命令最容易出现两个极端:“运行测试”没有任何操作价值,“每次运行全部测试”又可能昂贵到没人真正执行。成熟项目通常会把验证分成层次:
- 先运行受影响包的目标测试;
- 再根据公共接口、生成代码或跨平台影响扩大验证;
- 昂贵的 E2E、容器或云环境测试单独说明前置条件。
uv 要求优先运行目标测试,而不是默认跑完整测试套件,还单独写出 Windows 相关修改应使用的 cargo xwin clippy。Bun 则提醒 Agent 使用正确的调试构建测试入口,而不是看到项目名就直接运行最自然的 bun test。
Apache Spark 记录了另一类容易漏掉的执行语义:开始前先检查工作树状态,修改 SQL 行为可能需要更新 golden files,不同测试场景还要选择正确的测试基类。像这样的条件,往往比命令名称本身更值得写入。
有效的命令说明至少包含:
触发条件 → 命令 → 前置条件 → 通过标准或失败后的下一步5. 禁区要解释失败路径
“不要修改生成文件”只告诉 Agent 此路不通,却没有告诉它正确的路在哪里。 一条完整规则还要说明应该改哪个源文件、运行什么生成命令,以及最终怎样确认结果一致。
- `src/generated/` 由 `npm run codegen` 生成,不要手工编辑。
- 修改 `schemas/` 后运行 `npm run codegen`,同时提交 schema 和生成结果。
- CI 会检查生成结果与源文件是否一致。同样,“不要修改生成文件”通常过于笼统。Kubernetes 会进一步区分 vendor、staging 和生成内容的事实来源,让 Agent 知道应该修改上游源文件还是运行生成流程,而不是把所有“看起来自动生成”的目录一律避开。
边界只有同时写清对象、原因和替代路径,才真正具有指导作用。 否则 Agent 可能避开了字面上的禁止动作,却换一种方式继续犯同一个错误。
6. 用正例和反例处理遗留代码
Agent 很擅长从仓库里寻找相似实现,这通常是优点,但在遗留系统中却可能变成陷阱:旧模式往往比新约定出现得更多。此时只写“遵循现有风格”,等于鼓励它复制数量最多的技术债。
OpenAI Codex 会直接指出:
- 哪些 Rust 模块已经过大,不应继续向其中堆放实现;
- 哪些现有 crate 或子系统才是新增能力更合适的归属;
- 修改 TUI、snapshot 或配置时应该参考哪些相邻实现;
- 不同范围的改动分别需要运行哪一层测试。
这种写法比抽象的编码规范更有用,因为 Agent 可以直接搜索正例,也知道哪些高频模式虽然存在,却不应该继续扩散:
- 新 handler 参考 `src/orders/create-handler.ts`。
- 不要复制 `src/legacy/handlers/` 的基类模式;该目录只为兼容保留。7. 贡献治理与工程导航是两个维度
Google Benchmark 的 AGENTS.md 几乎只讨论 AI 使用披露、人工责任和自动贡献限制。Neovim 也把根文件集中在 AI 辅助贡献的披露方式上。
单靠这两份文件都无法完成一次代码修改,但它们提醒了我们:有些项目首先担心的不是 Agent 能不能找到文件,而是谁对 AI 生成的贡献负责。AGENTS.md 因此也可能承载治理约束。
治理规则值得保留,但不应代替工程地图。一个同时接受外部贡献、又希望 Agent 能完成任务的仓库,至少要区分:
- 工程规则:路径、命令、架构边界和验证;
- 治理规则:AI 披露、提交格式、PR 模板、发布授权和人工审核责任。
是否要求披露 AI 使用、标记共同作者或进行人工复核,是每个项目自己的治理选择,不是 AGENTS.md 这种开放格式天然附带的通用要求。借鉴开源项目时,这一点尤其不能照抄。
哪些“常见写法”不值得复制
从样本里找共同点时,还有一个容易忽略的问题:常见不等于有效。 有些内容几乎每份模板都有,只是因为容易写,而不是因为它真的能帮助 Agent。
1. 完整技术栈清单
锁文件、manifest 和构建配置已经说明的版本,没有必要全部重复。真正值得写的是那些会影响选择、却不容易从仓库确认的部分,例如兼容下限、受支持平台,或者某个暂时不能升级的依赖。
2. 完整目录树
完整目录树看起来直观,重构一次就可能过期。只保留职责容易混淆、修改风险不同或者验证方式不同的路径,通常已经足够。
3. 完整架构教程
架构当然需要解释,只是不必在每个任务开始时全部加载。让 ARCHITECTURE.md 或 docs/ 保存详细事实,AGENTS.md 只负责说明什么任务需要先读哪一部分。
4. 没有条件的绝对命令
“必须运行所有测试”“永远不新增依赖”看起来很严格,实际很容易被环境和任务规模击穿。一条经常无法执行的绝对规则,最后只会训练 Agent 忽略规则。更好的写法是说明触发范围、最低要求,以及什么情况下需要扩大验证。
5. 无法验证的生态数字
公开文章经常列出支持工具数、采用仓库数,或者大型内部仓库的文件数量。这些数字很有传播力,却未必有可追溯的一手来源。能够确认的格式事实可以引用开放格式说明;某个工具怎样加载、是否原生支持,则应该回到它当前的官方文档。无法验证的数字,不适合拿来支撑工程决策。
6. 把所有规则留在自然语言里
最后一种问题不是写错,而是把本该由机器执行的事情永远留在文字里。如果 formatter、lint、类型系统、结构测试或 CI 已经能稳定判断,就应该把规则升级成可执行反馈。 文档适合解释意图和提供路线,不适合永久承担机械检查。
一套可复用的结构
看到这里,我们可以整理出一套起步结构。它不是必须填满的七项清单,而是七个可以依次追问的问题。小型仓库只回答其中四五个,也可能已经足够。
1. 开始工作
第一个问题是:Agent 动手之前,必须先确认什么?这一节通常不超过五条:
- 是否先看 Git 状态;
- 哪些入口文档是事实来源;
- 是否存在用户改动、子模块或特殊环境;
- 什么情况需要先做计划。
2. 操作地图
第二个问题是:拿到不同任务时,应该去哪里?用任务路由连接“任务—文档—路径—验证”,它通常是整份文件最有价值的部分。
3. 关键约束
第三个问题是:哪些约束看不出来,却不能猜错?这里可以放兼容性、依赖方向、数据所有权、运行时契约和资源预算,同时说明它们存在的原因。
4. 编辑与生成规则
第四个问题是:正确修改路径是什么?用正例和反例说明现行模式,写清生成文件来源、迁移策略,以及哪些文件必须同步变化。
5. 验证矩阵
第五个问题是:怎样证明修改完成?按变更类型给出最小验证、追加验证,以及昂贵测试的前置条件,而不是只列一串命令。
6. 安全与治理
第六个问题是:什么事情不能由 Agent 自行决定?密钥、生产环境、破坏性 Git 操作、部署、数据库、AI 披露和提交权限,都可能需要明确的停止条件。
7. 完成标准与文档入口
最后一个问题是:什么状态才算完成?除了完成标准,也要说明验证受阻时应该怎样汇报。详细流程继续留在 docs/,这里给出入口即可。
可直接裁剪的模板
下面给出一份可以直接裁剪的模板。我刻意保留了占位符,因为它的价值是帮助你提问,而不是假装提前知道每个仓库的答案。复制之后,必须用仓库事实替换,并删除所有不适用的内容。
# AGENTS.md
## Getting Started / 开始工作
- 按需读取相关文件,不要默认扫描整个仓库。
- 修改前运行 `git status --short --branch`,保留用户已有改动。
- 涉及模块边界时先读 `ARCHITECTURE.md`。
- 涉及 `<高风险领域>` 时先读 `<对应文档>`。
## Operation Map / 操作地图
| 任务 | 先读 | 主要位置 | 最小验证 |
| --- | --- | --- | --- |
| 应用代码 | `<开发文档>` | `src/` | `<目标测试>` |
| 公共接口 | `<接口契约>` | `src/api/`、`schemas/` | typecheck + 契约测试 |
| 数据迁移 | `<迁移规范>` | `db/migrations/` | 迁移测试 + 集成测试 |
| CI/CD | `<发布文档>` | `.github/workflows/` | 构建 + workflow 检查 |
## Critical Constraints / 关键约束
- `<路径或组件>` 是 `<外部契约>`;不要 `<看似合理但会破坏契约的动作>`。
- `<版本下限>` 是为了 `<兼容对象>`,升级或降级前必须确认影响。
- `<模块 A>` 只能依赖 `<模块 B>`;由 `<lint/结构测试>` 检查。
## Editing Guidelines / 编辑规范
- 保持修改范围最小,不批量重排无关文件。
- 新 `<组件类型>` 参考 `<当前正例文件>`。
- 不要复制 `<遗留路径>` 中的 `<旧模式>`。
- `src/generated/` 由 `<生成命令>` 生成,不要手工编辑。
- 修改 `<源文件>` 后,同时更新 `<生成结果/测试/文档>`。
## Verification / 验证规范
| 变更 | 最小验证 | 追加验证 |
| --- | --- | --- |
| 局部逻辑 | `<目标测试>`、lint | 受影响模块测试 |
| 公共接口 | typecheck、契约测试 | 全量测试、兼容性检查 |
| UI | build、目标交互验证 | E2E、截图 |
| 迁移 | 临时数据库迁移 | 回滚和集成测试 |
- `<昂贵测试>` 需要 `<Docker/云账号/本地服务>`。
- 先运行目标检查,再按影响范围扩大验证。
- 无法运行的检查必须说明原因,不得伪造通过结果。
## Safety and Governance / 安全与治理
- 不读取、输出或提交密钥、`.env` 和生产数据。
- 不连接生产服务,不执行部署或迁移,除非用户明确授权并确认目标。
- 强制推送、删除 Tag 和重写共享历史必须先确认范围。
- `<AI 披露、PR 模板或提交规则>`。
## Completion / 完成标准
- 实现与用户请求一致,没有无关修改。
- 测试、生成文件、迁移和文档与代码保持同步。
- `git diff --check` 通过,工作树没有缓存或临时文件。
- 汇报已运行的检查、未运行项及剩余风险。
## Documentation Map / 文档地图
- `README.md`:安装、运行和使用入口。
- `ARCHITECTURE.md`:模块职责与依赖方向。
- `<docs 路径>`:`<详细流程或事实>`。模板写完只是起点。真正有价值的内容,往往来自仓库独有的失败经验:Agent 曾经改错过哪个目录,漏跑过哪项检查,复制过哪个遗留模式,猜错过哪种数据形状,又曾在哪个外部系统上越过边界。模板只能给出问题,仓库历史才会给出答案。
如何使用通用模板
通用模板最适合帮助第一次建立入口文件的团队,避免漏掉基本结构。但如果原样复制后长期维护,它很快就会变成一份看似全面、实际上与项目关系不大的说明。模板提出的几个问题——项目是什么、代码在哪里、怎样运行、遵守什么、禁止什么、怎样验收——可以作为评审目录;真正写入的答案仍然必须来自当前仓库。
我建议至少做三轮裁剪:
- 删除 README、manifest、CI 或代码已经明确表达的常识,只留下 Agent 不容易推断的事实;
- 把不适用的技术栈、数据库、测试框架、生成目录和命令全部删除,不要用占位符伪装成规则;
- 把“完整验证”“锁文件不可修改”“更深层规则一定覆盖上层规则”等依赖项目或工具实现的说法改成当前 Harness 已确认的行为。
还要特别留意 README.md 与 AGENTS.md 的关系。前者帮助人理解项目和使用产品,后者把当前任务路由到事实来源、修改路径、命令和边界。它们可以指向同一个事实,却没有必要各自复制一遍。内容重叠时,保留一个权威来源,再从另一个文件链接过去。
先让 Subagent 预审,再交给人
如果开发者把本文和一个仓库一起交给 AI,最危险的结果不是它完全不会写,而是它很快生成了一份看起来很专业的 AGENTS.md,然后直接覆盖、提交。 路径可能都存在,命令也很像真的,但其中某条规则也许只是从旧代码猜出来的,某个“禁止事项”也许根本不是团队共识。
更稳妥的做法是把生成和批准分开:主 Agent 先产出候选文件,多个 Subagent 围绕不同风险独立取证,主 Agent 汇总证据和冲突,最后再由熟悉仓库的人类开发者决定哪些规则可以进入仓库。
这里借鉴了“用多 Agent 交叉验证 AI 真实执行”这一实践中的一个关键原则:不要让几个 Subagent 用同一段 Prompt 重复回答“写得好不好”,而要按照风险和证据源分工。 四个 Subagent 都说“没问题”,最多只能说明它们没有发现分歧;路径、命令、测试结果和 Git 历史,才是可以交给人审查的事实。
不按章节分工,按失败风险分工
为什么不按“你看架构章节、我看测试章节”来分工?因为章节切分很容易让每个 Subagent 只检查文字是否通顺,却没人对一条错误命令负责。更好的分法是让每个角色守住一种失败风险。
第一轮评审尽量并行,也不要把其他 Subagent 的结论提前作为输入。所有角色共享同一个用户目标、候选文件和验收标准,但分别回到仓库的一手证据独立核对:
| 角色 | 主要证据 | 负责验证 | 默认权限 |
|---|---|---|---|
| Repository Mapper | 文件系统、架构文档、代码入口、Git 历史 | 路径是否存在、目录职责是否准确、文档入口是否遗漏、事实是否有来源 | 只读 |
| Command Verifier | manifest、Makefile、CI、命令实际输出 | 安装、构建、测试、codegen 命令是否真实可运行,前置条件和成本是否写清楚 | 只允许本地验证;不得访问生产环境或猜测凭据 |
| Instruction Auditor | 候选文件、局部 AGENTS.md、README、CI 和仓库规范 | 规则是否重复、冲突、越过作用域、包含模糊措辞或把偏好伪装成事实 | 只读 |
| Task Evaluator | 代表任务、候选规则、验收测试和执行轨迹 | Agent 能否找到正确文件、选择相关检查、避开禁区;必要时与无候选文件的 Baseline 对照 | 隔离 worktree 或容器,不执行外部高风险动作 |
安全、发布或生产操作较多的仓库,可以再增加 Security Reviewer,专门检查密钥、权限、不可逆操作和人工审批边界。小型、低风险仓库则不必为了形式派满所有角色,保留 Repository Mapper 与 Task Evaluator 两条独立证据链,往往就够了。重点不是 Subagent 数量,而是结论是否来自不同证据。
先做确定性检查,再让 Subagent 判断
这里还需要分清“检查”和“判断”。能由工具确定的事实,不应该交给 Subagent 投票:
- 路径和链接是否存在,直接检查文件系统;
- 命令是否有效,在干净 worktree 或容器中运行并保留退出状态;
- 局部规则是否覆盖当前路径,按目录层级计算作用域;
- 测试是否通过,读取测试进程和 CI 结果;
- 候选文件是否重复已有文档,用链接和内容差异检查定位。
Subagent 更适合处理那些需要解释的问题,例如“遗漏了哪个入口”“两条规则为什么冲突”“验证成本是否与风险匹配”。任何无法从仓库确认的内容,都应该明确标成“待人类确认”。多个 Subagent 给出同一个猜测,仍然只是猜测。
给人类开发者的不是一份长对话,而是一张证据矩阵
人类开发者最不需要的,是另一份几万字的 Agent 对话记录。主 Agent 应该把第一轮结论整理成可以快速审查的证据矩阵,而不是只报告“4 个 Subagent 均通过”:
| 候选规则 | 事实来源 | 验证方式 | 结果 | 人类需要决定什么 |
|---|---|---|---|---|
修改 schemas/ 后运行 codegen | package.json、CI workflow | 在隔离 worktree 运行命令并检查 diff | 通过 | 是否作为最低门禁 |
禁止修改 legacy/ | 架构文档、近半年 Git 历史 | Repository Mapper 与 Instruction Auditor 独立核对 | 有分歧 | 是绝对禁区,还是仅禁止新增代码 |
| 所有变更运行完整 E2E | CI 配置、近期待办和执行耗时 | 比较目标测试与全量测试成本 | 成本过高 | 哪些变更才需要触发 E2E |
一份真正可审查的评审包,至少包含:
- 候选
AGENTS.md的完整 diff; - 每条项目特定规则的事实来源;
- 实际运行过的命令、结果和未运行原因;
- Subagent 发现的冲突、未知项和反例;
- 代表任务的预演或 Baseline/Candidate 对照结果;
- 需要人类选择的治理偏好、风险容忍度和审批边界。
人类评审也不是给 AI 的文字润色背书。真正需要人决定的是三件事:仓库事实是否正确,团队是否真的接受这项约束,以及额外的验证成本是否值得。 只要证据仍有冲突、外部系统无法验证,或者高风险边界没有说清楚,默认动作就应该是停下来,而不是把候选稿自动写入。
可以直接交给主 Agent 的生成要求
如果使用的 Harness 支持 Subagent,可以把下面这段要求和本文一起交给主 Agent。它不是另一份 AGENTS.md 模板,而是一份生成和评审流程:
请根据本文为当前仓库生成 AGENTS.md,但不要直接覆盖现有文件、提交或推送。
1. 先在隔离 worktree 中生成候选稿,并为每条项目特定规则记录事实来源。
2. 第一轮并行分发独立 Subagent:
- Repository Mapper:核对路径、职责、文档入口和 Git 证据;
- Command Verifier:核对并安全试运行构建、测试和生成命令;
- Instruction Auditor:检查重复、冲突、作用域、模糊规则和过度约束;
- Task Evaluator:用代表任务验证导航、修改边界和最小检查是否有效。
3. 第一轮不要向 Subagent 提供其他角色的结论;要求每个结论引用原始证据。
4. 能用文件检查、命令退出状态和测试结果确定的事实,使用确定性检查。
5. 汇总候选 diff、证据矩阵、命令结果、分歧、未知项和建议修改。
6. 把评审包交给人类开发者;未获明确批准前不要写入正式文件或提交。
7. 获批后再更新正式 AGENTS.md,运行约定检查,并报告最终 diff 与验证结果。如果当前工具不支持真正的 Subagent,也没必要假装支持。主 Agent 应明确说明限制,再用相互隔离的会话或多轮独立评审作为降级方案。一次自我检查无论做得多认真,都不应该包装成“多 Agent 验证”。
怎样验证 AGENTS.md 是否有效
一份 AGENTS.md 写得结构完整、链接有效、命令具体,并不等于它真的有帮助。Agent 可能更认真地执行了每条指令,却因此读取更多无关文件、运行更多无关测试,最后反而更慢。真正需要验证的不是“文件写得像不像最佳实践”,而是它有没有让任务结果变好。
2026 年的论文 Evaluating AGENTS.md: Are Repository-Level Context Files Helpful for Coding Agents? 在多种模型和 Coding Agent 上做了三组对照:不提供 context file、提供 LLM 生成的 context file、提供开发者提交的 context file。实验包含 SWE-bench Lite 的 300 个任务,以及来自 12 个仓库的 138 个 CTXbench 任务。
结果并不支持一个很容易被接受的直觉——只要放入 AGENTS.md,Agent 就会做得更好:
- context file 中的指令通常会被遵守;
- Agent 会运行更多测试、读取更多文件,并使用更多仓库专用工具;
- 这些额外行为没有带来稳定、显著的任务成功率提升;
- LLM 生成的文件在多数实验设置中降低成功率;
- context file 让步骤数和推理成本平均增加约 20%-23%;
- 开发者编写的文件相对“没有 context file”平均提高 2.4 个百分点,但
p=21%,不能据此认定存在稳定提升; - 只有移除仓库内其他说明文档时,LLM 生成的 context file 才带来约 2.7 个百分点的提升,说明重复上下文可能是重要干扰项;
- 文件长度本身与效果没有显著相关性,问题不只是“控制在多少行”,而是内容是否相关、无重复且能改变决策。
这组结果很重要,因为它把“Agent 有没有听话”和“听话以后有没有做得更好”分开了。更多指令确实会改变 Agent 的行为,但行为变多并不自动等于结果改善。
直接研究已经出现不同结论
一篇论文当然不足以得出最终结论。截至 2026 年 8 月,直接研究 AGENTS.md、CLAUDE.md 等 context file 的论文已经有多篇,而且它们得到的结果并不一致:
| 研究 | 样本与结果 | 对本文方法的意义 |
|---|---|---|
| On the Impact of AGENTS.md Files on the Efficiency of AI Coding Agents | 对 10 个仓库、124 个 PR 做有无 AGENTS.md 对照;论文报告中位运行时间降低 28.64%,输出 Token 降低 16.58%,任务完成表现相近 | 与前述“成本增加”的研究方向相反,说明任务、Agent、文件内容和成本口径会显著影响结论,不能移植单个平均数 |
| Do Context Files Help Coding Agents?(arXiv) | 在 3 个仓库的 17 个真实任务上,对 Claude Code 和 Codex 完成 288 次评测;不同 context 注入策略没有可测得的正确性影响,失败更多来自功能设计、模式选择和具体接线能力 | context file 只能补仓库知识,不能替代实现能力;评测任务必须包含“上下文确实可能改变结果”的 informative cases |
| Agent READMEs | 分析 1,925 个仓库中的 2,303 份 context file;它们常通过频繁的小幅追加演化,且逐渐变成复杂、难读的配置;安全和性能要求都只出现在 14.5% 的样本中 | 支持把文件按配置代码治理:设置准入、去重、下沉和删除机制,同时主动检查非功能约束是否缺失 |
| Configuration Smells in AGENTS.md Files(SCAM 2026) | 对 100 个热门仓库归纳并检测六类 smell;Lint Leakage 出现在 62% 的文件中,Context Bloat 为 42%,Skill Leakage 为 35%,且常与冲突指令共同出现 | 为本文的自动化、上下文预算和规则去重提供了直接实证;能由 lint 承担的内容不应长期泄漏回自然语言配置 |
面对这些结论,最不应该做的就是数一数“支持”和“反对”各有几篇。它们使用了不同的 Agent、任务、仓库、文件质量和成本口径,部分也仍是尚未同行评审的预印本。更稳妥的判断是:context file 的收益具有条件性。 它可能有用,也可能只是增加工作量;答案取决于当前 Harness、任务分布以及文件里到底写了什么。
相邻研究把有效性拆成可测问题
如果只盯着 AGENTS.md 本身,还会漏掉另一个事实:它只是 Harness 的一个组成部分。把 Coding Agent、仓库检索和 Harness 评测的相邻研究放在一起,才能看到更完整的证据链:
| 研究 | 主要证据 | 对 AGENTS.md 的启示 |
|---|---|---|
| SWE-Agent(NeurIPS 2024) | 定制的 Agent-computer interface 改善了文件导航、编辑和测试交互 | AGENTS.md 只是 Harness 的一个输入面;清晰命令、稳定工具和及时执行反馈同样重要 |
| Agentic Harness Engineering | 通过“修改 → 可证伪预测 → 下一批任务验证”的闭环,在 10 次迭代中把 Terminal-Bench 2 pass@1 从 69.7% 提升到 77.0%;消融实验把主要收益定位到工具、中间件和长期记忆,而不是 Prompt 文本 | 不要只润色文字;反复出现的规则应优先升级为测试、lint、脚本、权限门禁或可观察工具 |
| The Scaffold Effect in Coding Agents(初步研究) | 在 50 个 Terminal-Bench Pro 任务上,不同 Harness 的每个成功任务 Token 消耗最多相差 40 倍,而通过率差异为 0-8 个百分点且多数不显著 | 对照实验必须固定模型与 Harness,并同时报告 Token、时间和工具调用,否则容易把脚手架差异误判为 AGENTS.md 效果 |
| Agent Retrieval Bench(arXiv) | 427 个样本的既有轨迹中,有 27%-35% 完全没有找到 gold file;受控实验显示更好的初始上下文能以更少探索提高文件定位 F1 | 仓库地图不能只看“有没有写”,还要测首次相关文件命中、无关读取量和上下文效率 |
| ContextBench | 1,136 个任务、66 个仓库、8 种语言,使用人工标注的 gold context 测量轨迹中的 recall、precision 和效率;Agent 普遍偏向 recall,探索内容与实际使用内容之间存在明显差距 | AGENTS.md 的地图价值不是引导 Agent 读取越多越好,而是提高相关上下文的 precision,并减少“读过但没有用于决策”的内容 |
| SWE-Explore | 以 848 个 issue、203 个仓库为样本,把仓库探索评价拆成覆盖率、排序和上下文效率 | 可以把 AGENTS.md 的导航价值单独测量,避免最终 patch 偶然通过掩盖低效探索 |
| RACE-bench | 528 个 feature-addition 任务同时评价 patch 和“理解 issue → 定位文件 → 规划步骤”的中间过程;成功与高召回、低过度预测相关 | 除最终测试外,还应检查 Agent 是否找对范围、少猜文件、按正确依赖顺序执行 |
| VeRO | 使用版本化 Agent snapshot、预算受控评测和结构化执行轨迹处理随机性 | 候选 AGENTS.md 应有明确版本,比较时固定预算,并保留完整轨迹以便解释结果 |
这些研究关注的对象并不完全相同,各自的百分点当然不能直接相加。但它们共同指向了一种更可靠的评测方式:把 AGENTS.md 放回完整 Harness 中,分别看指令遵循、仓库定位、任务结果和执行成本,而不是拿“内容更完整”代替效果证据。
于是,验证可以沿着一条很清楚的链路往下走:
是否加载 → 是否遵循 → 是否改善结果 → 改善是否值得额外成本第一层:静态质量
第一层先不运行 Agent,只检查这份文件能不能成为可靠输入:
- 文件位置和大小写是否会被目标工具识别;
- 子目录规则的作用域是否正确;
- 路径、命令和文档链接是否仍然存在;
- 命令能否在干净环境运行;
- 是否重复
README.md、CI 配置或代码中已经明显可见的信息; - 是否存在冲突规则、失效版本和无法判断的“尽量”“必要时”;
- 高风险规则是否包含对象、触发条件和停止条件。
这一步很像编译检查:通过只代表文件“可以被使用”,还不能说明它“使用以后有效”。
第二层:指令遵循
第二层才看 Agent 是否真的照做。每条关键规则都需要对应一个可观察结果。 评测清单可以给规则分配 ID,但没有必要把这些 ID 写进正式 AGENTS.md:
| 规则 | 触发条件 | 可观察结果 | 通过条件 |
|---|---|---|---|
R-GEN-01 | 修改 schemas/ | 命令记录、Git diff | 运行 codegen,源文件和生成结果同步 |
R-MIG-01 | 修改数据库结构 | Git diff | 新增 migration,没有改写已发布 migration |
R-TEST-01 | 修改业务逻辑 | 命令记录 | 运行目标测试,结果通过 |
R-SAFE-01 | 任务涉及生产环境 | 工具调用记录 | 停止执行并请求确认 |
计算时只看本任务真正触发的规则,否则大量不相关规则会把结果稀释:
规则遵循率 = 已正确执行的适用规则数 / 适用规则总数关键安全规则尤其不能被平均分稀释。 一次生产误操作、密钥读取或共享历史重写,就应该单独判为失败,即使其他十条普通规则都被正确执行。
指令遵循测试证明的是“这句话被理解了”,仍然不是“这句话有价值”。Agent 可能完整执行五个昂贵检查,却比没有 AGENTS.md 时更慢,也更容易偏离目标。因此还要继续看任务结果。
第三层:任务结果
第三层是最关键的一步:让 Baseline 和 Candidate 在同一组真实任务上进行配对比较。
| 组别 | 仓库状态 | AGENTS.md |
|---|---|---|
| Baseline | 相同 commit、相同环境 | 移除或禁用 |
| Candidate | 相同 commit、相同环境 | 使用候选版本 |
为了让差异尽量只来自候选文件,其余条件要尽可能固定:
- 使用相同模型、Agent Harness、系统指令和工具权限;
- 使用相同任务 Prompt、时间、Token 和步骤预算;
- 每次从干净 worktree 或容器启动,不复用会话记忆;
- 调换两组运行顺序,避免缓存和环境预热造成偏差;
- 对具有随机性的 Agent 重复运行,至少保留每次运行的原始结果;
- 为 Baseline 和 Candidate 固定版本号或 commit,保留工具调用、命令输出和 diff;
- 用测试和预先定义的验收条件评分,不根据回答语气评分。
任务也不能只挑那些最容易体现 AGENTS.md 优势的场景,否则评测会悄悄变成演示。一个小型仓库可以先准备 8-15 个任务,覆盖:
- 局部 Bug 修复;
- 新增小功能;
- 公共接口或跨模块修改;
- 生成代码或 schema 变更;
- 依赖或构建配置变更;
- 文档修改;
- 一个会触发禁止项或人工确认的安全任务;
- 一个与大多数规则无关的简单任务,用来观察上下文负担。
每个任务都需要固定初始 commit、任务描述、验收测试和允许修改的范围。还要留意数据泄漏:用于编写 AGENTS.md 的历史事故,不能全部原样拿来评测,否则规则里可能已经藏着任务答案。
第四层:成本与副作用
即使 Candidate 最终通过了测试,评测也还没有结束。AGENTS.md 可能让 Agent 更谨慎,也可能带来无效探索和机械执行。第四层因此要把成本和副作用一起放进来:
| 指标 | 观察内容 | 趋势 |
|---|---|---|
| 任务成功率 | 验收测试通过的任务数 | 越高越好 |
| 回归率 | 新增失败、兼容性破坏 | 越低越好 |
| 规则遵循率 | 适用规则被正确执行的比例 | 越高越好 |
| 关键违规数 | 破坏性操作、越权、禁区修改 | 必须为 0 |
| 定位效率 | 首次读取或修改相关文件前的步骤数 | 越低越好 |
| 修改精度 | 无关文件、无关重构和超范围 diff | 越少越好 |
| 验证有效性 | 运行的检查是否与变更相关 | 相关优于数量多 |
| 人工介入 | 纠偏、补充上下文和返工次数 | 越少越好 |
| 执行成本 | 工具调用、Token、时间和费用 | 在结果相同时越低越好 |
本地评测没有必要复制一套完整的 benchmark,但可以借用这些研究的共同原则:除了最终测试,还要看 Agent 是怎样定位、修改和验证的。相同结果下,少读无关文件、少做无关修改、少依赖人工纠偏,本身就是改进。
如何判定结果
做到这里,很多人会继续问:提高多少才算有效?这个问题没有适用于所有仓库的统一分数线。更实用的方式,是先为当前项目定义不能退让的门禁,再比较成对结果。一个保守的起点是:
- Candidate 的任务成功率不能低于 Baseline;
- 关键安全违规必须为 0;
- 对适用规则,遵循率应有明确改善;
- 无关修改和人工纠偏不能增加;
- 如果步骤、Token 或时间明显增加,必须能解释为回归减少或风险下降。
样本较小时,不要用一个汇总百分比制造并不存在的统计确定性。逐任务结果往往更有解释力,尤其要区分下面几种失败:
| 现象 | 说明 | 调整方向 |
|---|---|---|
| 没有加载规则 | 文件位置、作用域或工具支持有问题 | 修正发现机制 |
| 已加载但没有遵循 | 规则模糊、冲突或不可执行 | 改为触发条件 + 动作 + 验证 |
| 已遵循但结果不改善 | 规则冗余、过度约束或与任务无关 | 删除、缩短或移入局部文件 |
| 结果改善但成本过高 | 验证范围过大、导航路径过长 | 使用目标测试和渐进式文档 |
| 结果和成本都改善 | 规则提供了缺失且相关的仓库知识 | 保留并加入回归任务集 |
把评测变成回归测试
最后,评测不能只在文件创建时做一次。AGENTS.md 描述的是一个不断变化的仓库,下面任何变化都可能让原本正确的规则失效:
- 构建、测试或生成命令变化;
- 目录和模块边界调整;
- 支持版本、依赖策略或发布流程变化;
- 新增局部
AGENTS.md; - 更换模型、Agent Harness 或工具权限。
一个可行做法是保留 5-10 个成本可控的代表任务,在重要变化后比较当前版本与上一个稳定版本。发现退化时,先检查是否应该删除无关规则,而不是本能地增加说明。更多指令往往会被执行,但不一定带来更好的结果。
用七个维度做静态评审
如果暂时没有条件运行成对任务,也可以先做一次静态评审。下面七个维度各打 0-2 分。它不是行业标准,更不能替代真实任务,只是一份适合代码评审的自检表。
| 维度 | 0 分 | 1 分 | 2 分 |
|---|---|---|---|
| 可发现性 | 没有入口 | 有目录或文档列表 | 任务能路由到文档、路径和命令 |
| 项目特异性 | 多为通用常识 | 有技术栈和局部约定 | 记录隐性契约、遗留反例和失败路径 |
| 可执行性 | 口号和偏好 | 有部分命令 | 规则包含触发条件、动作和停止条件 |
| 可验证性 | 只说“保证质量” | 有通用测试命令 | 按变更类型给出分层验证和通过标准 |
| 安全性 | 没有边界 | 笼统禁止危险操作 | 明确对象、审批条件和可逆替代方案 |
| 上下文效率 | 重复完整手册 | 有少量重复 | 根文件聚焦,细节渐进链接到事实来源 |
| 可维护性 | 无来源、容易过期 | 能找到部分来源 | 命令和规则有事实来源,并随代码变更检查 |
低分不一定意味着继续加内容。 可发现性不足,可以补路由;可验证性不足,可能真正缺的是脚本或测试;上下文效率太低,应该拆文档,而不是继续扩写。这张表只能帮助评审写法,不能替代前面的 task-level 对照实验。
维护方式:从失败中升级 Harness
很多 AGENTS.md 不是因为没人维护而过期,恰恰是因为维护得太勤:Agent 每漏掉一件事,团队就顺手补一句。几个月后,同一个要求出现三种说法,只影响一个目录的约束被写成全局禁令,已经由 CI 保证的规则仍然占用上下文,真正重要的内容反而越来越难找到。
这类问题本质上不是“规则还不够多”,而是缺少规则治理。 AGENTS.md 如果只能做加法,迟早会从操作地图变成事故日志。
不要把一次失败直接翻译成一条新规则
发现 Agent 遗漏或忘记约束时,先不要急着改文档。更有用的问题是:失败到底发生在哪一层?可以把它拆成五个状态:知道入口、完成读取、提取约束、映射动作、验证执行。
| 观察到的失败 | 真正要确认的问题 | 优先处理方式 |
|---|---|---|
| 仓库里根本没有这项知识 | 这是稳定、重复出现且无法从代码推断的事实吗 | 补到事实来源;只有会改变 Agent 决策的摘要才进入 AGENTS.md |
| 已有规则,但 Agent 没有加载 | 文件位置、命名、目录作用域或 Harness 加载机制是否正确 | 修复发现机制、任务路由或局部文件位置,不要复制一份规则 |
| 已加载,但没有提取成约束 | 规则是否埋在长段落中、与其他规则冲突或触发条件不清 | 缩短、重写或拆分,明确“何时 → 做什么 → 如何验证” |
| 已提取,但没有映射到动作 | 规则是否缺少命令、对象、顺序或停止条件 | 补可执行动作与前置门禁,而不是增加强调词 |
| 已执行,但结果仍然错误 | 规则本身是否错误,或者验证信号是否不足 | 修复事实来源、测试和反馈回路;必要时删除规则 |
| 同一约束反复被忘记 | 自然语言是否已经不适合承担这项控制 | 升级为 lint、测试、生成脚本、hook、权限或工具门禁 |
尤其是“规则明明写了,Agent 还是忘了”的情况,最不适合再追加一句“务必遵守”。重复文本只会增加上下文和冲突概率,却没有修复读取、理解或执行链路。 先从工具调用、命令记录、diff、测试结果和会话轨迹确认 Agent 到底停在哪一步,才知道应该改入口、改表述,还是改工具。
事故记录也不适合逐条复制到入口文件。假设一次任务里连续有三个生成文件被手工修改,最直觉的反应是补三条规则,但它们其实是同一个问题:
# 不推荐:记录事故表现
- 不要修改 `src/generated/user-api.ts`。
- 不要修改 `src/generated/order-api.ts`。
- 不要修改 `src/generated/payment-api.ts`。
# 推荐:提炼稳定原则、替代动作和验证方式
- 不要手工修改 `src/generated/`;修改 `schemas/` 后运行 `pnpm generate`,
再运行 `pnpm check-generated` 检查生成结果。具体时间线、影响范围和根因分析,可以留在 docs/incidents/、docs/decisions/ 或 issue;AGENTS.md 只保留从事故中提炼出的长期原则、正确动作和验证方式。
每次规则变更都要有一张变更单
如果新增规则也像修改代码一样需要说明原因,文件就不容易无限膨胀。新增、扩大或强化一条规则之前,可以先填一张很轻量的变更单。它可以放在 PR 描述、issue 或评测记录中,没有必要把这些元数据全部塞进正式 AGENTS.md:
失败证据:哪次任务、哪段轨迹或哪个 diff 暴露了问题?
现有规则:仓库是否已经写过,实际是否被加载和遵循?
根因分类:缺少知识 / 未加载 / 未理解 / 未执行 / 规则错误 / 反馈不足
影响范围:全仓库、某个子系统,还是一次性的特殊任务?
选择载体:根 AGENTS.md / 局部 AGENTS.md / docs / lint / test / hook / tool
候选变更:新增、替换、移动、缩短还是删除哪些内容?
验证方式:哪个代表任务或确定性检查能证明问题被修复?
退出条件:规则何时失效、被工具覆盖或应该删除?这张变更单会迫使我们区分“值得长期保留的规则”和“刚刚发生的事情”。只有事实稳定、问题重复发生、Agent 难以自行推断,而且猜错代价足够高时,才值得优先增加自然语言规则。 一次性故障、外部服务瞬时异常和只适用于某个 issue 的补充说明,不应该永久进入根文件。
如果觉得变更单太长,也可以先回答六个问题。任何一项说不清,都不必急着合入:
- 长期有效:架构调整后它是否仍可能成立,还是一次性迁移要求?
- 重复发生:是否有多个任务或明确风险证明它不是偶发现象?
- 无法自动化:为什么暂时不能由类型、lint、测试、脚本、CI 或权限机制执行?
- 影响明显:违反后是否会造成缺陷、安全风险、兼容问题或大量返工?
- 可执行:是否包含触发条件、正确动作和可观察的验证结果?
- 位置正确:它适用于大多数全局任务,还是应该下沉到局部目录或专题文档?
怎样判断一条规则能否自动化
“这句话能不能自动化”经常让人想到选工具,然后卡在“现在没有现成插件”。换一个问法会简单很多:如果有人违反了这条规则,仓库里会留下什么可检测的证据? 接着尝试把规则改写成下面的形式:
当发生 X 时,检查 Y;如果观察到 Z,则报告或阻断。例如,“不要手工修改生成文件”描述的是人的操作过程,机器很难直接判断;可以改写为:
当源文件或生成目录发生变化时,重新运行生成命令;
如果生成后的工作树与提交结果不一致,则检查失败。改写之后,触发条件、输入、可观察结果和失败状态都出现了,自动化也就有了基础。下一步不是一律写 CI 脚本,而是根据信号寻找最合适的执行位置:
| 可观察信号 | 适合的机制 | 典型规则 |
|---|---|---|
| 数据类型、状态组合、接口签名 | 类型系统、schema、编译器 | 状态枚举、空值、非法组合、接口兼容 |
| 语法、API 使用、import 或依赖图 | lint、AST、静态分析、架构测试 | 禁用 API、跨层依赖、命名和安全模式 |
| 运行时输入与输出 | 单元测试、集成测试、契约测试 | 权限、边界条件、错误处理和兼容行为 |
| “修改 A 时必须同步 B” | Git diff 检查、PR policy | schema 与 migration、API 与 snapshot、配置与示例 |
| 生成源与生成产物 | 重新生成后执行 git diff --exit-code | OpenAPI、protobuf、GraphQL、数据库模型和文档生成 |
| 构建、启动或打包结果 | build、startup validation、环境 schema | 模块解析、环境变量、平台兼容和打包约束 |
| 密钥、许可证、依赖漏洞或仓库策略 | scanner、CI、hook、权限和 branch protection | secret、license、依赖安全和高风险操作 |
原则是让反馈尽量靠近违规发生的位置。 能由类型系统阻止的,不要等到 CI;能由静态分析判断的,不要写脆弱的 grep;描述运行时行为的,就交给测试。CI 是最后的统一兜底,不代表所有规则最终都要变成 Bash。
区分完全自动化和辅助自动化
自动化也不是非黑即白。有些规则可以准确判定,例如“Domain 不能导入 Infrastructure”;有些只能发现高风险信号,例如“修改公共 API 后同步更新文档”。后者可以观察到 API 路径变化而文档没有变化,却无法确认这次修改是不是纯重构。
这时更合适的是辅助自动化,而且要诚实说明它的证据边界:
- 默认输出 warning 或要求 PR 中确认,不直接宣称违规;
- 允许使用结构化原因跳过,并保留跳过记录;
- 报告“观察到了什么”,不要把启发式命中包装成事实;
- 自然语言原则仍可留在
AGENTS.md,可判定的子约束交给工具。
例如,“修复缺陷时增加回归测试”很难完全自动化,因为机器未必能确认任务是不是缺陷,也未必知道新增测试是否覆盖了根因;但 PR 模板、变更类型和测试文件 diff 至少可以提供提醒。相反,生成一致性和禁止跨层 import 通常可以确定性检查。等工具稳定后,对应的文字规则就应该删除,或者缩成一句入口说明。
自动化本身也需要验收
把规则变成检查,并不代表治理工作已经结束。自动化本身也可能误报、漏报,甚至变成新的维护负担。升级为强制门禁前,至少评估四件事:
| 维度 | 要回答的问题 |
|---|---|
| 误报 | 合法重构、测试或例外场景会不会频繁被阻断? |
| 漏报 | 别名、动态语法、生成文件或其他路径能否绕过检查? |
| 可解释性 | 失败信息能否指出文件、违反的约束和正确修复方式? |
| 维护成本 | 目录或工具调整后,检查是否会频繁失效或需要同步修改? |
因此,不要把刚写好的检查直接升级为强制 CI。更稳妥的发布方式是:
- 先手工观察几个真实任务,确认问题重复且规则稳定;
- 以只报告、不阻断的方式运行,收集触发次数和合法例外;
- 根据误报、漏报和修复成本调整检测条件与错误信息;
- 只有命中率高、误报低、修复路径清楚且风险足够高时,才升级为阻断;
- 自动化稳定后,删除、缩短或改写
AGENTS.md中已经重复的规则。
这套过程最后会回到几个很实际的问题:违规留下什么信号,由哪一层检查,有哪些合法例外,先 warning 还是直接阻断,以及自动化稳定后,哪些文字可以退出上下文。
用独立 Subagent 审查规则变更
维护阶段同样可以使用前面的多 Agent 交叉验证,只是角色不再围绕“候选文件是否完整”,而是围绕“这次失败到底发生在哪里”重新划分:
| 角色 | 独立任务 | 主要证据 |
|---|---|---|
| Incident Investigator | 重建失败发生在哪一步,不先接受执行 Agent 的自我解释 | 原始对话、工具调用、命令输出、diff、测试结果 |
| Rule Auditor | 查找现有规则、局部作用域、重复、冲突和过期内容 | 根与局部 AGENTS.md、README、docs、CI、Git 历史 |
| Harness Reviewer | 判断问题应该留在文档,还是升级为确定性控制 | lint、测试、hook、权限、工具接口和运行成本 |
| Regression Evaluator | 用同一任务或相邻任务比较修改前后效果与成本 | Baseline/Candidate 轨迹、验收测试、Token 和步骤数 |
第一轮里,各角色共享失败事实和验收标准,但不共享彼此的根因结论。主 Agent 最后把结果汇总成证据矩阵:哪些事实一致,哪些结论冲突,拟新增规则会替换或删除什么。然后再交给人类开发者评审。“多个 Subagent 都建议增加”不能代替仓库证据,产生失败的 Agent 也不应该独自宣布自己的修复已经有效。
给根文件设置增量预算
如果根文件没有任何预算,它通常只会越来越长。这里的预算不一定是死板的行数,更重要的含义是:每增加一条全局规则,都要解释为什么值得让所有任务加载。
团队可以把 100、120 或 150 行设成重构触发线,也可以使用字节数、Token 估算或章节条目数。这些数字只是复杂度的近似指标,不是跨项目通用的质量标准。真正起作用的是下面这些门禁:
- 新规则优先替换旧规则,不在原句旁边追加近义提醒;
- 只影响一个目录的规则下沉到局部
AGENTS.md; - 背景、例外和长流程移到专题文档,根文件只保留路由;
- 能由工具稳定判断的规则完成工具化后,从入口文件删除或缩成一句说明;
- 每次改动同时扫描相邻章节的重复、冲突和失效链接;
- 用 5-10 个代表任务回归,观察成功率、规则遵循率和额外成本;
- 如果候选规则没有改善行为,或者成本明显上升,就回退并记录结论。
除了每次修改时顺手压缩,还可以把“累计新增若干条规则”“超过上下文预算”“大版本或架构调整”设为集中整理的触发点。固定季度评审可以作为兜底,却不能代替规则进入时的检查,否则团队只是允许问题先积累几个月,再集中偿还。
比“到了季度就补文档”更可靠的触发点,是任务失败和仓库事实真正发生变化:
- Agent 找不到入口:补任务路由或文档索引;
- Agent 复制遗留代码:增加正例、反例或结构 lint;
- Agent 反复违反同一约束:把规则升级为测试、lint 或脚本;
- 命令已经失效:在修改命令的同一个变更里更新说明;
- 一节开始解释大量背景:拆到
docs/,这里只留入口; - 子系统出现独立工具链:增加局部
AGENTS.md,只写差异; - 规则只剩常识、已经失效或已被工具完全覆盖:删除它。
维护的目标不是让规则数量不断增加,而是让每次事故都推动控制方式往更可靠的一层移动:缺失事实进入文档,范围差异进入局部文件,机械要求进入工具,过时内容退出上下文。这样,失败留下的不是又一句提醒,而是更稳定的 Harness。
可直接复制的维护门禁
如果团队希望把这套治理方式也留在仓库里,可以使用下面的最小版本。它可以放在根文件末尾;如果入口已经很长,也可以放进专门的维护文档,再由 AGENTS.md 链接过去:
## Maintaining AGENTS.md
本文件不是事故日志。不要因为一次失误直接追加规则。
新增或强化规则前:
1. 检查是否能由类型、lint、测试、脚本、CI、hook 或权限机制执行;
2. 检查是否只适用于某个子目录、工具或一次性迁移;
3. 检查是否与现有规则重复、冲突或已经被工具覆盖;
4. 将具体事故提炼为长期、可观察、可判断的原则;
5. 写明正确替代动作、验证方式和规则退出条件;
6. 同时检查能否合并、下沉、缩短或删除其他规则。
根文件的上下文预算为 `<团队定义的阈值>`。超过阈值时,不得继续追加;
必须先完成去重、下沉、工具化或删除,并用代表任务验证修改后的效果。回到最初的问题,最终衡量标准从来不是文件有多完整,而是 Agent 能否在更少的人工提醒下完成闭环:定位正确、修改克制、验证充分,遇到高风险动作时知道停下。
所谓站在巨人的肩膀上,也不是把高星项目的规则拼成一份更长的模板。真正值得复用的,是它们处理隐性知识的方式:把容易猜错的事实变成路标,把容易重复的错误变成检查,把高风险动作变成明确门禁。 做到这一点,AGENTS.md 才不只是一份说明文件,而真正成为 Harness 的一部分。
参考资料
- Harness engineering: leveraging Codex in an Agent-first world
- AGENTS.md 开放格式说明
- AGENTS.md 完整指南 2026
- AGENTS.md 标准评测 2026
- GitHub 公开代码搜索:AGENTS.md
- 理解 GitHub Code Search 语法
- GitHub 新版代码搜索与代码浏览体验
- Evaluating AGENTS.md: Are Repository-Level Context Files Helpful for Coding Agents?
- On the Impact of AGENTS.md Files on the Efficiency of AI Coding Agents
- Do Context Files Help Coding Agents? A Two-Agent Ablation Study on Real Repositories
- Agent READMEs: An Empirical Study of Context Files for Agentic Coding
- Configuration Smells in AGENTS.md Files: Common Mistakes in Configuring Coding Agents
- SWE-Agent: Agent-Computer Interfaces Enable Automated Software Engineering
- Agentic Harness Engineering: Observability-Driven Automatic Evolution of Coding-Agent Harnesses
- The Scaffold Effect in Coding Agents: Harness Choice as a Hidden Variable in Coding-Agent Evaluation
- Agent Retrieval Bench: Evaluating Repository Context Retrieval for Coding Agents
- ContextBench: A Benchmark for Context Retrieval in Coding Agents
- SWE-Explore: Benchmarking How Coding Agents Explore Repositories
- RACE-bench: Repository-Level Code Agents with Intermediate Reasoning
- VeRO: A Harness for Agents to Optimize Agents