为什么一个巨型指令文件会拖垮你的 Agent

600 行的 CLAUDE.md 是自我强化的失败循环,拆成入口加分册才是解药。

Module C · 第 3 讲

立靶:文件越大,Agent 越笨,这是一个会自我强化的循环

你给 Agent 写了一份 CLAUDE.md。第一周它 80 行,跑得挺好。于是你不断往里加:又踩了个坑,加一条;又定了个规范,加一条;某次方案讨论的结论,也顺手记进去。三个月后它 600 行了——然后你发现 Agent 开始忽略你白纸黑字写下的硬约束。

这不是错觉,而是一个自我强化的失败循环

  • 文件越大 → 吃掉的 context 预算越多 → 留给实际任务的注意力越少 → Agent 表现越差
  • Agent 表现越差 → 你越想「再写一条说明它就懂了」→ 文件继续变大 → 表现继续变差

walkinglabs 的 Harness Engineering 把这条循环点破:把所有指令塞进一个大文件,是新手做 Agent 工程最常见、也最隐蔽的反模式。 隐蔽在于,它在小规模时完全无害,等你发现不对劲时,文件已经大到「不敢动」了。

框架:巨型指令文件的四个失败机理

把它们并排放,你会发现这四个问题互相喂养——不是四个独立 bug,而是同一个病灶的四张脸。

机理现象为什么致命
① context 预算耗尽一个臃肿文件吃掉 10–20K token,每一轮对话都重复加载这部分 token 每轮都是固定开销,挤占任务、检索结果、对话历史的空间
② lost in the middle长文本中段的利用率显著低于开头和结尾关键硬约束如果埋在第 300 行,模型读得到但「看不见」——优先处理首尾,中段被系统性稀释
③ 优先级糊成一锅硬约束、设计建议、历史注记用同一种格式平铺模型无法区分「绝对不能违反」和「可以参考」——一条铁律和一句随手记的 TODO 长得一模一样
④ 维护腐化增加一条无成本,删除一条有风险(怕删错),于是文件只增不减熵单调增加。没人敢删的文件,最终变成所有人都不读、Agent 也读不进的「考古地层」

四者的合力:①让有效注意力变少,②③让仅剩的注意力还用错地方,④保证情况只会越来越糟。这就是为什么「再加一条」永远治不好病——你是在给一个已经溺水的人灌水。

框架:文件柜——入口文件 + 专题分册

walkinglabs 给的解药是一个生活比喻:文件柜。你不会把内衣、洗漱用品、文件、药品全堆进一个箱子,然后每次找东西都翻到底。你会分抽屉。Agent 的指令也该如此——入口文件只放「永远要看」的,专题分册按需拉取。

指令文件柜:入口 AGENTS.md(≤200行常驻)链接到 docs 各分册,按需拉取
指令文件柜:入口 AGENTS.md(≤200行常驻)链接到 docs 各分册,按需拉取
层级文件行数装什么不装什么
入口(抽屉柜的标签)AGENTS.md / CLAUDE.md50–200项目概览 + 启动命令 + ≤15 条硬约束 + 指向分册的链接详细方案、历史决策、长清单
专题分册(各个抽屉)docs/ 下每个文件50–150单一主题的细节(如部署、数据模型、某子系统约定)与本主题无关的任何内容

两条数字纪律是关键:入口 ≤ 200 行、硬约束 ≤ 15 条。超出就说明你把不该进入口的东西塞进来了。入口文件的职责不是「说清一切」,而是「告诉 Agent 去哪儿找清楚一切」。

这正好接上上下文工程的视角:入口文件是每一轮都固定加载、应当 100% 命中 prompt cache 的部分;专题分册更像按需拉取的检索/记忆,不占每轮固定预算。把分册塞回入口,等于把本该 lazy 的东西改成 eager,白白烧掉每一轮的 token。

case:一份「不堆一起」的入口文件实例

这门公开课项目,入口文件就是按文件柜架构写的。它没有把需求、方案、架构、进度全堆进 CLAUDE.md,而是做了两件事:

第一,用「入会顺序」代替「全文背诵」。 入口文件开头不是一长串规则,而是一份读取顺序清单:

1. 先读 STATUS.md(一句话状态 + 下次入口 + 踩坑清单) 2. 再读 PRD.md / SPEC.md / architecture.md / features.json 3. 开工前跑 bash M1/init.sh 确认环境全绿

这等于把抽屉的「打开顺序」写在柜门上。Agent 不需要在入口文件里读到需求细节,它只需要知道「需求在 PRD.md,要看去那儿拉」。需求、方案、架构各自是一个分册(三件套),进度是另一个分册(STATUS.md),互不污染。

第二,入口只留「每轮都要的硬约束」,细节全部外链。 视觉规范在入口只有一句「橙皮书风 + 禁 emoji + 图标用 line-SVG」,完整视觉系统在 assets/ 的 CSS 里;讲义体的硬规矩在入口一行带过,schema 细节在 SPEC.md

对照四个失败机理,这套结构逐条拆弹:对①入口短,每轮固定开销小;对②硬约束集中在短文件里,没有「中段」可埋;对③入口里出现的就是硬约束,格式上天然区分于分册里的建议/细节;对④删除分册的某条细节,影响面被锁在那个分册内,你敢删了。

一个反向教训:某 SDK 默认 setting_sources=['user','project'],会偷偷~/.claude/CLAUDE.md(约 17K token 的暗物质)注入每一轮。这是「巨型文件失败」的隐身版——你的入口文件明明很干净,但框架在背后帮你堆了个 600 行进去。设 setting_sources=[] 后,纯文本轮从 4.5s 降到 2.4s。机理①不只来自你写的文件,也来自 SDK 替你加载的文件。

可操作做法:从巨型文件到文件柜的迁移清单

  1. 先量,再拆。 拆之前跑一次「上下文体检」:打印入口文件实际占多少 token,顺手审 SDK 有没有偷塞(setting_sources 这类暗默认)。没有数字就别凭感觉拆。
  2. 画一张上下文构成表。 把入口文件里每一段标三列:来源 | 每轮是否必看 | 该进入口还是分册。「每轮必看的硬约束」留入口,其余全部标记外迁。
  3. 按主题切分册,每册 50–150 行。 判据是「找这类信息时会不会一起找」——会一起找的放一册,不会的拆开。
  4. 入口瘦身到 ≤200 行、硬约束 ≤15 条。 超出的问自己:这是「每轮都要遵守的铁律」还是「需要时才查的细节」?后者一律外链。
  5. 用「读取顺序」替代「全文罗列」。 入口开头写一份入会清单,告诉 Agent 先读什么、去哪儿拉细节。
  6. 给硬约束一个视觉锚点。 把 ≤15 条硬约束集中成一个带标记的列表,让它们在格式上明显区别于建议。
  7. 立一条维护纪律对抗机理④:增加分册细节无需谨慎,但任何内容进入口必须过一道「这是否每轮都要看」的闸门。把「删除有风险」转成「进入有门槛」。

收口

巨型指令文件的失败,不是因为你写得不够多,恰恰是因为写得太多——Agent 的注意力是一笔固定预算,你往入口里多塞一行,就是从任务身上扣一行。

好的指令架构,是一个标签清楚的文件柜,不是一个塞满的箱子。入口只回答「去哪儿找」,专题分册回答「具体怎么做」。