是时候停止代码审查了
作者曾构建最好的AI辅助代码审查工具,但如今认为传统的人工代码审查已不再必要:知识传递、培训和大部分技术债务管理都已被AI改变,缺陷检测也应交给自动化工具和AI分类。工程师应把时间花在理解架构和意图上,而不是手动逐行阅读diff。
看到这个标题,也许有人会皱眉。我理解,因为就在不久之前我也持同样看法。今年年初,我花了一个月构建了当时——甚至可能现在依然是——世界上最好的AI辅助代码审查工具。但如今,我已经完全不再做传统意义上的代码审查了。
在人类主导的软件开发中,代码审查主要有三个目的。第一是知识传播,避免只有一位工程师知道如何安全地修改某段代码;第二是培训,资深工程师通过审查初级工程师的代码来帮助对方成长;第三是缺陷检测和避免技术债务。作者认为,前两个目的已经不再需要依赖代码审查来实现。借助AI,我们可以极快地理解任意代码,按需获取上下文,不再需要为每个PR花费几小时甚至几天来通读。至于培训,AI写代码之后,再向初级工程师反馈代码质量问题,性价比已经不高。模型目前还不能跨会话学习,虽然各大实验室都在尝试解决这个问题,预计几年内会有突破。
技术债务也不再像过去那样可怕。如果方向错了,直接修改代码去纠正方向就好。这是更高层次的YAGNI原则:如果未来再做的成本并不比今天更高,那就不必现在花昂贵的时间去做可能不必要的事情。实际上,随着模型逐月变强,未来做的成本往往会更低。新模型Fable 5,以及程度稍低的Sol 5.6和K3,在改进代码方面的能力远超前代,虽然仍会犯错,但每次发布都在减少。
剩下的是缺陷检测。我们得先承认,人工代码审查从来就不擅长找缺陷。它总比没有好,但最好的研究显示检出率约为35%,在安全等专业领域往往更低。工程师应该把这件事自动化。软件领域几十年来积累了大量关于如何让代码更健壮的研究,甚至包括很难推理的分布式系统代码,但在过去,由于需要为结构化和插桩做出巨大改变,这些方法几乎无法落地。现在有了按需智能,这个问题不存在了。所以作者觉得奇怪:几乎还没有人开始引入这些技术。
静态分析就是其中一个例子。Coverity从2002年就存在了,但人们更愿意使用Ruff和Clippy这样更简单的工具,因为更复杂的检查在真实代码库中噪声太大。而现在,AI可以直接在噪声中判断哪些真正值得关注。作者为Bifrost写了两条自定义分析流水线,都输入GPT,由它分类哪些应该忽略、哪些应该自动修复、哪些应该上报给人类。
那么,应该把“审查预算”花在哪里?作者并不认为人类不该接触细节。架构、不变量和意图仍然需要人来理解,但手动阅读diff,即使是精简后的diff,也不再是获得或维持这种理解的最佳方式。/plan 是作者的推荐工具。它可以让你在动手前发现指令中的歧义,除非是最机械、最直接的改动,否则都不应跳过。你可能会惊讶于模型觉得哪些地方有歧义,也会庆幸没有让它独自猜测。这也是检查难以变更的外部承诺的最佳时机,比如持久化数据格式、公开API、协议等。
作者举了今天早上的例子。他正在构建Hel——一个“harness of harnesses”。当会话增长到数十万事件时,worker-controller协议变得臃肿而缓慢,重新连接需要几分钟。这种事在过去的人工审查中百分百会被发现,但这意味着每次提交都要做那种级别的审查。如果那样做,四天之后大概连1.0的边都摸不到,而不是几乎完成。发现问题后,他进入 /plan 说:根据仪表盘目标,我们需要worker提供哪些事件,应该如何表示?原始事件流、每100毫秒汇总,还是其他方式?模型给出了合理设计,但作者发现有些地方对不上,于是要求把提议的结构映射到它驱动的功能上,结果又发现了几个需要清理的问题。
作者的结论是:直到大约2024年,代码审查都是传播知识、指导团队、防止技术债务和尽早修复bug的宝贵工具。但如今,变更变得太容易,工作方式也变了,手动例行阅读diff已是对资深工程时间的浪费。如果他现在作为独立贡献者找工作,会避开那些仍然把这种审查当作变相派活儿的组织,那种文化几乎和毫无意义的会议一样令人反感。在大多数科技公司,人力工程时间是最昂贵的资源。与其花在手动阅读diff上,不如用来构建能比人眼更好地捕捉回归的新系统。