很早的時候就想著用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: 8080spring:# Spring AI 配置ai:dashscope:api-key: ${DASHSCOPE_API_KEY}# GitHub App 相關配置
github:# App IDapp-id: ${GITHUB_APP_ID}# App 安裝后的 Installation IDinstallation-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 {// ...@Overridepublic ReviewResultDTO reviewCode(ReviewTaskDTO reviewTask) {// 1. 獲取代碼 diffString diff = githubAdapter.getPullRequestDiff(reviewTask.getOwner(), reviewTask.getRepo(), reviewTask.getPullRequestNumber());// 2. 準備 PromptString userMessage = "請評審以下代碼變更:\n" + diff;// 3. 調用 LLMString reviewContent = llmAdapter.generateReview(userMessage);// 4. 解析 LLM 響應并構建 ReviewResultDTO// ...return reviewResult;}
}
4.3. 與大模型交互
LlmAdapter
封裝了與 Spring AI 和通義千問模型的所有交互細節。
// LlmAdapter.java
@Component
public class LlmAdapter {private final ChatClient chatClient;@Autowiredpublic 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,可以顯著提升評審的準確性和深度,使其更貼合團隊的特定規范。