AIGC重塑软件工程CodeReview篇:IDE插件+DevOps平台协同组合

代码为聘礼 2024-02-21 02:25:39

在软件开发团队里,Code Review 是非常重要的一个质量保障环境。好的 Code Review 能促进团队成长,差的 Code Review 形同流水。而在有了 LLM 之后,事情又发生了一些微妙的变化:

随着代码产量上升,需要 review 的代码越多。

大量未经仔细阅读的 AI 代码。即由 GitHub Copilot、ChatGPT 生成的可以 work的代码,可能没有经过他的 pair (人类)进行过仔细的 review。

LLM 也可以帮我们 review 代码了。

过去,一个小规模(6 人)左右的开发团队,平均每天得花费 30 分钟在代码检视上(CodeReview)。所以,不管,从提效的角度来说,还是从未来需要更多的代码检视时间,改善 Code review 迫在眉睫。

TL;DR 版本:

AutoDev 插件更新到 1.3.0 即可体验初步版本的 Code Review

使用 DevOpsGenius 即可体验工具测:https://github.com/unit-mesh/devops-genius

思考:为什么 Code Review 需要协同组合?

首先,让我们来回顾一下:什么是好的技术实践 —— 诸如于如何写好提交信息?

1. 需求关联代码变更!

在编写提交信息里,又或者在 DevOps 标准化初中,业内的最佳实践是:保持提交信息与用户故事、需求的关联。

诸如于,我们使用的是 JIRA 工具里,需要结合 JIRA ID 在提交信息里;使用的是 GitHub 时,则使用 # + issue id 的形式,如下所示: feat(devops): init first review command #8 。基于此,我们来将需求信息与代码变更保持一致,方便于回顾。

问题来了,如果开发人员不愿意写好提交信息怎么办?—— 自然是用 AIGC 来自动生成了。

2. AIGC 不能取代质量管理工具!

了解完 AIGC 的基本原理之后,大部分人会关注 AIGC 生成代码的安全性问题。而对于代码的安全性问题,在没有 AIGC 之前,我们会采用 Sonarqube、JavaLint、ArchGuard、Feakin 等工具来监控、改进系统的代码、架构质量等等。

考虑到 AIGC 是受 prompt 影响结果的,并且在长 prompt 下如何失焦,所以在可靠性上不如静态代码分析来得稳定。

3. 我们关心的是业务还是代码问题?

事实上,根据不同的 Code Review 形式,诸如于时间(每日、每周、每次发布)、节点(发布前),每个人会关注的内容是有非常大差异的。诸如于,当我处在团队的不同阶段时:

初级开发,关注于是不是符合代码规范,即其他人的改进意见。

中级开发,关注于~~能不能按时下班~~ 。

高级开发,关注于其他人写的合不合理,是否偏离业务。

技术负责人,在 review 的同时,关注于是否会影响整体进度 —— 诸如于是否能按时完成。

所以,从 review 的内容来看,主要会关注于业务和技术两部分。而不同的人所关注的是不一样的,该交由传统工具的部分,还是应该交由传统工具。

设计:AIGC 辅助的 Code Review

在使用 AIGC 辅助 Code Review 上,网上已经有各种五花八门的解决方案,我们也只是其中的一种方案。

门槛:良好的代码提交实践

回到先前我们在构建 AutoDev 的经验上,对于 Code Review 来时,难点并非在于 Review 点的设计,而在于如何处理上下文。与其他的领域不同的是,如果采用的不是小步提交的方式,那么在 review 时难点很大。

简单来说:如果代码提交实践做不好,那么 AIGC 的 Code review 会非常鸡肋。过于发散的意图,使得我们无法关注到每一个小点。

模拟真实 Code Review 设计

在设计我们的工具时,大致分析了网上的各类 prompt。为此,我们发现 prompt 并不是难点,结合 AIGC 进行 Code Review 的难点在于:如何模拟真实的 Code Review。只有了解、深入真正的 Code Review 实践,那么我们才能设计出好的工具。

在日常的 Code Review 中,首先,我们需要知道对应的业务背景;其次,忽略大量无关的非代码变更,诸如文档更新、测试数据更新等等;最后,如果变更复杂的场景,则跳过 patch,直接查看代码。

基于此,我们构建了 Code Review 的 Prompt 演进路线。第一个版本则比较简单,即围绕于优化 prompt 长度来包含更多的上下文:

结合 DevOps 平台获取业务信息。

过滤非必要的文件。

过滤 patch 中非必要的内容。

优化生成的结果。

即通过实践 + 配置化的方式,来突出重点、核心的内容,而忽略无关紧要的东西。

实现:AutoDev + DevOpsGenius

不论是在 IDE 端,还是在平台端,在当前的第一个版本里,两个处理逻辑都是相似的。主要过程如下(由 ChatGPT 生成):

获取提交消息:从版本控制系统中获取一系列提交消息。

解析提交消息:将提交消息解析成可处理的格式。

筛选需要审查的提交:根据一些条件,决定哪些提交需要进行代码审查。

获取相关用户故事信息:提取提交消息中的问题标识,然后获取相关的用户故事标题。

生成差异内容:生成提交之间的差异内容以进行审查。

发送审查请求:向审查工具发送审查请求并等待审查结果。

比较大的差异是两个 Prompt 是针对不同场景下的,IDE 是针对于开发人员想知道业务变化,而平台端则是对语法等进行检查。

Prompt 设计

先看 Prompt 中的上下文(PS:更详细可以阅读代码中的 simple-review.open-ai.vm 模板文件)。

.....

Business Context: ${context.businessContext}

Commit Message: ${context.fullMessage}

Code Changes: ${context.changes}

简单来说:

Business Context 是指从看板、需求系统中获取的业务上下文。

Commit Message 是指用户编写的提交信息。

Code Changes 则是根据提交之前的 patch 文件。

需要注意的是:由于大部分编码大模型语料和数据中都是基于 patch 来进行训练的,所以它的效果会比较好。所以,需要根据不同的模型来选择,理想的 changes 形式。

结合提交信息与过滤配置

如下是 Conventional Commits 进行的提交格式示例:

从中解析出我们所需要的 type、 references 等信息,作为过滤条件的一部分:

// 从配置文件中读取,并过滤掉不需要 review 的 commit,诸如 chore、ci, docs 等

// 如果没有配置,则全部需要 review

val filterCommits = parsedMsgs.filter {

if (it.meta.containsKey("type")) {

val type = it.meta["type"] as String

project.commitLog?.isIgnoreType(type) ?: true

} else {

true

}

}

进而只呈现关键的上下文,减少 prompt 长度。更详细的可以阅读 AutoDev 和 DevOps Genius 的代码和文档:https://devops.unitmesh.cc/code-review 。

IDE 与 DevOpsGenius 平台中的 Prompt 差异

在结合 IDE 的 Code Review 里,我们往往会选择自己的多次提交,来讲解对应的业务功能、实现等等。而这也意味着,在 IDE 的场景下,让 AI 来 summary 更容易超出上下文限制。所以,需要添加更多的 review 方式来支持。

而在平台上时,更适合结合单次提交或者 Pull Request 的方式来进行。尽管,如此,但是在基本的 patch 优化上都是相似的策略。

不足之处

事实上,如果你参与到真正的团队 review 里,会发现哪怕是同一个部门下,不同团队的 Code Review 方式,以及其所关注的点是不一样的。如何有机结合关注点与 prompt 进行整合,是我们下一步需要考虑的。

未来:演进

结合 LLM 重塑软件开发中的 DevOps 实践,并不是一件简单事情,如果你有兴趣,欢迎来一起探索:https://github.com/unit-mesh/devops-genius 。

0 阅读:0

代码为聘礼

简介:感谢大家的关注