使用LLM进行自动代码审查

2024年08月27日 由 alex 发表 73 0

在本文中,我们将介绍 Faire 为实现一系列特定上下文自动审查而开发的审查生命周期和 RAG(检索增强生成)设置。我们还将重点介绍我们的测试覆盖率审查,该审查可突出显示覆盖率低的区域,并建议增加测试用例,从而展示审查自动化的灵活性和价值。


Fairey,我们的 LLM 协调器服务

Faire 开发了一个 LLM 协调器服务,我们将其命名为 Fairey 。该协调器服务可处理用户的聊天请求,并将其分解为产生响应所需的所有必要步骤。这包括调用 LLM 模型、获取额外信息、调用函数和其他各种逻辑。


Fairey 与 OpenAI 的助手 API 高度集成。我们创建了一个简单的用户界面来管理人工智能助手,例如调整助手的指令或添加它可以调用的函数。功能赋予助手额外的能力,例如获取额外的信息--这种技术被称为 RAG(Retrieval Augmented Generation)。


RAG 正在迅速成为一种行业标准方法,为 LLM 提供必要的信息,以便其执行特定的任务。LLM 是根据极其广泛的信息集进行培训的,但通常不会使用贵公司的专有数据。而且,即使你已经开始像 Faire 一样对开源模型进行微调,LLM 通常仍然需要任何特定案例的信息--在我们的审查管道中,这就是关于正在审查的代码变更的信息。


2


每个函数调用都在协调服务中定义了一个回调,只要 GPT 认为应该调用,我们就会调用。这就允许 Fairey 决定何时获取所需的数据,而不必在主提示中发送大量额外信息。


审核生命周期

Fairey 还与 Github 的 webhooks 相连接,只要拉取请求上发生有趣的事情,webhooks 就会发送事件有效载荷。我们以多种方式对 Github 的每个 webhook 作出反应,包括检查是否有任何自动审查已准备好处理拉取请求。对于符合审查标准(如编程语言或特定差异内容)的拉取请求,Fairey将与 OpenAI 进行交互,以执行审查。


3


与 OpenAI 交互后,我们会检查输出结果,看看 Fairey 是否有什么有用的信息。如果有,我们就会在拉取请求上发布评论。评论通常包括评论和提示,甚至可能包括对代码的具体修改建议。


为避免重复评论,Fairey 留下的每条评论都会包含一些隐藏的元数据,以便我们检查哪些内容已被涉及。这样还可以继续之前的审查线程,或将之前审查的输出作为增量审查的输入。


测试覆盖审查

为了更好地展示 Faire 的自动审查是如何工作的,我们将深入了解测试覆盖率审查。测试覆盖率是一种衡量特定代码分支在运行测试套件时是否被实际执行的方法。举个简单的例子,让我们想象一个正在实现新功能的拉取请求,它使用了设置框架中的一个新设置。代码可能是这样的:


const isSettingEnabled = getSettingValue();
if (myNewSetting) {
  doTheNewThing();
} else {
  doTheOldThing();
}


测试覆盖率告诉我们,我们的测试是否覆盖了启用和未启用设置的代码分支。也许我们还没有为新代码添加测试,而代码审查员会指出我们需要这样做!


在我们的前端(Web)代码库中,Faire 使用 Jest 作为单元测试套件。我们要求面向用户的代码区域必须有最低覆盖率。我们在拉取请求中的测试覆盖率是以增量方式计算的,这意味着当我们创建拉取请求时,我们的 CI 系统会执行带有 --changedSince 标志的测试套件,导致 Jest 只执行与拉取请求中包含的源文件有依赖关系的测试。


4


每当我们收到来自 Github 的 Webhook,说明测试覆盖率检查运行已完成并出现失败结果时,就会触发测试覆盖率审查。当覆盖率检查失败时,意味着拉取请求中的增量覆盖率低于我们要求的覆盖率阈值。通常,这是因为作者添加了新的源代码文件,却没有相应的单元测试,或者在代码中创建了现有测试未覆盖的新分支。


测试覆盖率审查使用一个自定义助手(如上截图所示)。它可以访问几个重要的功能工具,包括:

  • fech_github_diff 抓取拉取请求中的更改差异
  • fetch_github_pull_request 用于获取拉取请求的元数据,如标题、描述等。
  • fetch_code_coverage_report 用于从 CI 的构建工件中加载 lcov 报告
  • fetch_github_file_contents 用于加载给定文件的全部内容。


辅助指令与系统提示信息同义,内容如下:


You are an expert React and Typescript programmer.
Using the test coverage reports and contents of source code and corresponding
test files, suggest new test cases that would increase coverage of the source
code.
Test files in our frontend codebases are located in a `./__tests__/` folder`./__tests__/` folder
next to the source code, with `*.test.ts` suffix instead of `*.ts`. A couple
of examples,
```yaml
- source: `src/something.ts`
tests: `src/__tests__/something.test.ts`.
- source: `app/home/utils.ts`
tests: `app/home/__tests__/utils.test.ts`
```


我们的代码库会在每个拉取请求中收集 lcov 代码覆盖率报告。测试覆盖率审核人员会被指示使用覆盖率报告来确定代码中覆盖率较低的区域。


除了这些系统级的助理指令外,审查还有一个特定的提示模板。发送的聊天信息大致如下


You are performing a code review of ${diffSource}. The PR has failing test coverage checks for ${failingCoverage.join(",")}.
Use the diff and the code coverage report to identify the changes in the PR that are not covered by tests.
For those changes, suggest test cases that should be added to the code.
Use the existing test file as a reference when suggesting test cases. Do not suggest cases that are already covered by the existing tests.


当用户提出拉取请求时,我们的构建管道最终会报告测试覆盖率检查运行失败。这将导致 Fairey 使用上述提示启动助理聊天。为了生成回复,ChatGPT 将发出函数调用,由 Fairey 执行并提交回 ChatGPT,最终生成回复消息。


然后,我们使用回复制作 Github Review,并将其发布到拉取请求中。


5


评估审查

LLM 的输入非常灵活,但输出也同样千变万化。GPT(生成式预训练转换器)模型只是一种预测模型,它们可能会犯错误、产生幻觉、输出过于冗长或不相关的内容。我们使用两个信号来评估评论的质量:一个是定量信号,另一个是定性信号。我们的定量评估包括使用 LLM 评估框架,而定性评估则包括对最终用户(我们的工程师)进行调查。


6


为了量化质量,我们建立了一套测试用例,对审查进行迭代,并重新运行这些测试用例,计算正确性得分。为了实现这一流程,Faire 使用了 LLM 评估工具,如 Gentrace、CometLLM 或 Langsmith 提供的工具。每当我们进行审查时,都会将输入和输出转发给评估工具。每个输入/输出对都可以用来创建一个测试用例。然后,当我们迭代审查(如调整提示、更改模型、获取不同数据等)时,我们可以在所有测试用例中重新运行审查流水线。然后,我们使用 LLM 来评估结果的质量。


固定装置

拉取请求审查的性质非常短暂。通常情况下,当工程师准备对行为进行迭代并重新评估时,与审查相关的拉动请求信息已经发生了变化。


为了适应这种情况,Fairey 支持 “固定 ”功能,将函数调用的输出保存为快照,以便在以后的运行中重新使用。我们使用 OpenAI 线程历史记录来实现这一功能,将函数调用的结果提取为夹具文件并上传到存储空间。以后运行审查时,我们会读取这些固定文件,并将其作为 ChatGPT 在调用函数时应该给出的重载文件传递给 Fairey。


自动审查的早期影响

在 Faire,我们相信提高生产力。使用 LLMs 的自动化审查有助于实现这一目标,它简化了审查流程,减少了对简单问题的审查延迟,并使我们的人才能够专注于审查中最有影响和最复杂的部分,例如正确满足产品要求、实现简洁的架构、长期可维护性和适当的代码重用。


到目前为止,我们已经看到了自动化审查的成功--以积极的用户满意度和高准确性来衡量:

  • 执行风格指南
  • 评估标题和描述的质量
  • 诊断构建失败,包括发布自动修复操作
  • 建议额外的测试覆盖范围
  • 检测向后不兼容的更改


仍有发展空间--对于每一种新的审查类型,输出质量最初都会有很大差异。我们发现,在使用 LLM 时,复杂的输入会带来难以预测的输出。要达到 C 的三要素(一致、简洁和正确),就需要对输入内容和结构进行大量的改进、广泛的测试用例集以及使用更复杂的提示技术,如自我评估和 CoT(思维链)。利用我们的迭代周期,工程师们能够自信地对提示和功能进行迭代,以提高效率。


如果使用得当,LLM 可以为工程师提供令人兴奋的全新帮助,帮助他们快速向用户交付优质产品。


文章来源:https://medium.com/faire-the-craft/automated-code-reviews-with-llms-cf2cc51bb6d3
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消