跳至主要內容

OpenAl 代码自动评审组件

科哒大约 6 分钟

背景

诞生

设计思路原理图

  1. 基于gitlab的webhooks获取代码提交或者合并事件。
  2. 获取到事件之后通过本次ID,获取到变更的文件列表giff。
  3. 获取到变更的文件列表后,我们确定一个模型进行代码评审。
  4. 评审后的结果需要进行记录,落地形式较多,可以新建一个工程提交到功能里,或者直接落库,再或者使用gitlab的评论进行记录。这里使用的是评论进行记录,因为简单。
  5. 记录之后需要通知开发人员闭环,可以通过微信、飞书、或者邮件等。这里是基于企业微信的机器人进行通知,因为简单。

工程目录

项目地址:https://gitee.com/keyyds/gitlab-codereview/tree/masteropen in new window

SDK工程

测试工程

对外提供的接口

配置文件相关

  • gitlabUrl:

这里截取了主流程编排代码

  public void executeDispatch(HttpServletRequest request, String requestBody) throws Exception {
        // 解析请求头
        GitlabWebhookHeader gitlabWebhookHeader = GitlabWebhookHeaderUtil.parseHeader(request, requestBody);
        log.info("接收到的请求为:{}", JSON.toJSONString(gitlabWebhookHeader));
        // 根据不同的类型解析请求体
        if (!"Push Hook".equals(gitlabWebhookHeader.getGitlabEvent())) {
            return;
        }

        // 解析请求体,获取提交ID
        GitlabWebhookContent content = JSON.parseObject(requestBody, GitlabWebhookContent.class);

        // 可通知的分支
        List<String> branch = gitlabAiCodeReviewConfig.getBranch();
        String pushBranch = content.getRef().replace("refs/heads/", "");
        if (branch != null && !branch.isEmpty()) {
            if (!branch.contains(pushBranch)) {
               return;
            }
        }

        //  如果当前是推送提交类的事件,则解析请求body,获取提交ID
        GitlabServer gitlabServer = new GitlabServer(gitlabAiCodeReviewConfig.getGitlabUrl(), gitlabAiCodeReviewConfig.getGitlabToken());
        // 根据请求判断是什么类型的事件处理器,根据提交ID找到diff内容
        List<Diff> commitsChange = gitlabServer.getCommitsChange(content.getProject_id(), content.getCheckout_sha());

        commitsChange.forEach(diff -> {
                    try {
                        String recommend = codeReviewService.codeReview(diff.getDiff());
                        log.info("评审结果:{}", recommend);
                        // 结果处理,调用Gitlab API写入结果
                        Comment comment = gitlabServer.addComment(content.getProject_id(), content.getCheckout_sha(), recommend);
                        log.info("评论结果:{}", comment);
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("评审失败", e);
                    }
                }
        );
        String NotifyContent = "Ai代码评审结果通知:\n" +
                "项目名称:" + content.getProject().getName() + "\n" +
                "分支名称:" + pushBranch + "\n" +
                "提交ID:" + content.getCheckout_sha() + "\n" +
                "操作人:" + content.getUser_name() + "\n" +
                "查看连接:" + content.getProject().getHomepage() + "/commit/"+content.getCheckout_sha();

       WeChatRobot.sendMessage(gitlabAiCodeReviewConfig.getWebhookKey(), NotifyContent,"markdown");

    }

相关依赖

项目依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.6.6</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>32.1.2-jre</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>org.gitlab4j</groupId>
            <artifactId>gitlab4j-api</artifactId>
            <version>5.6.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.49</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>10.1.11</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

gitlab端配置

配置访问令牌

添加个人令牌,我们将过个人的方式获取gitlab的API访问权限。

得到API调用的能力。

gitlab AIP文档地址:
https://docs.gitlab.com/ee/api/commits.html#get-the-diff-of-a-commitopen in new window

https://docs.gitlab.com/ee/api/commits.htmlopen in new window

连接gitlab客户端

部分代码截图

大模型提问

申请使用智普

智普大模型免费申请使用。

智普:https://www.bigmodel.cn/console/overviewopen in new window

模型很多,有付费和免费的。免费的模型:GLM-4-Flash

新建API Key

在个人中心设置添加Apikey,后续需要在项目里配置使用。

对接智普

对接文档地址:

https://bigmodel.cn/dev/api/normal-model/glm-4#glm-4open in new window

提问模型

提问模型,就是针对变更代码,按你想要的方式进行评审的模型,也可自行配置。

这是工程里配置的默认的模型。

评审结果记录

借助gitlab自带的评论接口完成了,评审结果的记录方便查看。

通知

我司是基于企业微信办公的,这里开发选择了企业微信通知,方便查看。可自行拓展。

部署使用

  • 需要部署一个服务器评审服务器,暴露评审接口,或者借助现有的系统部署。
  • 需要评审的项目需要配置web钩子,就是配置评审接口。

启动评审系统

部署暴露评审接口。

配置钩子

在gitlab上配置需要评审的项目,配置钩子。

测试评审

完成上述两步之后,在项目里提交一次合并记录,验证。

总结

  1. 大模型的利用。
  2. 自定义的配置。
  3. 评审大模型该怎么确定。
  4. 进一步思考评审速度的提升。
  5. 更多的大模型利用方式。
上次编辑于:
贡献者: 黄科铭