Press "Enter" to skip to content

使用机器学习解决代码审查评论

由亚历山大·弗瑞姆根 (Alexander Frömmgen),高级软件工程师莱拉·卡拉提扬 (Lera Kharatyan) 发布

代码更改审查是规模化软件开发过程中至关重要的一部分,占用了代码作者和代码审查人员相当数量的时间。作为这个过程的一部分,审查人员检查建议的代码,并通过自然语言编写的评论要求作者进行代码更改。在 Google,我们每年看到数百万个审查人员的评论,作者需要平均 ~60 分钟的积极引导时间,在发送更改进行审查和最终提交更改之间。在我们的测量中,代码作者必须做出的为了应对审查人员的评论所需的积极工作时间几乎是随着评论数量线性增长的。然而,通过机器学习 (ML),我们有机会自动化和简化代码审查过程,例如,根据评论的文本提出代码更改。

今天,我们描述了我们在 Google 的日常开发工作流程中应用最新的大型序列模型 (使用 DIDACT 方法论) 的应用,自动解决代码审查评论。截至今天,Google 的代码更改作者通过应用 ML 建议的编辑,处理了大量的审查人员评论。我们预计,在 Google 的规模下,这将每年减少数十万小时的代码审查时间。非请求的非常积极的反馈表明,ML 建议的代码编辑的影响增加了 Google 员工的生产力,并允许他们专注于更具创意和复杂的任务。

预测代码编辑

我们首先训练一个模型,预测以应对审查人员的评论需要进行的代码编辑。该模型是在各种编码任务和相关的开发人员活动 (例如,重命名变量、修复破损的构建、编辑文件) 上进行预训练的。然后,它通过评审的代码更改、审查人员的评论和作者执行的编辑,针对这个特定的任务进行微调。

使用机器学习解决代码审查评论 机器学习 第1张
一个关于 ML 建议的编辑的重构示例,它们分布在代码中。

Google 使用单一代码库 (monorepo),即用于构建 Google 最新软件以及以前版本的所有未受限制的代码,这使得我们的训练数据集包括了所有未受限制的代码。

为了提高模型质量,我们对训练数据集进行了迭代。例如,我们比较了每个文件一个审查人员评论数据集和多个评论数据集的模型性能,并尝试使用分类器清理训练数据,基于小型的精选数据集选择具有最佳离线精度和召回率指标的模型。

提供基础架构和用户体验

我们在训练好的模型之上设计和实现了这个功能,关注整体用户体验和开发效率。作为其中一部分,我们通过一系列用户研究探索了不同的用户体验 (UX) 选择。然后,我们根据内部测试 (即开发中的功能测试) 的见解,包括用户反馈 (例如,“这有帮助吗?”按钮旁边的建议编辑) 来改进该功能。

最终模型被校准为 50% 的目标精度。也就是说,我们调整了模型和建议过滤器,以便在我们的评估数据集上,50% 的建议编辑是正确的。一般来说,增加目标精度会减少显示的建议编辑数量,而降低目标精度会导致更多不正确的建议编辑。不正确的建议编辑会占用开发人员的时间,并降低开发人员对该功能的信任。我们发现,50% 的目标精度提供了很好的平衡。

在高层次上,对于每个新的审查人员评论,我们生成与训练使用的相同格式的模型输入,查询模型,并生成建议的代码编辑。如果模型对预测有信心,并满足一些额外的启发式规则,我们会将建议的编辑发送到下游系统。下游系统,即代码审查前端和集成开发环境 (IDE),向用户公开建议的编辑,并记录用户的交互,例如预览和应用事件。一个专门的管道收集这些日志,并生成聚合的见解,例如本博客文章中报告的整体接受率。

使用机器学习解决代码审查评论 机器学习 第2张
ML建议修改基础架构的体系结构。我们从多个服务处理代码和基础架构,获取模型预测,并在代码审查工具和IDE中呈现预测。

开发人员在代码审查工具和IDE中与ML建议的修改进行交互。根据用户研究的见解,集成到代码审查工具中最适合获得流畅的审查体验。IDE集成提供了额外的功能,并支持在合并结果(中间)中将ML建议的修改(下图左侧)与已审核代码状态(右侧)上的冲突本地更改进行3路合并。

使用机器学习解决代码审查评论 机器学习 第3张
IDE中的3路合并用户体验。

结果

离线评估表明,该模型以50%的目标精度处理了52%的评论。beta版和完整内部发布的在线指标确认了这些离线指标,即我们看到模型建议超过我们的目标模型置信度达到约50%的所有相关评论者评论。40%至50%的所有已预览的建议的修改都是由代码作者应用的。

我们利用beta版中的“不帮助”反馈来识别模型的重复故障模式。我们实施了服务时间启发式来过滤这些内容,从而减少了显示不正确预测的数量。通过这些变化,我们为质量交易了数量,并观察到了增加的实际接受率。

使用机器学习解决代码审查评论 机器学习 第4张
代码审查工具用户体验。建议将其显示为评论的一部分,并可以预览、应用和评为有用或无用。

我们的beta版发布显示了一个发现性挑战:代码作者只预览了所有生成的建议编辑的约20%。我们修改了用户体验并引入了一个突出的“Show ML-edit”按钮(请参见上图),位于评论者评论旁边,从而在发布时导致总体预览率为约40%。我们还发现,代码审查工具中的建议修改通常不适用于作者在审查过程中所做的冲突更改。我们通过代码审查工具中的一个按钮解决了这个问题,该按钮打开IDE以在建议的编辑中进行合并视图。我们现在观察到,超过70%的这些应用于代码审查工具,少于30%的应用于IDE。所有这些变化都使我们将ML建议的编辑中的评论者评论的总比例提高了2倍,从beta版到完整的内部发布。在Google规模下,这些结果有助于自动解决每年数十万个评论。

使用机器学习解决代码审查评论 机器学习 第5张
建议过滤漏斗。

我们在生产中看到了 ML 推荐的编辑可以解决广泛的审阅者评论。这包括简单的本地化重构和分散在代码中的重构,正如以上博客文章中的示例所示。该功能解决了需要代码生成、重构和导入的更长且不正式措辞的评论。

使用机器学习解决代码审查评论 机器学习 第6张
一个需要代码生成、重构和导入的更长而不正式措辞的评论的建议示例。

该模型还可以回应复杂的评论并生成大量的代码编辑(如下所示)。生成的测试用例遵循现有的单元测试模式,同时根据评论中描述的更改细节进行更改。此外,该编辑建议一个全面的测试名称,反映测试语义。

使用机器学习解决代码审查评论 机器学习 第7张
模型响应复杂评论并生成广泛的代码编辑的示例。

结论和未来工作

在本文中,我们介绍了一项 ML 功能来减少代码审查相关更改所花费的时间。目前,在 Google 上支持的语言中,大量的可行代码审查评论都使用应用的 ML 推荐编辑来解决。一项为期 12 周的 A/B 实验将进一步衡量该功能对整体开发者生产力的影响。

我们正在整个堆栈上进行改进。这包括提高模型的质量和召回率,并构建一个更流畅的开发者体验,通过改进审查过程中的发现能力来实现。作为其中的一部分,我们正在研究向审阅者展示建议的编辑,同时扩展该功能到 IDE,以使代码更改作者能够获得自然语言命令的建议代码编辑。

致谢

这是 Google 核心系统与体验团队、Google 研究和 DeepMind 团队的许多人的工作。我们要特别感谢 Peter Choy 带来的合作,以及我们所有团队成员的关键贡献和有用的建议,包括 Marcus Revaj、Gabriela Surita、Maxim Tabachnyk、Jacob Austin、Nimesh Ghelani、Dan Zheng、Peter Josling、Mariana Stariolo、Chris Gorgolewski、Sascha Varkevisser、Katja Grünwedel、Alberto Elizondo、Tobias Welp、Paige Bailey、Pierre-Antoine Manzagol、Pascal Lamblin、Chenjie Gu、Petros Maniatis、Henryk Michalewski、Sara Wiltberger、Ambar Murillo、Satish Chandra、Madhura Dudhgaonkar、Niranjan Tulpule、Zoubin Ghahramani、Juanjo Carin、Danny Tarlow、Kevin Villela、Stoyan Nikolov、David Tattersall、Boris Bokowski、Kathy Nix、Mehdi Ghissassi、Luis C. Cobo、Yujia Li、David Choi、Kristóf Molnár、Vahid Meimand、Amit Patel、Brett Wiltshire、Laurent Le Brun、Mingpan Guo、Hermann Loose、Jonas Mattes、Savinee Dancs。感谢 John Guilyard 在本文中创建的图形。

Leave a Reply

Your email address will not be published. Required fields are marked *