很早的时候就想着用AI来做Code Review,最近也看到了一些不错的实现,但是没有一个使用Java来构建的,看的比较费劲,虽然说语言只是一种工具,但是还是想用Java重新写一遍,正好最近Spring AI Alibaba出了正式版,就拿来用了。
简单的效果图

1. 架构概览
本应用采用事件驱动架构,其核心工作流程如下:
- GitHub Webhook 触发:开发者在 GitHub 仓库中创建或更新一个 Pull Request (PR) 时,会触发一个预先配置好的 Webhook。
- 事件接收与处理:后端的 Spring Boot 应用通过
GitHubWebhookController接收该事件。 - 任务分发:
GithubWebhookServiceImpl解析 Webhook 负载,提取 PR 相关信息,并异步触发CodeReviewServiceImpl执行代码评审任务。 - 获取代码变更:
CodeReviewServiceImpl调用GitHubAdapter,通过 GitHub API 获取该 PR 的代码变更详情(diff)。 - 调用大模型分析:
LlmAdapter负责构建发送给大模型的 Prompt。该 Prompt 包含代码变更、预设的评审规则以及可选的 RAG(检索增强生成)知识。随后,它通过 Spring AI 的ChatClient将请求发送给阿里巴巴通义千问模型。 - 处理与发布结果:应用接收 LLM 返回的评审建议,将其格式化后,通过
GitHubAdapter调用 GitHub API,将评审评论发布到对应的 PR 下。
2. 依赖配置 (pom.xml)
<!-- Spring AI 核心与阿里巴巴通义千问集成 -->
<dependency>
<groupId>com.alibaba.cloud.ai</groupId>
<artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
</dependency>
<!-- GitHub API Java 客户端 -->
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.321</version>
</dependency>
spring-ai-alibaba-tongyi-spring-boot-starter:这是 Spring AI 对接阿里巴巴通义千问模型的关键,它提供了自动配置和ChatClient实现。github-api:一个便捷的 Java 库,用于与 GitHub REST API 进行交互。
3. 应用配置 (application.yml)
所有外部服务的凭证和行为都在 application.yml 中定义。
server:
port: 8080
spring:
# Spring AI 配置
ai:
dashscope:
api-key: ${DASHSCOPE_API_KEY}
# GitHub App 相关配置
github:
# App ID
app-id: ${GITHUB_APP_ID}
# App 安装后的 Installation ID
installation-id: ${GITHUB_INSTALLATION_ID}
# App 生成的私钥(Base64 编码)
private-key: ${GITHUB_PRIVATE_KEY}
# Webhook 使用的密钥
webhook-secret: ${GITHUB_WEBHOOK_SECRET}
spring.ai.alibaba.tongyi.*:此路径下的所有配置都用于设置通义千问模型。你需要提供一个有效的 API Key,并可以选择合适的模型。github.*:此处配置了 GitHub App 的认证信息。使用 GitHub App 而非个人访问令牌(PAT)是最佳实践,因为它提供了更细粒度的权限控制。
4. 核心代码实现
4.1. GitHub Webhook 接入
GitHubWebhookController 是应用的入口点。它负责验证和接收来自 GitHub 的 HTTP POST 请求。
// GitHubWebhookController.java
@RestController
@RequestMapping("/api/github")
public class GitHubWebhookController {
// ...
@PostMapping("/webhook")
public ResponseEntity<String> handleWebhook(
@RequestHeader("X-Hub-Signature-256") String signature,
@RequestBody String payload) {
// 1. 验证签名
// 2. 调用 IGithubWebhookService 处理业务逻辑
githubWebhookService.processPullRequestEvent(payload);
return ResponseEntity.ok("Event received");
}
}
4.2. Code Review 核心服务
CodeReviewServiceImpl 是业务逻辑的核心。它编排了整个代码评审的流程。
// CodeReviewServiceImpl.java
@Service
public class CodeReviewServiceImpl implements ICodeReviewService {
// ...
@Override
public ReviewResultDTO reviewCode(ReviewTaskDTO reviewTask) {
// 1. 获取代码 diff
String diff = githubAdapter.getPullRequestDiff(
reviewTask.getOwner(), reviewTask.getRepo(), reviewTask.getPullRequestNumber());
// 2. 准备 Prompt
String userMessage = "请评审以下代码变更:\n" + diff;
// 3. 调用 LLM
String reviewContent = llmAdapter.generateReview(userMessage);
// 4. 解析 LLM 响应并构建 ReviewResultDTO
// ...
return reviewResult;
}
}
4.3. 与大模型交互
LlmAdapter 封装了与 Spring AI 和通义千问模型的所有交互细节。
// LlmAdapter.java
@Component
public class LlmAdapter {
private final ChatClient chatClient;
@Autowired
public LlmAdapter(ChatClient chatClient) {
this.chatClient = chatClient;
}
public String generateReview(String codeDiff) {
// 系统消息,用于设定 AI 的角色和任务
String systemMessage = "你是一个资深软件工程师,擅长代码评审..."
// 用户消息,包含具体的代码变更
String userMessage = "请评审以下代码变更,并以JSON格式返回你的发现...\n\n" + codeDiff;
Prompt prompt = new Prompt(List.of(
new SystemMessage(systemMessage),
new UserMessage(userMessage)
));
ChatResponse response = chatClient.call(prompt);
return response.getResult().getOutput().getContent();
}
}
这里使用了 SystemMessage 来为 AI 设定角色和输出要求,这有助于获得更稳定和结构化的输出。
4.4. 发布评审结果
当 CodeReviewServiceImpl 获得格式化的评审结果后,会调用 ResultPublishServiceImpl,后者再通过 GitHubAdapter 将评论发布回 GitHub。
// GitHubAdapter.java
public void postReviewComment(String owner, String repo, int prNumber, String commentBody, String commitId, String path, int lineNumber) {
try {
GHRepository repository = getGithubClient().getRepository(owner + "/" + repo);
GHPullRequest pullRequest = repository.getPullRequest(prNumber);
pullRequest.createReviewComment(commentBody, commitId, path, lineNumber);
} catch (IOException e) {
throw new RuntimeException("Failed to post review comment to GitHub", e);
}
}
5. (暂时简单实现) 结合 RAG 提升评审质量
RAGService 为项目引入了检索增强生成(RAG)的能力。通过将内部的编码规范、最佳实践或常见错误模式文档化并存储在向量数据库(如 Elasticsearch)中,我们可以在生成 Prompt 前,先检索与代码变更最相关的信息。
将这些检索到的信息一并提供给 LLM,可以显著提升评审的准确性和深度,使其更贴合团队的特定规范。
1153

被折叠的 条评论
为什么被折叠?



