跳到主要内容

代码所有权衰减:当 AI 编写大部分提交时,团队知识会发生什么

· 阅读需 11 分钟
Tian Pan
Software Engineer

当生产环境出现 Bug 时,第一个仪式总是相同的:打开 git blame,找到写下那行代码的人,问他们为什么要这么写。这个仪式假设作者是有原因的——他们知道的某个限制、刻意处理的边缘情况,或者从三个季度的复盘报告中内化而来的业务规则。在软件史的大部分时间里,git blame 回答的是关于意图的问题。

现在,对于比例日益增长的提交,git blame 指向的是合并代码的人和生成代码的 AI。人类可能只花了 90 秒阅读 diff。而 AI 除了 prompt 之外没有任何上下文。那些让 git blame 变得有用的“为什么”——即组织知识——从未在任何地方被记录下来。

这就是代码所有权衰减。它不会自我宣告。没有哪一个单一的提交会破坏系统。相反,理解力会慢慢被掏空,直到团队到达一个决策点——一次重构、一次事故或一名新员工入职——才发现再也没有人能从内部解释这个系统了。

Git Blame 究竟在衡量什么

Git blame 始终是一个代理指标。真正的问题不是“谁写了这段代码?”——而是“谁知道这段代码为什么存在?”当写下那行代码的人也是对代码进行推理、辩论替代方案并记住上下文的人时,这两个问题之间存在着可靠的相关性。

这种相关性正在瓦解。被重构的代码行占所有变更的比例从 2020 年的 24% 下降到 2024 年的 10% 以下。同期,代码流失(Code churn,即编写后两周内被修改的代码行)几乎翻了一番。这种模式表明,开发人员正处于与 AI 的快速生成循环中——生成、丢弃、再生成——而没有建立起能够支撑后续深思熟虑改进的理解力。

当你对 AI 密集的代码运行 git blame 时,你看到的是合并者。你没看到的是,合并者可能在 15 分钟内审查了 800 行生成的内容,因为测试通过了就予以批准,而对代码实际执行的操作基本上没有留下任何心智模型。归属是准确的;但暗示的知识传递从未发生。

试图解决这个问题的工具——跟踪哪种模型、哪个智能体、哪个会话产生特定代码行的系统——解决了归属差距,但没有解决理解差距。知道 Claude 3.7 在 45 分钟的智能体任务中生成了第 847 行,并不能告诉你代码旨在保留的“不变性”(invariant),也无法告诉你曾考虑过并被拒绝的替代方案。

作为社交虚构的 PR 审查

Pull Request (PR) 审查过程依赖于一种社会契约:审查者阅读代码,理解到足以对其进行评估的程度,然后批准或要求修改。当 AI 生成代码时,这种契约会以一种特殊的方式瓦解。

开发人员知道代码何时来自 AI。审查者也知道。在这种共同认知中,一种新的动态出现了:审查者不提出澄清性问题,不是因为代码显然正确,而是因为提问就等于承认自己看不懂——这暗示了代码太复杂,进而暗示了开发人员生成了自己都不理解的东西,而没人愿意揭穿这一点。双方都有动力将审查视为一种形式。

缺陷数据让这一点变得显而易见。AI 参与编写的 PR 包含的问题大约是人类编写的代码的 1.7 倍。与基准相比,AI 参与的 PR 中的关键问题增加了 40%。审查时间增加了 91%——不是因为审查者阅读得更仔细了,而是因为即使你没有深入评估,不熟悉的模式也需要更长的时间来扫描。审查者花的时间更多,理解的却更少。

这造成了一种特定的失败模式:如果有人理解代码就能发现的 Bug 进入了生产环境,引发了事故,而当你进行复盘时,你发现审查链中的任何人都无法解释这段代码原本应该做什么。审查发生了,理解却没有。

组织知识无法在 Prompt 中存活

每个团队都拥有不在代码库中的知识。两年前发生的并发 Bug,以及那个看起来有误但解决了仅在凌晨 3 点复现的竞态条件的修复方案。那个看似冗余的数据库索引,但其实是因为一个报表查询每周日都会拖垮生产环境才存在的。API 客户端之所以重试 3 次而不是 5 次,是因为上游供应商的速率限制非常激进,曾一度将他们限制到长达 45 分钟的停机。

这些知识存在于亲历者的脑海中。它在代码审查中表现为莫名其妙的意见(“我们这里不那样做”),出现在事故复盘中,也出现在有人说“我们以前尝试过这个”的架构讨论中。这就是“维护系统的团队”与“仅拥有代码的团队”之间的区别。

AI 助手不承载这些知识。它们承载的是训练数据。当工程师通过 prompt 寻求解决方案时,模型提出的代码在语法上是正确的,可能处理了常见情况,但对团队特定的失败历史完全一无所知。在那工作了五年的工程师原本能立即发现问题。但如果那个工程师在一个 sprint 中要审查 200 个 AI 生成的 PR,而不是自己写代码,他们就会变成粗略浏览而非深入阅读——于是组织知识永远无法得到应用。

Anthropic 的研究发现,使用 AI 辅助的参与者完成任务的时间与对照组相同,但在随后的理解评估中得分低了 17%。下降幅度最大的是调试能力——而这正是当凌晨 2 点出现问题,你正在追踪一段在编写时就没人完全理解的代码时所需要的技能。

在 AI 密集的团队中,定义标准、捕捉架构偏差并通过代码审查进行教学的高级工程师成了组织知识唯一的传播机制。他们原本就是瓶颈。而现在,他们成了唯一关键的瓶颈。

积累问题

单个 AI 生成的 commit 并不是问题所在。问题在于一个八人团队在 12 个月内积累的代码量。

在 2021 年至 2024 年间,重构在所有代码变更中所占的比例从 25% 下降到不足 10%。代码重复率翻了四倍。代码行数在增加,而每位工程师对代码的理解深度却在下降。你最终得到的是一个增长速度超过任何人理解速度的代码库,其中无人深读的代码浓度越来越高。

这给新员工入职带来了特定的风险。传统上,阅读系统的 git 历史是了解其演进过程的最佳方式之一——解决了什么问题、做了哪些权衡、团队是如何思考的。充斥着 AI 生成内容的 git 历史无法传递这些信号。它展示的是一系列由测试通过点缀的生成事件流。历史确实存在,但其中嵌入的推理过程却消失了。

同样的风险也出现在故障排查中。有效的根因分析依赖于有人足够了解代码,从而能够推断代码原本应该做什么以及在哪里偏离了预期。当“谁理解这个组件”的诚实回答是“没有人从推理的角度写过这段代码”时,故障解决就变成了探索性的,而非诊断性的。

真正有效的做法

在那些能够管理好这一问题(而不是在宕机后才发现问题)的团队中,正在涌现出三种实践。

将架构决策记录(ADR)作为 AI 治理上下文。 在 AI 编程助手出现之前,ADR 就已经很有用了。现在,它们变得至关重要。当你的 ADR 存在于代码仓库中时,它们不仅仅是文档——它们是可以直接输入到 AI 编程工具中的治理上下文。这创造了一个反馈循环:工程师写下架构决策的“原因”,AI 工具利用这些决策生成尊重架构意图的代码,从而缩小生成代码与团队标准之间的差距。在引入 AI 之前就投入建设 ADR 的团队正在看到其价值的复利效应;而跳过这一步的团队则在目睹 AI 生成技术上正确、却违反了无人记录的约束条件的代码。

将刻意的评审仪式与审批仪式分开。 一些团队正在将代码评审原有的两项功能分开:验证(这是否达到了合并标准?)和理解(我知道这段代码在做什么吗?)。AI 快速生成的代码能迅速通过验证。而理解需要时间,评审时间表往往无法保障这一点。一些团队会开展专门的每周会议,让工程师阅读 AI 生成的代码,目标是建立理解——而不是做出合并决定——这些团队维持了代码的可理解性,而那些仅进行审批关卡式评审的团队则没能做到。

记录意图而非仅仅是作者的归属信息。 Co-Authored-By 惯例记录了 AI 参与了贡献。但它没有记录的是 prompt(提示词)、正在实现的架构决策或考虑过的替代方案。团队正在尝试扩展 commit 消息和 PR 描述来保留这些上下文——这并非官僚主义,而是作为一种组织知识资产,使得 commit 在六个月后依然具有阅读价值。在每个 commit 层面上,这是高摩擦的,但在系统层面上是低摩擦的:每项变更的小额投入,在某些东西损坏且你需要理解它时,会带来巨大的回报。

代码所有权不再等同于作者身份

代码所有权始终关乎责任归属,而非作者身份。问题从来不是“谁敲了这些代码?”,而是“谁负责了解这段代码的功能并保持其健壮性?”

这种责任正在被稀释,而没有被明确地重新分配。当 AI 生成代码时,编写提示词的开发者负有责任。当代码在评审后合并时,评审者共同承担责任。当这条链条中没有人深度理解代码时,所有权就是名义上的——它存在于纸面上,而非任何工程师的大脑中。

应对得当的团队已经明确了责任的重新分配:使用 AI 生成代码的工程师拥有该代码的全部所有权,就像他们亲手敲下了每一个字符一样。这意味着要足够仔细地阅读代码,以便能够解释它、在评审中为它辩护,并在它出错时进行调试。AI 是一个产出初稿的工具,而不是一个分担认知负荷的共同作者。

当 AI 每个 sprint 生成数千行代码时,这比听起来要难得多。这意味着要放慢生成速度以匹配理解速度——这在一定程度上抵消了 AI 带来的吞吐量优势。正在解决这一问题的团队正在寻找一种平衡:在规范明确、测试覆盖率高的成熟领域,AI 生成代码的速度最快。在这些领域,理解可以走“快车道”。而在新颖、关键或复杂的代码中,评审开销必须如实预算,而不能假设其微不足道。

如果不进行这种平衡,团队将面临“构建快、理解慢”的局面,积累起一个无人能回答 git blame 本应回答的最重要问题的代码库:为什么。

References:Let's stay in touch and Follow me for more thoughts and updates