项目规则膨胀,让编程代理启动即超上下文
文章记录了 Claude Code 子代理因启动指令达到 347,814 tokens、超过 200,000 tokens 上限而失败的案例,主会话也被预加载规则占用大量上下文。作者通过 /context 测量并讨论规则膨胀及后续治理。
AI 深度解读
一个只需回答一句文档问题的 Claude Code 子代理,还没开始工作就报错了:请求约 347,814 tokens,模型上限只有 200,000。撑爆窗口的不是问题,而是仓库在每次会话启动时自动塞入的项目规则。
作者对私有项目 DI² 做了测量和改造,把启动时的项目指令从 454,900 降到 64,700 tokens。最有用的发现不是「规则要写短」,而是要分清:哪些内容指导下一步,哪些内容只是记录过去,以及它们分别该在什么时候加载。
为什么还没提问,窗口就占了一半
按作者描述,Claude Code 启动时会加载根目录的 CLAUDE.md、它通过 @ 导入的文件,以及 .claude/rules/ 下没有 paths: 前置配置的规则。导入最多递归四层。这些内容与当前任务无关,问一句文档问题也要支付同样的上下文成本。
作者在 2026 年 10 月 15 日,使用 Claude Code 2.1.145、Opus 5.5 测得:项目指令占 454,900 tokens,加上其他启动内容共 487,500 tokens。对于一百万 tokens 的窗口,开场已经占了约 49%;对于 200,000 的窗口,则是 244%。测量版本还会给自动压缩预留 33,000 tokens。
检查自己的仓库,可以用原文这条命令:
claude -p "/context"
关键是 /context:它按文件报告实际加载量。比较改造前后时,要固定模型和仓库状态。
作者最初也走过弯路。代理把文件字节数除以经验值 3.7,估出了约 244,000 tokens;真正测量后却是 454,900。那批德文 Markdown 混有表格、路径和代码标识符,实测约为每 token 2.0 字节,各文件在 1.9 到 2.2 之间。
模型也影响计数。原文称,Claude 4.7 起使用的新 tokenizer,对相同文本通常比旧版多计约 30%。所以报错中的 347,814 和 /context 的 487,500,不能直接相减解释,它们对应不同请求和 tokenizer。
上下文预算要靠实际计数,文件大小只能帮助定位嫌疑。
真正膨胀的是历史台账,不全是开发规则
最大的测试规则文件占 124,000 tokens,其中约 104,000 来自测试清单。清单有 162 行,每个测试文件一行,记录检查内容、触发它的 bug,以及如何通过反向验证确认测试能抓住问题。最长一行达到 15,129 个字符。
这些信息有价值,但大多数时候不参与下一步决策。
写测试需要知道文件放在哪里、用什么环境、怎么 mock、允许多少执行时间;排查历史问题时,才需要知道某个测试为什么存在。作者把前者称为规则,把后者称为记录。
清单按字节占比计算,占测试规则的 84%。移出后,规则从 124,000 降到 20,300 tokens,节省 103,700。剩下的内容保留了原有约束,并没有靠删掉测试要求换空间。
划分标准也不是「列表都移走」。文件中还有一份已知测试缺口清单,它提醒代理:修改这些位置时,没有测试兜底。这会影响下一步操作,所以仍属于规则。
拆出去同样不能随便读。作者把清单放到 docs/inventories/unit-tests.md,每行开头写测试文件名,并明确要求按文件名搜索。测试规则只留下位置、查询方式和「新增测试必须补一行」的维护义务。
第三个改动也是这个思路:原先创建 bug 的流程会读完整个编号登记表,只为找下一个编号。登记表按编号倒序排列,最高编号就在第一条数据里,于是改成最多读前 30 行;另外两处查询具体记录的流程改用 grep。
把大文件拆成多个 @ 导入没有帮助,因为它们仍会随 CLAUDE.md 一起加载。文件分开了,读取方式也要一起改。
按路径加载能省最多,但新文件可能先写错
作者的仓库有 30 个规则文件,最初只有 3 个使用路径限定,改造后变成 24 个。这一项减少了 264,300 tokens,贡献了总节省量的三分之二以上。
下面是原文的配置,用于把规则限定到相关目录:
---
paths:
- "src/components/**"
- "src/app/**"
- "src/lib/**"
---
要留意每条路径外面的引号。原文实测中,未加引号的 **/*.tsx 被 YAML 当作锚点引用,解析失败后规则反而全局加载;正常使用时没有提示,只有 claude --debug 报出解析错误,而且未指出文件名。
更关键的是加载时机。
作者在 2.1.292 中观察到,路径规则随着匹配文件的工具调用结果才进入上下文。已有文件通常先 Read 再 Edit,规则来得及参与编辑;新文件的 Write 却可能先把内容写下去,规则随后才到。通过 shell 改文件,也不会触发这套加载机制。
2026 年 10 月 20 日的探测进一步显示:2.1.145 的 Write 根本没有加载匹配规则;2.1.301 会加载,但仍在写入之后。另一次运行中,代理看到规则后补改了文件,可这种自我纠正并不稳定。原文称,Write、Edit 的路径规则支持从 2.1.288 开始加入,不能忽略版本差异。
因此,作者保留了三层保障:测试创建和页面骨架规则继续全局加载;生成代码的 workflow skill 在写文件前主动读取相关规范;CLAUDE.md 留下一份规则地图,只列文件和适用范围。地图占 1,800 tokens,自动压缩后也能随 CLAUDE.md 重新读入。
路径还不能绑得过窄。品牌规范最初只覆盖字典等少数文件,但用户可见文案也散落在旁边的文件里,最后扩大到了整个目录。
路径匹配解决的是按需加载,创建前的约束还需要显式安排。
我的判断
这篇最值得采纳的是把规则当成有预算的工程资产。测试越多、事故复盘越完整,记录自然越长;如果每次都把记录塞进全局指令,维护文档本身就会持续抬高启动成本。
但它是一份单项目经验报告。454,900 降到 64,700 是作者用 /context 得到的结果,不能推出普通团队也能省这么多。原文没有提供修改正确率、任务耗时或费用的对照实验,也没证明迁移后所有规则都能稳定生效。
换大窗口确实可以缓解启动失败。作者记录,文档代理在 2.1.292 使用 Haiku 4.5、窗口为 200,000;从 2.1.293 起改用百万窗口的 Haiku 5.5。在 2.1.301 复测旧仓库状态时,485,056 tokens 的请求能够启动。容量门槛变高了,重复加载的成本仍在。
直接压缩规则措辞也有用,但面对 84% 都是历史清单的文件,先改存放位置和查询方式更直接。作者还提醒需要 CI 护栏,不过提供的原文没有展开具体检查方法、阈值或落地结果,不能把它当成已经验证完毕的方案。
能拿来做什么
- 在常用模型下运行一次
claude -p "/context",记录版本、日期和启动指令量,先检查占用最大的几个文件,避免用统一字节换算值代替测量。 - 把测试覆盖清单、bug 历史等记录移到独立文档,在规则中保留维护要求和搜索入口,并让记录能按文件名或编号局部查询。
- 给组件、SQL 等规则配置带引号的
paths:,同时把新建文件前必须遵守的规范留在全局,或由生成流程提前读取;验证时覆盖首次创建文件的场景。 - 检查日常 AI 编程流程里的「读取整个登记表」指令。如果只需要最高编号或一条记录,就明确要求读取前 30 行或搜索目标条目,把读取范围写进流程。