翻译:BitsAI-CR: Automated Code Review via LLM in Practice
代码审查在软件开发中仍然是一个关键但资源密集的过程,尤其是在大规模工业环境中更具挑战性。尽管大型语言模型(LLMs)在自动化代码审查方面展现出潜力,但现有的解决方案在精确性和实用性方面仍存在显著局限性。本文介绍了BitsAI-CR,这是一种创新框架,通过结合RuleChecker进行初步问题检测和ReviewFilter进行精确性验证的两阶段方法来增强代码审查。该系统基于一套全面的审查规则分类法构
BitsAI-CR:通过LLM实现的自动化代码审查实践
BitsAI-CR: Automated Code Review via LLM in Practice
摘要
代码审查在软件开发中仍然是一个关键但资源密集的过程,尤其是在大规模工业环境中更具挑战性。尽管大型语言模型(LLMs)在自动化代码审查方面展现出潜力,但现有的解决方案在精确性和实用性方面仍存在显著局限性。
本文介绍了BitsAI-CR,这是一种创新框架,通过结合RuleChecker进行初步问题检测和ReviewFilter进行精确性验证的两阶段方法来增强代码审查。该系统基于一套全面的审查规则分类法构建,并实施了一种数据飞轮机制,通过结构化反馈和评估指标实现持续性能改进。我们的方法引入了一个名为“过时率”(Outdated Rate)的指标,能够反映开发人员对审查意见的实际采纳情况,从而实现大规模的自动化评估和系统优化。实证评估表明,BitsAI-CR在生成审查意见方面表现出了有效性,达到了75.0%的精确度。对于在字节跳动广泛使用的Go语言,我们保持了26.7%的过时率。该系统已成功部署于字节跳动,服务于超过12,000名每周活跃用户(WAU)。我们的工作为自动化代码审查的实际应用提供了宝贵的见解,并为寻求大规模实施自动化代码审查的组织提供了一个蓝图。
关键词
代码审查,大型语言模型,数据飞轮
1 引言
代码审查是软件开发中一个关键的过程,对代码质量和项目成功有着重要影响 [2, 48]。它能够识别潜在的安全漏洞、逻辑错误和性能瓶颈,同时促进研发团队之间的知识共享 [34]。然而,我们在字节跳动的分析揭示了在企业规模的代码审查实践中存在显著挑战。内部数据显示,审查人员平均每次审查花费15分钟,在超过50%的情况下如此,其余案例则需要更长时间。仅有30%的审查能够立即得到关注,而超过67%的工程师表示需要更有效的工具。这些证据表明,对高效自动化代码审查工具的需求十分迫切,但当前的方法 [8, 35] 仍显不足,或缺乏对其在企业规模上的实际影响进行综合评估。
传统的静态分析工具虽然提供了基本的代码质量检查功能,但由于复杂的构建配置和编译过程,它们为开发工作流带来了显著的额外负担。大型语言模型(LLMs)因其在代码理解和自然语言生成方面的卓越能力 [9, 12, 22] 成为了一种有前景的解决方案。近期的商业实现已开始探索基于LLM的方法来解决这些局限性。然而,Google 的方法 [40] 仅专注于问题分类,而未生成具体的审查意见;腾讯 [50] 则主要关注代码可维护性问题。我们的研究表明,当前基于LLM的解决方案面临三个基本挑战:i) 在生成技术上准确的意见方面精确度不足;ii) 意见虽技术上正确,但缺乏实质性价值 [26, 29];iii) 缺乏系统性的机制进行针对性改进,无法通过数据驱动的方式提升模型的精确性和建议的实用性。
为了解决这些问题,我们提出了BitsAI-CR,这是一个由两个核心组件协同工作的框架:高精度的审查意见生成管道和基于用户反馈持续优化的数据飞轮机制。首先,为了解决审查意见精确度低的问题,审查生成管道设计为两阶段流程,称为RuleChecker 和 ReviewFilter:(1) RuleChecker 是一个经过微调的LLM,训练于一套包含219条审查规则的全面分类法之上,旨在识别潜在问题;(2) ReviewFilter 是另一个在RuleChecker之后微调的LLM,通过验证检测到的问题来提高精确度。其次,为了实现有针对性的持续改进,我们构建了一个数据飞轮,利用真实世界反馈来应对大规模工业场景:(1) 利用注释反馈数据增强训练数据集,从而通过有针对性的改进提升BitsAI-CR的性能;(2) 通过计量“过时率”来解决技术正确但实际冗余的意见问题,自动测量被BitsAI-CR标记后修改的代码行百分比,从而提供开发人员是否接受并采纳审查意见的具体证据;(3) 根据过时率和精确度测量动态调整审查规则,移除那些产生低价值意见且具有低过时率和高精确度的规则。
通过这种方法,BitsAI-CR 建立了一个持续改进的循环,以提升代码审查效果。
实证评估表明,我们的BitsAI-CR在精确度方面取得了显著改进,开发人员也逐渐认可生成的意见。两阶段审查管道达到了75.0%的峰值精确度,大幅减少了冗余意见。更重要的是,我们的数据飞轮机制随着时间推移展现出一致的改进效果,在Go语言中实现了26.7%的过时率。在字节跳动的大规模工业部署进一步验证了BitsAI-CR的影响,吸引了超过12,000名每周活跃用户(WAU)。
本文详细介绍了我们如何构建和部署BitsAI-CR,并已在字节跳动生产环境中使用数月,服务于上万名工程师。主要贡献包括:
- 一套全面的审查规则分类法,简化了整个代码审查流程,通过数据驱动的反馈回路实现评估实践、数据收集机制和持续优化。
- 一种结合RuleChecker进行问题检测和ReviewFilter进行验证的两阶段方法,展示了审查效率的显著提升。
- 引入“过时率”指标,解决了传统精确度测量中的两个关键限制:手动评估的可持续性和评估用户对审查意见接受度的能力。
- 通过大规模部署进行实证验证,展示了数据飞轮在现实软件开发环境中的有效性和可扩展性,通过系统的实施实践证明其价值。
2 背景
代码审查已从一个简单的正确性检查机制演变为一项全面的质量保证流程,塑造了组织文化和开发实践。现代审查如今评估代码质量的多个维度,包括设计模式、架构选择和可维护性,同时促进知识共享和团队协作 [7]。与此同时,“代码最佳实践” [28] 指的是一套被广泛接受的方法论,这些方法被证明能够提升软件开发过程的质量和效率。代码审查是实施这些最佳实践的关键手段,审查人员根据公司的内部标准评估代码的各个方面。
在字节跳动,代码审查是软件开发生命周期中不可或缺的一部分,遵循行业标准实践的同时还结合了公司特定的需求。与现有的代码管理系统(如GitHub的拉取请求 [17] 和Google的Piper [32])类似,字节跳动的软件开发流程要求经验丰富的审查人员检查每次代码更改提交。只有在获得“LGTM”(即“看起来不错”)批准后,代码才会被合并。作者和审查人员通过代码审查系统交换意见,检查受影响文件的快照。
典型的增量审查流程包括以下几个步骤:(1) 开发人员创建合并请求(MR)。(2) 代码差异提交给审查人员进行错误识别和解决,这一过程可以由BitsAI-CR自动化或增强。(3) 审查人员在BitsAI-CR的辅助下(或直接由其取代)提供反馈,以确保代码符合质量标准。(4) 开发人员根据审查人员的反馈重构代码。(5) 必要时重复步骤2-4。(6) 一旦审查人员确认所有问题都已解决,代码即可获得合并批准。
3 方法论
在本节中,我们介绍了自动化代码审查的方法。首先,我们将概述框架,展示审查意见生成管道和数据飞轮机制如何协同工作,如图1所示。然后,我们详细说明作为整个系统基础的代码审查规则分类法。接下来,我们阐述审查意见生成管道,包括上下文准备、规则检查、审查过滤和意见聚合。最后,我们描述数据飞轮机制以持续改进BitsAI-CR。
3.1 BitsAI-CR框架
BitsAI-CR的任务是分析代码变更并提供有意义的审查意见。给定一段代码差异,系统旨在识别潜在问题并生成适当的审查建议。输出包括审查类别、具体的有问题代码位置以及详细的解释性评论。
图2展示了这种输入-输出关系。输入由代码变更组成,而输出则提供了结构化的审查反馈,帮助开发人员提高代码质量。
如图1所示,BitsAI-CR框架由两个主要组件组成:审查意见生成管道和用于持续改进的数据飞轮机制。审查意见生成管道通过四个步骤处理代码审查:(1) 上下文准备,为分析构建输入;(2) RuleChecker,使用LLM识别潜在问题;(3) ReviewFilter,验证检测到的问题;(4) 意见聚合,整合相似反馈。支持该管道的是数据飞轮机制,它通过审查规则分类法确保持续改进,这些规则用于创建LLM的训练和测试数据集。生成的审查意见会收到注释反馈,这反过来有助于完善审查规则,从而创建一个自我改进的系统,随着时间推移提升代码审查质量。
3.2 代码审查规则的分类法
我们建立了一套全面的代码审查规则分类法,这是BitsAI-CR系统的基础组件,并引入了一个三层分类结构:审查维度(广泛的代码质量评估领域)、审查类别(需要评估的具体问题类型)和审查规则(具有示例的详细标准)。术语“审查规则”指的是定义具体评估标准的详细规范。每个审查类别都有详细规则支持,这些规则明确了问题类型分类、严重性级别、全面描述以及正确和错误实现的示例。
我们的审查维度涵盖了各种编程语言的独特特性,包括语言特定的习惯用法、性能优化以及每种语言生态系统中的常见陷阱。如表1所示,它们包括:
- 代码缺陷:此维度涵盖代码正确性的各个方面,包括错误处理、逻辑缺陷和资源管理。
- 安全漏洞:它解决了关键的安全问题,例如注入漏洞、跨站脚本和不安全的数据处理。
- 可维护性和可读性:它强调代码的清晰性、一致性和结构,以确保代码库的长期可维护性。
- 性能问题:此类别专注于优化代码执行,涵盖高效数据结构、查询优化和资源利用等领域。
每个审查类别包含多个具体的审查规则,从而实现细粒度的质量评估。例如,考虑审查维度“代码缺陷”,它包含各种审查类别,包括“条件逻辑错误/遗漏/重复”。在此类别中,具体的审查规则包括“不可达代码检测”和“无限循环识别”等。这些规则解决了关键的代码质量问题:“不可达代码”表示由于逻辑约束而永远无法执行的冗余语句,而“无限循环识别”则识别可能导致系统资源耗尽的潜在无尽程序执行周期。我们已经涵盖了一系列编程语言,包括Go、JavaScript、TypeScript、Python和Java,总计219条审查规则。
这种结构提供了几个关键优势:(1) 高效的数据收集:分层分类法使系统化数据收集和标记成为可能,为不同类型代码问题及其相应评论的分类提供了明确的指导方针。(2) 简化的模型训练:结构化的分类提供了明确定义的训练目标和有组织的数据集,从而更有效地针对特定审查任务对模型进行微调。(3) 系统化的评估:清晰的分类结构能够精确测量模型在不同审查维度上的表现,促进全面的质量评估。(4) 针对性的优化:结构化的反馈机制允许通过为每个审查维度定义明确的改进路径来系统地提升模型性能。
3.3 审查意见生成管道
我们的审查意见生成管道实施了一种以RuleChecker和ReviewFilter为核心的两阶段方法。第一阶段使用RuleChecker根据分类法识别潜在问题,而第二阶段则利用ReviewFilter验证这些发现,确保高精确度。两个辅助组件完善了该管道:上下文准备(Context Preparation),用于构建和丰富输入代码以便分析;以及意见聚合(Comment Aggregation),用于整合相似反馈以防止信息过载。
上下文准备
此阶段采用系统化方法准备输入代码并为分析构建适当的提示。该过程涉及三个关键步骤:(1) 我们基于头部差异块对每个代码差异进行分区,创建多个分析单元,以管理上下文长度并防止在后续处理步骤中消耗过多标记。(2) 我们扩展每个分段代码块以包含完整的函数定义,遵循一种受控策略,将上下文扩展到原差异大小的四倍以内,或限制为原大小的三倍。我们使用tree-sitter(https://tree- sitter.github.io/tree-sitter/)来精确定位代码块并检测函数边界。(3) 我们实现了一个详细的变更注释系统,标记每行的状态和位置:旧版本行被标记为“[已删除或修改前 @旧代码中的行号]”或“[未更改]”,新版本行被标记为“[已添加或修改后 @新代码中的行号]”或“[未更改]”。这些注释保留了原始结构,同时提供了有关代码修改的关键上下文。当这些上下文准备就绪后,我们将它们应用于后续的提示构建。这种系统化的准备确保模型既能接收全面的上下文,又能获得明确的指令,从而生成更准确且相关的审查意见。
RuleChecker
RuleChecker组件通过一个微调的LLM识别问题,该模型集成了字节跳动内部的代码标准和我们的审查规则分类法。该模型彻底检查目标代码,并提供检测到的问题及修改建议,输出如图2所示。
此外,该组件包括一个规则类别阻断器,可在我们认为某些规则对用户不可接受时动态排除规则,而无需重新训练模型。
ReviewFilter
ReviewFilter将一条审查意见作为输入,并输出二元决策(是/否)以确定是否应保留该意见。此组件通过解决RuleChecker输出中的幻觉和事实错误来提高管道的精确度。在实践中,我们发现RuleChecker在识别问题时经常遇到与幻觉和事实错误相关的不良案例。然而,我们的实验表明,即使使用优化的训练样本和强化学习方法,传统的监督微调方法也未能充分缓解这些问题。经过多次迭代,我们最终选择引入ReviewFilter组件,对RuleChecker生成的结果进行二次验证,从而提高意见的精确度。ReviewFilter组件同样基于一个微调的LLM。为了实现有效的意见验证,我们在模型的输出结构中探索了三种不同的推理模式:(1) 直接结论,不带推理直接生成单一决策(是或否)标记;(2) 推理优先,在得出结论之前提供完整推理,需要像思维链(CoT)[44]一样生成完整的标记;(3) 结论优先,先输出决策标记,然后提供支持性理由,只需评估第一个标记即可,同时保留完整输出。每种模式在精确度、推理速度和可解释性之间提供了不同的权衡,我们将在第4.2节中对其进行广泛评估。最终,我们选择了“结论优先”模式来组织训练数据。
意见聚合
单个MR中的多个文件和头部差异块可能会生成大量相似的意见,可能使开发人员因冗余反馈而不知所措。意见聚合模块位于管道的末端。该模块使用余弦相似度确定意见是否相似,并随机保留每个相似组中的一条评论。具体而言,问题类别和意见通过我们内部的嵌入模型Doubbao-embedding-large进行向量化,该模型运行于512维空间中。经过上述管道处理后,我们将为每个合并请求获得一批准确的意见。这些意见将包括详细的问题描述和修改建议,并经过充分聚合以避免干扰。
3.4 评估指标
优先考虑代码审查实践中的精确度
在代码审查开发的早期阶段,我们通过分析和用户研究发现了两个关键见解。首先,与警报疲劳类似,开发人员在面对大量评论时往往会完全忽略审查意见,因为他们不愿意花时间仔细甄别。其次,早期阶段的不准确意见会显著损害用户信任,阻碍系统的持续迭代和改进。这些实际挑战促使我们在方法中优先考虑精确度而非召回率。关于召回率,一个基本挑战在于全面问题检测所需的巨大人力投入。许多缺陷仅在长时间生产部署或大量人力投入后才会显现,即使是经过充分测试的代码也可能隐藏只有在特定使用模式或边缘情况下才会出现的潜在问题。形式上,设CcorrectC_{correct}Ccorrect表示正确意见的集合,CtotalC_{total}Ctotal表示BitsAI-CR生成的所有意见,我们定义精确度为:
Precision=∣Ccorrect∣∣Ctotal∣×100%(1) \text{Precision} = \frac{|C_{correct}|}{|C_{total}|} \times 100\% \tag{1} Precision=∣Ctotal∣∣Ccorrect∣×100%(1)
用于自动化评估的过时率
尽管精确度是评估模型性能的关键指标,但单独使用精确度测量存在根本局限性。一个主要限制是,精确度无法反映开发人员是否真正接受并根据审查意见采取行动。此外,手动精确度评估需要大量人力,使得大规模评估和长期持续监测变得困难。为了解决这些问题,特别是衡量开发人员对意见的响应的需求,我们引入了“过时率”(Outdated Rate)指标,它跟踪被BitsAI-CR标记后修改的代码行百分比。具体而言,该指标计算如下:
Outdated Rate=∣{c∈Cseen∧isOutdated(c)}∣∣Cseen∣×100%(2) \text{Outdated Rate} = \frac{|\{c \in C_{seen} \land \text{isOutdated}(c)\}|}{|C_{seen}|} \times 100\% \tag{2} Outdated Rate=∣Cseen∣∣{c∈Cseen∧isOutdated(c)}∣×100%(2)
其中,CseenC_{seen}Cseen表示代码提交者在一周测量窗口内审查的意见集合,函数isOutdated(c)\text{isOutdated}(c)isOutdated(c)仅在意见ccc被视为过时时返回真值,即在其标记的代码范围内任何行在后续提交中被修改时发生。这种自动化的测量方法能够在手动评估不切实际的情况下实现系统化的大规模评估。虽然过时率不能明确证明更改是直接响应BitsAI-CR的意见,但它有助于在大规模部署中持续改进系统。
3.5 数据飞轮:持续演进
BitsAI-CR的有效性依赖于高质量数据集和基于用户反馈的持续迭代。我们的数据飞轮方法通过系统化的方式构建、维护和增强数据集,进行基于用户反馈的目标优化,如图1下半部分所示。
3.5.1 挖掘审查规则并整合代码风格指南
BitsAI-CR的基础是一套全面的代码审查规则分类法,该分类法将代码风格指南与实际审查经验相结合(如表1和第3.2节所示)。代码风格指南为代码格式化、最佳实践、编程原则等提供了标准化的规范。基于代码风格指南,我们从两个主要来源推导出规则:
- 内部静态分析规则:字节跳动采用了一套全面的内部静态分析规则。每条静态分析规则都标有推荐指数和接受率。我们选择那些推荐指数高且开发者接受率高的规则,形成我们的审查规则集。
- 手动审查意见:考虑到静态分析规则在理解代码语义方面的不足,我们对内部手动审查意见进行分类,提取未被静态分析规则覆盖的审查规则。这包括诸如“拼写错误”、“重复代码”和“不清晰的代码注释”等审查规则。
我们当前的系统涵盖了五种编程语言中的219条审查规则,并通过下文描述的反馈循环动态更新。
3.5.2 模型训练的数据集构建
数据飞轮通过系统化流程将审查规则转化为高质量的训练数据集:
- 原始数据收集:我们从内部代码仓库的MR评论中提取了120,000条代码审查意见,涵盖静态分析结果和手动审查反馈。该原始数据集成为后续数据精炼的主要来源。
- 数据精炼:我们开发了一个利用Doubao-Pro-32K-0828 LLM的精炼流程。对于手动审查意见,该流程首先过滤掉非实质性内容(例如对话元素、表情符号),然后对剩余样本进行分类,保留符合规则的意见。接着,通过将简洁的反馈扩展为包含具体修改建议的全面问题描述来增强这些意见。对于静态分析结果,我们根据静态分析规则的具体定义对评论进行改进,并结合针对性的修改建议。
- 质量保证:我们通过系统化的手动抽样和标注确保数据集质量。为了节省人力成本,我们采用了确定性的抽样规则。在对每条审查规则的样本进行标注后,我们会调整抽样率——降低高精确度审查规则的抽样率,增加低精确度规则的抽样率。
这一过程生成了精炼的训练数据集,其中Go和前端语言各约18,000个样本,其他编程语言各5,000个样本。
3.5.3 在线反馈与持续演进
在BitsAI-CR部署后,我们每周对其在线性能进行详细评估,并根据评估结果进行有针对性的调整。我们的评估主要来自以下三个方面:
- 用户反馈收集:最直接的反馈来自用户的点赞和点踩,通常附有点评原因。通过分析点赞和点踩数据,我们可以针对表现不佳的审查规则进行具体优化。然而,这类反馈数据相对稀疏,通常用作补充分析。
- 手动精确度标注:每天,我们对在线数据进行抽样和标注(抽样比例一般不超过10%)。标注结果每周汇总一次,为审查规则的精确度提供准确测量。对于精确度较低的审查规则,我们将收集相应样本重新训练LLM。上述RuleFilter组件的训练数据主要来自此来源。
- 过时率监控:每周,我们跟踪每条审查规则的过时率变化。对于精确度高但过时率持续较低的情况,我们会考虑是否该审查规则未被用户接受,并可能决定将其淘汰。
这些多样化的反馈渠道为我们的审查规则的技术精确度和实际效用提供了宝贵的见解。
例如,图3展示了这样一个例子:BitsAI-CR标记了魔法数字“100”的使用。虽然该建议符合Go语言编码标准(不鼓励使用魔法数字),但用户对此表示不喜欢。用户不喜欢的案例突显了需要超越简单精确度指标的更全面评估框架。为应对这一挑战,我们开发了一种系统化的方法,同时使用精确度和过时率作为评估审查规则的关键指标。规则根据特定标准进行评估:14天内过时率约为25%(±5%),精确度约为65%(±5%)。这种双指标评估框架使我们能够以数据驱动的方式决定保留或移除特定的审查规则。
我们在表1中展示的全面代码审查规则分类法是这一演进过程的基础。通过将所有在线反馈样本映射到该分类法中的特定规则,我们可以高效地收集数据并进行有针对性的评估。这种系统化方法创建了一个持续的反馈循环:用户互动为规则评估提供数据,评估结果指导规则改进,改进后的规则生成新的反馈。通过这一迭代过程,我们维持了一个动态的审查系统,不断适应用户需求,同时保持高标准的质量。
3.6 BitsAI-CR的实现
开发者可以轻松启用BitsAI-CR功能,如图4所示。我们系统的输入是一个代码差异,而输出则是一条全面的审查意见,如图2所示。
如图5所示,BitsAI-CR会自动识别待合并代码中的潜在问题,确认审查类别,定位有问题的代码行,并提供相关评论。在开发者处理这些审查意见并进行必要的代码修改后,BitsAI-CR重新评估更改,并如图5所示,将原始审查意见标记为“过时”,同时提供“LGTM”(看起来不错)批准,表明代码修改成功解决了已识别的问题,现在符合所需的质量标准。
4 实验与分析
本节通过离线实验和大规模工业部署对BitsAI-CR进行了全面评估。我们首先详细说明了模型训练方法和配置,随后使用精心策划的数据集对代码审查能力进行了严格的离线评估。接着,我们进行了一项消融研究以验证ReviewFilter的必要性。分析扩展到生产环境中的在线性能指标,包括精确度趋势和用户留存率。在这些实验中,我们展示了BitsAI-CR在代码审查多个维度上的有效性,从技术精确度到实际开发场景中的实用性。
4.1 模型训练
BitsAI-CR的开发主要受企业安全需求和数据隐私考虑的驱动。因此,我们使用了字节跳动开发的Doubao-Pro-32K-0828 LLM,该模型在确保符合我们的安全政策的同时保持高性能标准。这是最先进的LLM之一,拥有丰富的知识库和强大的分析能力。我们采用低秩适应(LoRA)[13]技术对Doubao-Pro-32K-0828进行微调,用于RuleChecker和ReviewFilter。基于我们对历史审查数据的分析,显示99%的审查样本包含少于8192个标记,我们使用具有8192序列长度的Doubao-Pro-32K-0828。我们以8的批量大小对其进行5个周期的微调。LoRA配置包括128的秩和256的alpha。我们使用0.00005的学习率,并在1步上进行梯度累积,预热步率为0.05以稳定早期训练。
4.2 代码审查能力的评估
为了评估BitsAI-CR在代码审查中的有效性,我们收集了一个离线数据集,其中包括从生产代码库中采样的1397个案例,其中767个样本违反代码最佳实践,630个样本遵循代码最佳实践。这些案例来自表1中分类的审查规则分类法。
遵循LLM-as-a-judge方法[52],我们使用Doubao-Pro-32K-0828自动评估我们的业务代码数据集,同时保护数据机密性。只有当模型确定评论与真实情况一致时,该评论才被视为正确。实验结果如表2所示,我们将我们的方法与强基线模型进行比较,包括Qwen2.5-Coder-32b-instruct[15]和Deepseek-v2.5[54]。我们评估了两个版本:(1) 基础版本(BitsAI-CR w/o Taxonomy),在随机采样的内部审查数据上训练,没有分类学分类(类似于现有的开源方法[21]);(2) 分类学引导版本(BitsAI-CR),其训练数据根据我们的审查规则分类法专门构建,同时保持相同的数据量。结果表明,虽然我们的基础BitsAI-CR已经优于基线模型,但分类学引导版本在所有类别中实现了显著更高的精确度,总体精确度达到57.03%,而基础模型为16.83%。这些结果表明,我们的分类法增强了审查精确度。
ReviewFilter的消融研究
为了评估ReviewFilter组件的必要性,我们进行了一项消融研究,比较有和没有此过滤阶段的模型性能,如表2所示。
我们的实验揭示,即使是经过广泛微调的高级LLM原始输出也无法满足生产部署的精确度要求。这种局限性在各种代码审查场景中表现为持续的幻觉。例如,我们观察到微调后的RuleCheck模块经常错误地识别格式问题。在一个案例中,输出的消息是:“变量名‘basicInfoInstantHome’不符合编码标准,应删除下划线‘_’,更改为‘basicInfoInstantHome’。”这条消息显然是一个幻觉,因为变量名‘basicInfoInstantHome’已经符合编码标准,并且不包含任何下划线。在另一个案例中,它将函数名‘WhenAwemeStartFrom2580’误认为包含魔法数字,这表明如果没有适当的过滤,微调后的LLM可能会误解代码上下文。消融结果显示,添加ReviewFilter在所有类别中持续提高了精确度——在分类学引导模型中,总体精确度从54.50%提高到67.12%。这些定量改进以及防止幻觉的定性示例表明,ReviewFilter是实现自动化代码审查生产级可靠性的关键组件。
ReviewFilter的推理模式
为了优化我们在ReviewFilter中的评论验证机制,我们评估了第3.3节中描述的三种推理模式。我们为此实验额外收集了400个相关数据。
如表3所示,直接结论模式记录了最低的精确度。重要的是,通过推理过程丰富训练数据集可以提高ReviewFilter的性能。对推理模式的比较分析显示,推理优先模式达到了81.80%的优越召回率,但代价是显著延长了推理时间,达到31秒/样本,使其在生产场景中部署不太可行。相反,结论优先模式尽管获得最低的召回率为69.00%,并具有最高的过滤率,即被ReviewFilter识别为错误的评论比例为55.25%,但其显著提高了精确度至77.09%。此外,由于主要依赖推理期间的初始标记生成,结论优先模式的推理时间相对较短,与直接结论模式相当。鉴于在代码审查背景下精确度优先于召回率,结论优先模式在有效性和操作效率之间提供了平衡,从而成为首选方案。
4.3 在线产品性能
为了说明我们数据飞轮方法的有效性,我们跟踪了BitsAI-CR随时间的性能表现。
精确度趋势
图6展示了BitsAI-CR在18周内的精确度趋势。在最初的三周内,没有使用审查规则分类法和两阶段方法时,整体精确度停滞在约25%左右(此时RuleChecker和ReviewFilter之间没有区分)。在实施审查规则分类法并结合两阶段方法后,两个组件开始逐步改进。RuleChecker的精确度从最初的27.9%提高到62.6%,而ReviewFilter的精确度从35.6%上升到峰值75%。这些改进证明了我们方法的可持续迭代特性。值得注意的是,图6显示RuleChecker的精确度始终低于ReviewFilter的精确度,这使得ReviewFilter能够为用户提供更优的结果,从而验证了其关键作用。
过时率趋势
我们方法的有效性在图7中得到了体现,该图跟踪了18周期间Go语言中的三个关键指标。我们选择Go语言是因为它是字节跳动的主要语言之一,自早期代码审查起就建立了支持和优化流程,因此非常适合观察我们方法的效果。在前10周内,尽管审查规则数量持续增加,但过时率仍保持在约15%左右的相对稳定水平,即使精确度指标有所改善。在将审查规则扩展到73条后,我们观察到过时率显著增加,达到约20%,与63%的峰值精确度同时发生。在此之后,过时率暂时趋于稳定。从第14周开始,我们基于过时率和精确度指标优化BitsAI-CR,移除表现不佳的审查规则,导致过时率逐渐增加,最终在第18周达到26.7%的峰值。作为对比,字节跳动的人工过时率(表示人工审查标记的代码被修改的频率)在35%-46%之间波动,成为有效代码审查影响的基准。BitsAI-CR的过时率逐步接近人类水平的表现,证明了我们数据飞轮的有效性。
用户反馈与专家访谈
为了验证BitsAI-CR的有效性,我们进行了结合定量调查(N=137)和深入专家访谈(N=12)的综合评估。调查参与者随机选择了不同编程语言的用户,包括Go(50%)、前端技术(25%)以及其他语言如Java和Python(25%)。结果显示,用户对BitsAI-CR的代码审查价值和效果给予了强烈肯定,74.5%(102/137)的用户认可其有效性。在剩余25.5%(35/137)提出改进建议的用户中,反馈分为以下几类:不正确的评论(10.9%,15/137)、正确但不必要的评论(12.4%,17/137)、无关反馈(1.5%,2/137)以及理解困难(0.7%,1/137)。为了补充调查数据,我们对12位使用BitsAI-CR超过一个月的专家开发人员进行了结构化的10分钟访谈。参与者涵盖了前端、后端和算法开发等不同角色。表4总结了这些访谈的关键发现,按使用模式、质量评估、性能考量和功能请求进行分类。
4.4 大规模工业部署
在全面实施之前,我们进行了金丝雀测试以验证系统的性能和用户接受度。这种分阶段部署方法确保对用户的干扰最小化,同时也使我们能够快速收集用户反馈数据,并根据在线响应进行即时调整。目前,BitsAI-CR已全面部署于字节跳动的开发团队中。它拥有超过12,000名每周活跃用户(WAU)和210,000次每周页面浏览量(WPV),表明其被广泛采用并有效集成到开发工作流中。
此外,如图8所示,系统在第二周的留存率达到61.64%,并在八周内仍能保持约48%的高留存率。据我们所知,这是首个记录的大规模代码智能工具的留存率基准,为其他组织实施类似系统提供了宝贵的参考指标。
5 经验教训与实践见解
BitsAI-CR的大规模实施为我们提供了宝贵的经验,可以指导其他组织开发和部署自动化代码审查系统。我们在以下几个关键维度上总结了我们的主要发现:
审查规则分类法
通过系统化的代码问题分类、数据收集和性能评估推动自动化审查系统的构建。
我们的经验表明,定义良好的代码审查规则分类法是构建高效自动化审查系统的基础。分类法(表1)提供了以下关键优势:(1) 实现系统化的问题分类和检测,指导BitsAI-CR的开发,在Go语言中通过ReviewFilter将其精确度从30.92%提升至65.59%;(2) 促进结构化的数据收集和标注,确保训练数据的一致性质量;(3) 为评估和改进系统在不同审查维度上的性能提供明确标准。与缺乏系统化数据驱动演进的传统方法不同,我们的分类法驱动方法通过结构化问题分类和目标优化实现了更精确且可操作的代码审查。
两阶段审查生成
通过验证识别的问题增强自动化代码审查的可靠性。
我们的研究结果表明,结合RuleChecker和ReviewFilter的两阶段审查生成方法对于实现生产级可靠性的自动化代码审查至关重要。虽然LLM可以识别潜在问题,但它们倾向于产生误报和幻觉,因此需要一个强大的验证机制。我们通过将ReviewFilter作为专用验证模块的实施显著提高了BitsAI-CR的可靠性,整体精确度从60%提升至75%。这一改进表明,专用过滤模块是构建可靠的自动化代码审查系统的关键组件。
精确度和过时率指标
通过以用户为中心的评估引导数据飞轮优化。
我们的部署记录表明,在自动化代码审查的早期采用中优先考虑精确度而非召回率至关重要。高精确度能够在早期建立用户信任,避免打扰用户或导致他们放弃使用BitsAI-CR,鼓励持续使用系统并实现迭代改进。然而,我们发现传统的精确度指标单独使用并不足够,因为它们需要不可持续的手动标注,且无法捕捉用户对审查规则的接受度。为了解决这些局限性,我们引入了过时率作为补充指标,反映用户对审查建议的接受度。精确度和过时率指标的结合在推动我们的数据飞轮、促进大规模部署以及通过持续系统优化获得积极用户反馈方面发挥了重要作用。
6 相关工作
代码大型语言模型
代码LLM [10, 14, 53] 是更广泛LLM领域中的一个关键垂直方向。这些模型通过增强代码智能推动了软件工程的发展 [51]。近期的模型,包括GPT-4 [30]、Llama3 [6]、Qwen2.5-Coder [15] 和 DeepSeek-V2.5 [54],在多语言代码生成和调试任务中展现了显著能力。代码LLM正在改变软件开发的各个方面,涵盖代码生成 [3, 36, 42, 43]、程序修复 [23, 37]、日志解析 [20]、网页设计 [41, 45] 以及其他应用 [24, 46]。
基于LLM的代码审查
LLM在代码审查中的应用是一个活跃的研究领域,涵盖了实施和评估方法。开创性工作建立了深度学习在代码审查中的基础,相关研究如CodeReviewer [21] 和其他研究 [4, 19, 39, 49] 探索了用于审查任务的预训练模型。AutoCommenter [40] 通过分析代码是否符合最佳实践推动了该领域的发展,尽管其输出仅限于Google的最佳实践链接,而未提供具体的代码建议。LLaMA-Reviewer [25] 通过对LLAMA模型进行微调以实现代码审查,标志着一项重大进展。近期研究探讨了超参数、微调策略和提示工程 [9, 11, 31, 50],而关于多智能体系统的研究 [33, 38] 拓展了自动化审查能力。并行的评估工作包括EvaCRC [47],它引入了一个用于评估审查意见的框架。其他研究 [1, 5, 18, 29] 探讨了审查质量评估和人机一致性问题。值得注意的研究发现表明,LLM在错误检测方面可以超越人类表现 [27],同时研究也解决了审查过程中的认知偏差问题 [16]。
7 结论与未来工作
本文介绍了BitsAI-CR,一种全面的自动化代码审查系统,旨在解决企业规模审查流程中的效率瓶颈以及现有基于LLM解决方案的基本局限性,尤其是其评论效果不足和缺乏系统改进机制的问题。为此,我们引入了一种新颖的审查规则分类法,作为我们两阶段方法的基础:RuleChecker用于初步问题检测,ReviewFilter用于精确度提升。我们进一步提出了过时率指标,用于评估评论实用性,并通过数据飞轮机制推动系统化改进。我们的实证评估证明了这种方法的有效性,在评论生成中实现了可接受的精确度,并在Go语言审查中达到了具备竞争力的过时率。在字节跳动的成功部署验证了其在企业级软件开发环境中的可扩展性和实际价值。
我们的未来工作将集中于技术和服务增强的关键方向:首先,我们计划将语言覆盖范围从目前支持的五种主流编程语言扩展到对所有编程语言的全面覆盖。其次,我们将增强当前主要聚焦于函数级理解且上下文信息有限的审查规则,通过开发有效的跨文件审查能力。通过这些持续努力,我们力求丰富和强化我们的系统,以提供更全面、更深入的代码审查服务,最终帮助开发者提高代码质量和工程效率。

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)