我们所熟知的拉取请求(pull request)已有大约 20 年历史,比现在许多仍在捍卫其不可或缺性的人的职业生涯还要年轻。代码审查也给人一种永恒的感觉,但事实并非如此。谷歌大约在 2006 年开始在内部进行代码审查——许多早期的 Windows 软件发布时,并没有类似现代审查的流程。
代码审查如今已成为一个审批关卡,但它已不再符合软件工程工作的形态。而当我们即将再次改变它时,值得记住的是:这个实践最初是由我们自己发明的。它曾解决过特定问题:在集成前捕获缺陷、指导初级工程师,以及传播知识以避免所有上下文都集中在一个人身上。但在某种程度上,它也演变成了合规、把关,并在许多组织中变成了形式主义。
“代码审查停滞在合并环节。AI 是将其前移的推动力。”
如今代码量已摧毁了这一实践,而困境不再是 完全不读代码 与人类逐行审查 AI 生成的代码以防止低质量内容之间的选择。它关乎代码审查的真正目的,以及如何在机器编写大部分代码的世界中重建这些功能。
审查停滞在合并环节
问任何人代码审查发生在哪里,答案总是自动的:就在你合并之前。不早不晚,流程中的一个固定点,已成为唯一的选择。
在 Thoughtworks,基于主干的开发、测试驱动开发和结对编程被奉为圭臬,这意味着审查并非一种仪式。好处是持续性的,发生在结对会话中,而不是数周后有人终于打开一个 500 行的 diff。当你不在分支上停留数周,且测试充分时,一个绿色的 流水线就是你所需的大部分。
集成前不应是唯一进行审查的地方,这一想法并不新颖。过去缺少的是推动力。如今,随着强大的代理式 AI 和 帮助我们生成更多代码的代理式 IDE 的出现,每个人都开始重新思考这个问题。当一个代理可以在一个下午生成一个功能所需的代码时,你希望捕获的差距就前移了,移到开发者向工具表达意图的时刻。到 diff 存在时,你审查的已是数小时前做出的决策的后果,价值数千个 token。
“到 diff 存在时,你审查的已是数小时前做出的决策的后果。”
意图驱动开发在 Aviator 中意味着在意图产生时捕获它。这可以是对范围的简要描述、明确排除的内容,或是 验收标准列表。根据我们的经验,意图最好直接从提示中捕获,从工程师与代理协作时做出的决策中捕获。
我们现在究竟在审查什么?
表达意图会产生产物。每个功能可能有数十个 Markdown 文件、规格说明、澄清问题日志,以及埋藏在提示对话中的决策树。大多数团队都不会对这些内容进行版本控制。因此,值得代码审查的内容已经发生了变化。
目前出现了三种阵营。一些团队只审查规格并信任其余部分。一些团队仍审查所有产物(规格、代码及其中间一切),明知自己正在成为瓶颈。还有一些团队什么都不审查,只测试运行中的系统,因为代码量已让他们别无选择。
由于生成的代码量巨大,团队进行代码审查的方式也在发生变化。一个跨越五个以上文件的 diff 已超出人类将预期变更与实际变更关联起来的能力。再乘以十倍。审查者现在需要的不仅仅是一个 diff 和一个工单。他们想要看到原始意图、代理所走的路径,或许还有代码本身。
阅读意图,而非实现
审查者不必查看数百行代码来判断它是否正确,而是查看 10 行意图和验收标准,只需思考一个问题:这是否在正确的约束下解决了正确的问题?这是对高级工程师时间更好的利用。
它还保留了审查的知识共享功能。知道平台中存在已使用多年的日期处理库的审查者,可以将这一知识编入组织的 AI 低质代码注册表,并实现完美扩展。挖掘你过去的 1000 条审查评论,进行聚类,并生成待人工批准的不变性候选。每编入一条不变性,就相当于一条永远不需要再写的代码审查评论。
集体代码所有权——即不应由一个人掌握所有上下文——终于在实践中实现,因为上下文必须离开人的头脑,才能对 LLM 有用。
代理审查代码不需要用户界面
如今大多数 AI 代码审查工具都构建在 GitHub 或 GitLab 之上,并留下评论。代理读取评论、反驳、推送变更或为自己辩护。这与我们之前的形式主义相同,只不过现在两边都自动化了,并且不再需要界面。
无论是人类还是代理进行的代码审查,都必须发生得更早,而且甚至不必是审查。它可以是橡皮鸭调试或教学时刻。尽可能前移所有工作,以最小化后续需要做的工作量。在生成过程中伴随的咨询或对抗性代理,在反模式形成时捕获它们,远比提交后发表评论更有价值。
我们在 Thoughtworks 构建了一个代码审查代理,最初是面向初级开发者的教学代理,指向团队已知的原型和约定文档,并被要求解释开发者偏离的地方。它后来演变为审查代理。
Aviator Verify 会启动服务器、发送真实流量,并驱动 UI 交互,以检查代码是否实现了意图所说的,而不仅仅是看起来正确。目标是向审查者提供证据,使审查成为证据与意图是否合理的问题,而不是逐行阅读 diff。
代码审查不会一夜之间演变
这一切不会通过组织范围的备忘录在一夜之间发生。你无法通过指导让团队放弃数十年的信念;你必须在实践中展示。
Thoughtworks 的一位客户曾有严格规定:顾问产出的任何内容都必须经过审查。后来,一个规格驱动开发试点给了他们大量 Markdown 文件和异常大的变更集,规则与现实发生了冲突。他们自己得出了结论:用老方式审查所有内容会使他们成为瓶颈。
“验证交给机器。判断和知识留给人。”
构建 AI 低质代码注册表需要时间,在第一个月里会感觉像是双倍工作:既要做代码审查,又要 构建不变性。但一旦编入,低质代码注册表将永远不需要审查者,并能防止同样的错误再次出现。
机器负责验证,人类负责判断
形态在改变,但审查的原因没有变。我们仍然需要捕获缺陷、指导下一代工程师,并保持决策可见。改变的是这些工作发生的位置。验证交给机器,它们比我们更快、更一致。判断和知识留给人,因为这是审查中对学习重要的部分。
因此,转变不是从审查到不审查,而是从阅读代码转变为 阅读意图。
技术发展迅速,不要错过任何一集。订阅我们的 YouTube 频道,观看我们所有的播客、访谈、演示等内容。
Group Created with Sketch.
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.