夜雨聆风学习资料网

ARTICLE · 1127368

AGENTS.md 写4000行没用:源码在场时文档是冗余

AGENTS.md 写4000行没用:源码在场时文档是冗余

📰 科技要闻

• AMD 宣布以约82亿美元全股票交易收购 AI 研究实验室 World Labs,李飞飞将加入担任首席科学家。

• 据报道 OpenAI 以安全顾虑为由暂缓发布最新一代模型(代号 Astra),未给出明确的重新评估时间表。

• Anthropic 传出估值冲击2万亿美元的IPO消息,但报道也指出其2025年营收增长超10倍的同时,训练和推理成本也在同步飙升。

上个月我给团队里新接入的 Coding Agent 项目狂堆了一份 4000 多行的 AGENTS.md,把模块划分、命名规范、历史坑点、甚至某个 SDK 版本号的坑都写进去了。写完挺满意,觉得这下 Agent 该"什么都懂"了。结果实测下来,修复 bug 的准确率跟之前那份 200 行的精简版几乎没差,个别任务反而变慢了——因为 Agent 要先啃完这堆文档才开始干活。

我当时就纳闷了:这不该是越详细越好吗?直到刷到一篇论文,才发现这事早就有人系统测过,而且结论比我想的还打脸。

论文说了什么:把乐高成品拍成说明书

这篇论文叫《Compact Documentation for Coding Agents: A Benchmark, an Optimizer, and Why It Does Not Transfer》,团队问的问题很朴素:文档到底能不能帮 Agent 修 bug?他们的验证方式挺形象——有点像把一套拼好的乐高成品拍照写成说明书,再让另一个人只照着这份说明书把乐高拼回去,拼出来的成品越接近原样,说明这份说明书写得越到位,没漏关键步骤。

往返评测:用"能不能还原代码"打分

落到代码上,思路是一样的:让一个模型(describer)把一段代码写成自然语言描述,再让另一个模型只看这份描述,把代码重新写出来,然后跑原始单元测试。测试通过率越高,说明这份描述的"信息完整度"越高——它没有丢关键信息。  

源代码
↓ describer 生成描述
自然语言文档
↓ 另一模型仅看文档重建代码
✅ 测试通过 → 文档信息完整,没丢东西   
❌ 测试失败 → 文档漏了关键约束/边界条件   

拿这个基准当优化信号跑一轮自优化,最后收敛出"既完整又紧凑"的描述写法,结论很干净:描述的质量由"完整性"决定,不是长度。写得长不代表信息全,写得短也不代表漏东西。这一点我是认的,跟我自己写代码 review 意见的经验一致——啰嗦的评论不代表说到点上。

真正的反转:源码在场时,文档没用

前面这套评测证明了"能写出高质量文档"这件事是可行的。真正的问题在第二步:这种高质量文档,能不能帮 Agent 解决真实仓库里的 issue?

他们在两个模型家族、十个真实仓库上做了大规模测试,还专门设了一个"正对照组"——先证明自己的评测方法在有真实提升的情况下确实能测出来(不然结果是零可能只是评测方法不灵敏)。正对照组的结果证实评测是灵敏的。然后看真正的实验组:

场景
测试通过率
源码缺失,只给优化后的描述
0.08 → 0.71
源码在场,额外附加静态紧凑文档
没有显著提升
源码在场,额外附加检索到的历史任务上下文
没有显著提升
源码在场,文档写得偏长
反而略微变差

意思很明确:当 Agent 能读到源码本身的时候,无论是静态编写的紧凑文档,还是检索增强拿回来的相关上下文,都没有比"直接把 issue 甩给它"效果更好。而这恰恰不是我们平时给 Coding Agent 写 AGENTS.md / CLAUDE.md 的场景,因为大多数时候源码就在仓库里,Agent 完全能读到。

 这就跟给一个已经站在书架前、随手就能翻书的人念摘要一样——他不会因此更懂这本书,只会先浪费五分钟听你念完,然后自己去翻书。源码在场时,Agent 自己读代码得到的信息,比你写的任何摘要都更准确、更新鲜。 

回头看我踩过的坑

说实话,我最开始也不信这个结论——毕竟我们团队一直信奉"给 Agent 的上下文越丰富,效果越好"。但对照自己那份 4000 行 AGENTS.md 的实测数据,其实早就有信号:那份文档里至少 60% 的内容,是在描述 Agent 本来就能从代码里读出来的东西,比如某个类的字段列表、某个函数的调用关系。这部分对 Agent 是纯冗余,甚至可能因为文档和代码存在轻微不同步而互相矛盾,反而误导它。

真正有用的那 40% 是什么?回头复盘发现,全是源码里"看不出来"的东西:

// 好文档:解释"为什么",不是"是什么"// PaymentRepo 必须先写本地DB// 再发网络请求,顺序不能反// 因为断网重试逻辑依赖本地// 状态先落盘,这是2026年3月// 那次资金对不上的事故换来的// 教训,代码本身看不出这层// 因果关系// 冗余文档:Agent 读代码就知道// PaymentRepo.save() 写入// Room 数据库的 payments 表

前者是"隐含约束"和"历史教训",代码里根本不存在这些信息,删掉就真的丢了;后者是"代码结构复述",Agent 打开文件五秒钟就能自己看出来,写文档等于白费功夫,还占上下文窗口。

按这个边界重新拆一遍 AGENTS.md

照着论文给出的边界——"文档只在源码不可及时有用"——反推一下,AGENTS.md 里该留什么、该删什么,其实有一条挺清晰的判断标准:这句话,Agent 打开对应的源文件能不能自己推出来?能推出来的,删;推不出来的,留。

该留
该删
跨模块的隐含调用顺序约束
类/函数的字段与签名列表
历史事故换来的"为什么不能这样做"
模块目录结构说明(能用 tree 看)
外部系统的行为约定(对方接口不会体现在本仓库源码里)
代码风格规范(能用 lint 强制的就别靠文档)
还没写进测试用例的隐藏边界条件
已经在 CI 里跑起来的构建流程细节

我把团队那份 4000 行文档按这个标准砍了一轮,砍到不到 800 行。做了个小范围对照测试,同一批 issue,用砍后的文档跑,修复通过率跟原来基本没差,但 Agent 完成任务的耗时平均缩短了将近三分之一——因为它不用先啃一堆自己能读出来的复述内容。这跟论文里"文档写长反而略微变差"那条完全对得上。

检索增强上下文为什么也没用

论文里还有一条容易被忽略的结论:不光是静态文档,连"检索到的历史任务上下文"(RAG 那一套)在源码在场时也没提升。这个我倒是有点意外,毕竟检索增强这两年被吹得挺神。但细想一下也合理——检索回来的历史上下文本质上还是"关于代码的描述性信息",只是换了个动态检索的壳子。如果 Agent 已经能直接读到源码,这些间接信息提供的边际价值确实有限,甚至可能引入噪音(检索到的历史任务未必和当前 issue 完全对应)。

换句话说,检索增强真正该解决的问题,是"源码在场但太大读不完",而不是"源码在场但理解不了"。这两者是完全不同的瓶颈,前者是上下文窗口容量问题,后者是模型理解能力问题。混着当同一个问题解决,自然事倍功半。

下一步想验证的事

论文的实验场景是"源码完整可及"的仓库级 issue 修复,跟我们平时用 Coding Agent 干的活场景基本一致,所以这个结论我打算认真当回事,而不是当成一篇论文一晃而过。接下来准备做两件事:一是把公司内部几个仓库的 AGENTS.md 都按"能不能从源码推出来"这条标准过一遍,量化对比裁剪前后的任务完成时间和准确率;二是想试试反过来验证论文的正向结论——故意把某个子模块的源码从 Agent 上下文里拿掉,只给优化后的紧凑文档,看看能不能复现论文里那个从 0.08 冲到 0.71 的提升。如果能复现,说明"给 Agent 分层喂上下文"(核心模块给源码,边缘依赖给摘要)这个思路是可行的,那价值就不只是省文档篇幅这么简单了。

相关学习资料