理解债务:AI 写代码的真正代价

HN Claude Code Adoption 2026-08-19T00:53:03.504989

随笔

理解债务:AI 写代码的真正代价

你的代码库里有一个模块,是上个月上线的。它能跑,有测试,也通过了评审。但如果某天凌晨两点它出了问题,团队里没有一个人能说清楚它是干什么的。

在一个以 AI 为核心的代码库里,随便指着某个文件问一句“谁懂这块?”,诚实的答案往往是:没有人。这不是因为工程师变差了,而是因为代码在进入生产环境之前,不再经过人脑了。

解耦

过去七十年里,“代码被写出来”这件事,本身就意味着“有人理解这段代码”。这个隐含关系太过可靠,以至于我们从来没把它当作一种假设:写代码,就是把一个问题理解到足够精确、然后把它表达出来的过程。无论代码写得多烂、文档多缺失,至少总有一个人——作者本人,在写作的那一刻——知道这段代码在干什么、为什么这么写。我们用来让团队在代码库里保持方向感的所有方法,都悄悄建立在这个地基上:评审假设作者能解释自己的改动,新人入职假设有人能讲解系统,调试假设旁边有位同事可以问。

AI 代理打破了这层隐含关系。写代码和理解代码变成了两件独立的事,而且只有前者在规模化。一个 AI 代理一个下午就能产出团队以前要写一个月的东西——但那个下午并不会附带一个月的理解。那层“至少有作者知道”的地基没了:对于代理写的代码,作者不在你的团队里,它根本就不是“某个人”。

代码库“实际做了什么”与“负责它的人类理解什么”之间的差距,需要一个名字,因为没名字的东西没法管理。这个名字已经有了,而且出现有一阵子了。Jason Gorman 在 2025 年 9 月把它命名为“理解债务”(comprehension debt)——指“团队产出代码的速度超过他们理解代码的速度”时发生的事情。随后 Addy Osmani 在 2026 年 3 月把它带给了更广泛的读者,将其定义为“你的系统中实际存在的代码量,与任何人类真正理解的代码量之间,不断扩大的差距”。

我们在同一点上偏离了这两种定义,而这正是这篇文章能写下去的原因。“写得比人理解得快”“真正理解”——这些都是对心智状态的断言,而心智状态是观察不到的。一个无法验证的定义只是措辞,不是工具;措辞在第一次与持怀疑态度的资深工程师争论时就撑不下去。所以下面讲的都是你能实际检验的版本:不是看有没有人理解某个文件,而是看最近有没有人写过、评审过、解释过它。这个说法故意更弱,但也是唯一能拿出工作依据的说法。

为什么“技术债”概括不了这个问题

一个明显的反驳是:代码库积累的问题早就有词可叫了。但技术债(tech debt)按照 Ward Cunningham 提出时的意思,是代码本身的属性——那些走捷径的做法体现在制品里,也能在制品上直接看到。你可以在一个 diff 里明确指出技术债在哪。

理解债则是团队的属性。同一个文件,在一个团队里是零债务,在另一个团队里却是彻底的盲区,一个字符都不用改——因为债不在文件里,而在文件与对它负责的人之间的关系里。这就是为什么技术债的套路对理解债不管用:你无法靠重构来还清理解债。一个完美、整洁、测试充分的模块,如果没人懂得它的内部,它依然是负债——甚至可以说是更糟的负债,因为它看起来毫无问题。

它还颠倒了一般的担心方向。技术债担心的是能跑但写得很烂的代码;理解债担心的是能跑而且写得不错的代码——直到某一天它跑不动了,团队才发现自己原本以为已经具备的理解,其实从来没有被任何人真正获得过。

为什么它一直不被看见

现代工具链里没有任何东西会去度量理解。我们度量覆盖率、复杂度、速度、部署频率、事故数量——代码和流程的每一项属性都在量,唯独人不理解代码这件事,没有任何指标。

我们最接近“度量”的手段是代码评审,而评审从来都不是度量——它只是抽样。它只在合并那一刻、由一个人、检查一次理解程度,然后我们就从“一个人批准过一次”外推出“团队都理解这个”。这个外推从来都是高估。在 AI 原生的吞吐量下,它直接崩塌:当 diff 体积翻三倍、频率翻四倍,评审只会更浅,不会更深。一个四百行 Agent 生成的改动,没有任何评论就批准通过,这不能证明理解。它只能证明吞吐量。

与此同时,我们最古老的团队风险启发式也悄然跌到新的底部。Bus factor——也就是“消失多少人之后,系统就再没人能看懂”——过去的最小值是 1,因为代码总归有人写过。而 Agent 撰写的代码打破了这层地板。确实有人给了提示(prompt),所以人数不是零;但一个“提示了文件、读了一遍 diff”的人,并不是作者,不在那辆巴士上,而且往往根本没有任何其他人。诚实的单位其实是分数,而不是整数——这让让人不舒服,但关键就在这里。一个只数整数的启发式,根本看不见大多数 AI 原生代码实际上处于什么状态。

利息的偿还

和金融债务一样,理解债务背着很便宜,还起来却很凶。持有成本是看不见的:代码能跑,仪表盘全绿,速度看起来很好。利息在特定时刻到期:

有人离职

团队向来会因为有人离开而丢掉一部分理解。而现在,他们失去的可能是最后一个还对代码有理解的人——离职面谈也问不出「所有人都没意识到只有一个人知道」这种事。

新人上手

新工程师都是从懂代码库的人那里学习的。而一个原生 AI 的代码库可以走到这一步:再也没有人可以请教了——代码库的增长速度超过了任何人对它的心智模型。

这些都不是反对 AI 写代码的理由。杠杆带来的增益是真实的,拒绝 AI 的团队会输给拥抱 AI 的团队。问题是:这种杠杆有代价,而现有的工具全都看不见这个代价。看不见的代价不会被管理,只会被事后撞上。

理解真的能衡量吗?

一个合理的反驳是:理解是人脑的状态,而人脑的状态不会出现在 git 里。

对——那就别去衡量理解本身。改而衡量记录,工程领域所有严肃的指标本来就是这么做的。可观察的信号是真实的:一个变更是否被人实质性地审查过(要有评论轨迹,而不是只点了一个「通过」);一个文件最近一次被人认真写过是什么时候;有多少个不同的人真正接触过它。这些都不问「谁知道什么」,但它们全都已经躺在你的 git 历史里了。

真实情况本身也可以验证,但有一个约束——而正是这个约束决定了成败:验证不能自己给自己做。让人说说某个文件在故障时是干什么的,这才是真测试。让人给自己的回答打分,那只是问卷;一份绑定了大家在意数字的问卷,说白了就是可以随意拖动的滑块。答案必须由没写过它的人来评判。

比选哪些信号更重要的,是围绕这些信号的纪律:

理解债务:AI 写的代码真正要付出的代价

逐渐退化:理解会流失

对代码的理解会随时间不断流失。一年前你对某个模块还了如指掌,现在能记住的已经所剩无几——这个指标本身就是最好的证明:理解不是存进银行里的钱,而是需要反复重新挣回来的东西。

由他人验证

任何代理指标最终都会被钻空子——一旦分数变得重要,大家很快就会搞起「表演式评审」来刷评审深度(古德哈特定律保证了这一点)。反钻空子的办法很简单:定期找一个真人,问一个关于代码的真问题。但光问还不够,让答题人自己打分,是这份清单里最容易作弊的一种验证方式,而且作弊的成本为零。真正算数的验证,是让一个没写过这段代码的同事来读、来理解。

怎么应对(有没有工具都行)

不用引入任何新工具,明天就可以开始管理理解债务:

  1. 给 AI 写的代码指定一个人类「记录在案作者」——这个人要把「我能解释清楚这段代码」当作合入代码的一部分,并且明确知道自己接下了这个责任。

  2. 禁止对 AI 提交的 PR 做无实质内容的默许通过。如果评审里没有任何实质性评论,那团队对这段代码的理解程度,就和评审之前一模一样:零。

  3. 把问题当面问出来。在下一次规划会上问一句:「我们系统里有哪些部分,是在座没有人真正理解的?」问完之后的那阵沉默,就是债务自己发出的声音。

  4. 把被点名的盲区写进待办清单——刻意花一小时去啃最难啃的那一块,相当于按白天的价格买下了一份事故响应。

靠手工做不到的事情是:同时看清整个系统的全貌、盯着它随时间变动、以及对自己诚实地承认认知在衰退——就像没人会用电子表格来追踪测试覆盖率,道理是一样的。

查看原文