假设你的代码库里有 3 处写错的错误处理。
人类同事写到第 4 处的时候,code review 会把它拦下来。
AI 不会。它会认定这是你的项目约定,然后一口气写到第 30 处——每一处都工整、一致、通过测试,也每一处都是错的。
模型不是在偷懒。它是在忠实地跟随你代码库里已经存在的东西。

〇、元问题:模型的一致性,是它最大的优点,也是最危险的性质
先说清楚一件事:AI 生成代码时,它做的事情是推断你代码库里的模式,然后复制这个模式。
这在绝大多数时候是你想要的行为。你不希望 AI 每写一个新功能就换一套错误处理风格;你希望它跟随项目约定。所以模型被训练成一个高度一致的模式复制器。
问题出现在一个特定条件下:当它复制的那个模式本身是错的。
Anuradha Weeraman 在《The Compounding Problem》里把这件事说得很准:
模型不是在偷懒。它是在和你给它的代码库保持一致。这正是你希望它做的事——直到它保持一致的那个东西本身是错的。
这句话是整个问题的核心。AI 代码腐烂不是因为模型笨,而是因为模型太一致了。
传统技术债的形成机制是「人偷懒 + 时间压力」。AI 代码债的形成机制是「模型忠实执行 + 传播速度极快」。这两者需要完全不同的应对策略。
一、复制速度打破了「发现窗口」
在传统软件开发里,一个坏模式的生命周期大致是这样:
出现 1 处 → 出现 2 处 → 有人在 code review 里发现 → 讨论 → 制定规范 → 停止扩散
关键在于:人类的复制速度足够慢,慢到留出了发现窗口。
第 2 处、第 3 处出现的时候,团队里总会有人皱一下眉头:“我们为什么要这样写?“这个皱眉的动作,就是技术债的免疫系统。
AI 把这个免疫系统绕过了:
出现 1 处 → AI 在 30 秒内扩散到 30 处 → 已成为「项目约定」→ 修改成本超线性上升
Weeraman 的原文说得很直接:
AI agent 会毫不犹豫地把它扩散到代码库里的三十处,而每多一处,这个模式就显得更根深蒂固、更难回头。
坏模式一旦到了 30 处,它就不再是「一个 bug」,而是「架构」。
这就是「复合」(compounding)这个词的真实含义:不是错误变多了,而是修正的成本随传播数量超线性增长,而传播速度快了一个数量级。
二、为什么 code review 拦不住
标准答案是「加强 code review」。这个答案在 AI 场景下有一个结构性缺陷。
Weeraman 把它叫做 review gap(审查落差):
当一个模型在 30 秒内产出 500 行结构良好、语法正确的代码,认真审查它所需要的认知投入,和它看上去的生成成本完全不成比例。
这里有一个认知不对称:
| 生成成本 | 审查成本 | |
|---|---|---|
| 人写 500 行 | 4 小时 | 40 分钟 |
| AI 写 500 行 | 30 秒 | 40 分钟 |
审查成本没变,生成成本降了 480 倍。
结果是:审查时间在总时间里的占比,从 14% 变成了 98%。这个比例在心理上是不可持续的,人会自然地降低审查强度,尤其是当代码「看起来很对」的时候——语法正确、结构清晰、命名规范、有注释。
一位 HN 用户 @ThePhysicist 描述了真实结果:
我正准备把一个副业项目里好几个月的 LLM 生成代码全部扔掉。我写 design spec 的时候非常小心,而且 LLM 动的还不是一个新代码库。但经过几个月的 AI 改动,我还是觉得我的代码退化了。
注意他强调的两点:他写了仔细的 design spec,而且不是绿地项目。这两个条件通常被认为是「用好 AI」的关键。他都做到了,结果依然是几个月后代码退化到需要丢弃。
另一位 @techpression 补充了一个更微妙的现象:
这和我的经验一致:长期使用之后,会开始出现一种单独看根本看不出来的不一致。
「单独看根本看不出来」 —— 这是 AI 代码债最难对付的地方。每一个 PR 单独看都是合理的。腐烂只在整体上可见,而没有人的日常工作是「审查整体」。
三、模型版本的地质分层
还有一个几乎没人讨论的问题:一个用了两年 AI 辅助开发的代码库,它的不同层是由不同代模型写的。
2024 早期基础模块 ← GPT-4 时代写的数据模型
2025 中间层 ← Claude Sonnet 4.5 时代的业务逻辑
2026 最新功能 ← Opus 5 / Composer 2.5 写的接口层
每一代模型有不同的强项、不同的失败模式、不同的风格倾向。Weeraman 指出这个问题的严重性远超「代码风格不统一」:
这种不一致比风格层面深得多。它是对问题的推理方式的不一致。老模型可能以某种方式误解了需求,而这个误解被固化进了数据模型。新模型把这个数据模型当成既定前提,在一个错误的基础上构建出正确的逻辑。下游的一切在技术上都成立,在根本上都是错的。
这是最难调试的一类问题。因为你去 review 任何一段新代码,它都无懈可击——它正确地实现了基于错误前提的逻辑。错误在前提里,而前提在两年前的一次需求误解里,被固化进了数据模型。
新模型越强,它在错误基础上构建的东西就越精致、越难拆。
四、“让 AI 自己检查"为什么不管用
HN 上有个高赞评论提出了一个很多人在用的方法:
@tim-projects:产品做出来之后,试试这个 prompt:「审查整个代码库,它能上生产吗?我要用 100 万美元把它卖掉,它够得上这个标准吗?」然后你就等着哭——AI 会告诉你,它做的东西跟它之前声称的完全不是一回事。
紧接着两条回复揭示了这个方法的局限。
@KronisLV 的回复:
你用 AI 生成代码,你让它生成代码,它就生成了。不管你写多少遍「你是一个专家开发者」或者「不要犯错」,都改变不了这个根本。
@geraneum 说得更精准:
然后你让它修。等它说「修好了」,你再问一遍同样的问题——你会得到一份差不多的回答。
这是一个无限循环。因为「找问题」和「修问题」用的是同一个模式匹配器。你让它找问题,它生成一份看起来很专业的问题清单;你让它修,它生成看起来修好了的代码;你再问,它再找出一批新问题。
这个循环永远不收敛,因为它缺少一个外部的、不可被模型说服的判据。
那个判据必须来自代码之外。
五、可以真正起作用的三件事
Weeraman 给出的核心原则是 curation(主动策展):你必须持续地修剪和纠正代码库,因为在 AI 辅助的项目里,延迟维护的成本增长速度比传统项目快得多。
具体到操作层面,有三件事的性价比最高。
1. 端到端测试必须先于任何重构
这是 Weeraman 强调的第一条,理由很关键:
AI 生成代码上的单元测试,往往测的是实现而不是意图,因为代码和测试都是同一个模型写的,它让两者互相吻合。
测的是它自己的实现,不是你的意图。 代码和测试都是它写的,必然互相吻合。这种测试通过了,什么都没证明。
端到端测试不同:它在系统边界上验证用户可见的行为。这个判据在模型之外,模型无法通过「调整实现」来让它通过。
Weeraman 的建议是:自己写这些测试,或者至少自己写测试规格并亲自审查。
2. 把「坏模式检测」变成定期动作,而不是 review 时的偶然发现
既然 code review 在认知上顶不住 AI 的生成速度,就不要指望它。
改成主动搜索:定期在代码库里搜索重复模式的实例数量。如果某个模式出现了 15 次,问一个问题:这是我们决定的约定,还是 AI 推断出来的约定?
区分这两者,是控制 AI 代码债最有效的单点动作。
3. 记录数据模型的决策理由,而不只是数据模型
模型版本地质分层最危险的部分是「被固化进数据模型的需求误解」。防止它的唯一方法,是让数据模型的理由是可查的。
不是 schema 文档,是决策记录:这个字段为什么这样设计,当时的约束是什么,被拒绝的方案是什么。
这样当新模型在这个基础上构建时,你有机会发现前提已经不成立。
总结
| 机制 | 传统代码债 | AI 代码债 |
|---|---|---|
| 坏模式传播速度 | 慢,留出发现窗口 | 快,绕过发现窗口 |
| 审查/生成成本比 | 约 1:6 | 约 80:1 |
| 腐烂可见性 | 单个 PR 可见 | 只在整体可见 |
| 不一致的层次 | 代码风格 | 对问题的推理前提 |
| 有效的免疫系统 | code review | 端到端测试 + 主动模式审计 |
回到那场没人吵赢的争论。
「AI 能不能写生产代码」这个问题问错了,因为它把 AI 当成一个静态的质量水平在评估。而真实的问题是动态的:AI 的核心优点(模式一致性)在时间维度上会变成它的核心风险,而现有的工程免疫系统(code review)恰好是被这个风险绕过的那一个。
AI 代码腐烂不是质量问题,是速度问题——坏模式的复制速度,第一次超过了人类发现它的速度。
🔍 如果你在维护一个 AI 辅助开发的代码库——
- 你的项目里有多少「约定」是团队定的,多少是 AI 推断出来的?
- 你的测试是在验证用户行为,还是在验证 AI 自己的实现?
- 你的数据模型有决策记录吗,还是只有 schema?
📬 关注梦兽编程,获取更多 AI 工程实践的深度分析。
参考来源:
- Anuradha Weeraman:The Compounding Problem: Why Your AI-Generated Codebase Is Quietly Deteriorating
- Anuradha Weeraman:The Prototype Isn’t the Product
- HN 讨论:AI doesn’t generate working products, that’s still your job

