
AI 编程越改越慢?用 IRV 思路压缩每次改动前的阅读量
AI 编程越改越慢?用 IRV 思路压缩每次改动前的阅读量
AI 编程助手在项目变大后变慢,往往不是模型退化,而是每次改动前要读的东西变多了。这篇教程把「一个 Issue 需要 AI 读懂的信息量」称为 IRV,讲清它为什么会膨胀,并给出三条可落地的整理手法、一份 Issue 收尾检查清单,以及一段可以直接交给 AI 代理的指令模板。
用 AI 改一个 bug,本来以为几分钟就能结束,结果它先打开一堆文件,在同一个位置反复搜索,最后回一句「影响范围比较广,需要先确认」。项目刚起步时同样的请求快得惊人,代码量涨上来之后却越来越慢,偶尔还会改错地方、碰坏无关逻辑。这通常不是模型本身退化了,而是 AI 在动手之前必须读懂的信息变多了。
这篇教程把「为了完成一个 Issue,AI 在改动前需要读懂的信息量」称为 IRV(Issue Reading Volume)。名字是新的,盯的却是工程里很老的一件事:一次改动之前的调研范围。目标很明确——让每次改动所牵动的理解范围保持得足够小,从而把 AI 编程的速度找回来。适合已经在项目里用 AI 代理写代码、并且感觉到「越用越慢」的开发者阅读;如果你还没遇到这个问题,也可以把它当成一套提前整理代码结构的思路。
准备工作
这套方法不需要额外安装工具,也不需要接入任何监控系统。开始之前,先确认下面几件事:
- 一个正在使用 AI 代理的项目:无论是命令行里的编码代理,还是编辑器内置的助手,只要它能读文件、能改代码、能跑测试即可。
- 一个具体的 Issue:不要拿「重构整个模块」这种模糊目标练手,选一个边界清楚的小任务,比如修一个 bug、加一个小功能。
- 能查看 AI 读了哪些文件:多数代理会输出它打开、搜索、编辑过的文件列表,或者至少能在会话记录里看到。这是后续复盘的全部依据。
- 一份测试:哪怕只有几条,也要有。没有测试就无法判断「少读一点」之后改动是否仍然安全。
- 一个记录的地方:Issue 评论、笔记文件都行,用来写下这次调研扩散到了哪里。
关于工具本身的版本、价格、配额和可用地区,各家变化很快,请以官网当前信息为准,这里不做列举。
操作步骤
第一步:先看清 IRV 到底包含什么
IRV 不是「代码行数」,也不只是源码。它统计的是为了理解、修改并确认安全而读过的全部材料。大致可以分成四类:
| 类别 | 具体内容 |
|---|---|
| 源代码 | 实现、类型定义、配置文件 |
| 测试 | 单元测试、集成测试 |
| 规格 | Issue 正文、验收条件 |
| 说明材料 | README、设计笔记、开发约定 |
举例来说,某次修 bug 读了 1200 行源码、500 行测试、300 行规格与说明,那么这次 Issue 观测到的 IRV 就是 2000 行。一开始不必精确统计行数,先记录「读了几个文件」「调研扩散到了哪几个功能」就已经很有用。
这里有一个容易混淆的点:IRV 和代码库整体规模是两回事。 一个百万行的系统,如果一次改动只需要在 5 个文件里就能判断清楚,调研范围依然很小;反过来,一个一万行的小系统,如果同一条规则散落在 10 个地方,每次改动都要读一大堆文件。要压小的不是代码库,而是「一次改动所需的理解范围」。
第二步:判断 IRV 为什么会膨胀
用一个聊天应用的例子最直观。开发初期,AI 收到「修一下消息发送的 bug」,需要读的只有发送处理和对应测试,信息量少,很快就能进入修改。
几个月之后,同一个项目里陆续加上了:发送失败重试、重新打开页面时的重连、防止重复发送、按用户的用量限制、计费与审计日志、旧版本兼容。此时同样是「修消息发送」,AI 必须先确认一大串事情:
| 确认项 | 开发初期 | 功能变多之后 |
|---|---|---|
| 要读的处理逻辑 | 发送处理 | 发送、重试、保存、计费等 |
| 状态存放位置 | 基本只有一处 | 多处都会更新 |
| 测试 | 几条 | 牵动多个功能 |
| AI 的动作 | 直接改 | 先探索、先确认影响面 |
功能变多本身不是问题。真正的问题是:为了判断一次改动,必须把相关功能内部全部读一遍。 当同一条规则的知识散落在发送处理、重连处理、状态管理、保存处理、计费处理里,AI 就得读完五个功能,再自己把关系拼回去。这种状态可以称为「知识碎片化」——像硬盘上一个文件被拆成很多块,读取时自然要多花时间。
那是不是把所有东西塞进一个巨大的文件就好了?不是。关键不在文件数量,而在于这条规则由谁负责管理是否清楚。
第三步:用三条手法压缩 IRV
手法一:给规则指定唯一的负责人。 先确定「这条规则归谁管」。以上面的例子来说,把「判断两条消息是否相同」的职责收拢到一个去重组件里,不要让发送界面、重连处理、计费处理各自维护一套判断方式。这样 AI 第一次要确认的位置就变得明确,调研的入口也好找。
手法二:把组件之间的约定写出来。 光看函数名和参数,有时判断不出能不能安全调用。以保存处理为例,把下面这些约定写清楚:
- 同一份数据再发一次会怎样
- 同时发两次会怎样
- 失败之后能不能重试
- 成功的那一刻,数据已经保存到什么程度
这些约定就是「契约」。契约写清楚了,AI 就不必读保存处理内部的细节就能使用它。把验证契约的测试放在旁边,判断会更省力。
手法三:把「因为同一个理由而变化」的知识聚到一起。 经常一起改的规则,放在能一起找到的地方;而像计费和界面展示这种因为不同理由而变化的,就分开。两者之间用上一步的契约连接起来。
| 状态 | AI 需要确认的内容 |
|---|---|
| 整理前 | 读多个功能,从中找出隐藏的规则 |
| 整理后 | 读要改的那个功能,加上对方的契约 |
按「变化理由」重新组织知识,这一步可以理解为「知识整理」。它不减少文件总数,但能显著缩小一次改动需要读懂的范围。
第四步:给 AI 代理一段明确的指令
日常使用的编码代理,可以直接把下面这段要求交给它:
开始修改之前,请先确认:
1. 管理这条规则的位置在哪里
2. 管理相关状态的位置在哪里
3. 与其他组件之间的契约是什么
4. 用来验证正确行为的测试在哪里
5. 最开始必须读的最小范围是什么
如果调研扩散到了别的功能,请记录扩散的原因。
完成时请告诉我:
- 下一个类似的 Issue 里,哪些内容可以不用再读
- 这次新增加了哪些必须理解的内容
注意,这不是「限制阅读量」的指令。必要的调研照做,只是要让「范围为什么扩大」变得可见。
第五步:在 Issue 收尾时做一次复盘
不需要搭建复杂的度量系统。只挑一个 Issue,做完之后回答下面几个问题:
- 这次改的是哪个功能?
- 管理这条规则和状态的位置在哪里?
- AI 读了哪些源码、测试和规格?
- 调研扩散到别的功能,原因是什么?
- 下一个类似的 Issue 里,有什么可以不用再读了?
调研扩散的常见原因包括:规则分散、状态归属不明、组件之间的契约不清、测试和规格的入口不好找。当然,也有 Issue 本身就确实横跨多个功能的情况。
复盘时看的不是「减少了几个文件」,而是下一个类似的 Issue 里,有什么不用再读了。
一个完整示例
把上面的步骤串成一个最小可跑通的流程。假设项目里有一个聊天功能,现在要修「同一条消息被保存两次」的 bug。
整理前。 去重判断散落在三处:发送界面里比较一次、重连处理里比较一次、计费处理里又比较一次。AI 接到任务后,需要打开这三个功能,还要读状态管理和保存处理,才能确认哪一处才是真正的判断逻辑。测试分散在多个文件里,规格只写在 Issue 正文里。这次调研读了 6 个文件。
动手整理。 把「判断两条消息是否相同」抽成一个去重组件,三处调用方都改成调用它。然后为这个组件写下契约:
去重组件契约
- 输入:消息标识、发送方、时间戳
- 同一标识重复提交:返回「已存在」,不写入
- 并发提交同一标识:只有一次写入成功,另一次返回「已存在」
- 写入失败:可以重试,重试不会产生重复记录
- 成功返回时:数据已持久化,可被后续读取
把验证这份契约的测试放在组件旁边,覆盖重复提交、并发提交、失败重试三种情况。
整理后。 再次接到同类 bug,AI 的路径变成:先读去重组件的契约,再读调用它的那个功能,然后跑组件旁边的测试。它不需要再打开计费处理,也不需要读保存处理的内部实现。这次调研读了 2 个文件。
复盘记录。 在 Issue 里写下:本次改动涉及发送功能;规则由去重组件管理;AI 读了去重组件、发送处理及其测试;调研没有扩散到计费;下一个类似 Issue 里,保存处理和计费处理都可以不用再读。
这个例子里真正的收益不是「文件从 6 个变成 2 个」,而是下一次遇到同类问题时,有一整块代码可以确定不必打开。
注意事项
IRV 不是越小越好。 读得少却漏掉 bug 或安全问题,不能算改进。下面这些做法要避免:
| 错误做法 | 会引发的问题 |
|---|---|
| 把所有东西塞进一个巨大文件 | 不同规则混在一起,反而更难改 |
| 删掉注释和规格 | 数字是降了,理解难度却上升 |
| 给阅读量设上限 | 连必要的影響确认也被打断 |
| 把大量调研藏给另一个 AI | 整体读取成本并没有减少 |
| 省略测试 | 看起来快了,质量却下降 |
故障排查、安全相关的改动,本身就需要很宽的确认范围。目标不是「最小的 IRV」,而是:为了安全地完成改动,该读的信息读到,无关的内部细节不必读。
统计口径上还有几个细节值得注意。 同一个文件被反复读取时,要把「去重后的量」和「累计读取量」分开记录;一个 Issue 被拆成多次会话时,按 Issue 为单位合并;日志里无法还原的读取,记成「不明」而不是 0。
不要用 IRV 单独判断生产力。 它要和解决率、耗时、成本、评审负担放在一起看。重构之后,要用单元测试、集成测试和回归测试确认行为没有变化。
IRV 的定位要说清楚。 它是本文提出的一种称呼和观察框架,不是标准化指标,也不存在「IRV 小就一定生产力高」这样的结论。Issue 的难度、使用的模型、工具链、测试耗时都会影响开发速度。
最后,不必一开始就精确统计行数。下一个 Issue 开始时,先把 AI 打开过的文件列出来;结束时只问一句:下一个类似的 Issue 里,有什么可以不用再读了? 反复问这个问题,项目变大之后,AI 和人都会少迷路一些。