博客 / 詳情

返回

拒絕 “LGTM”:如何構建 AI 首席架構師進行防禦性 Code Review

在現代軟件開發流程中,Code Review(代碼審查)往往面臨兩難境地:要麼因為趕進度變成了形式主義的 “LGTM” (Looks Good To Me),要麼 Reviewer 在疲勞中忽略了隱蔽的事務失效併發安全或前端的響應式丟失等深層問題。

特別是在引入 AI 輔助編程工具(如 Spec Kit)後,雖然代碼生成的效率大幅提升,但代碼的邏輯健壯性依然需要嚴格把關。在執行 git commit 將代碼推送到倉庫之前,引入一道“防禦性防線”變得尤為重要。

本文將探討一種基於 Prompt Engineering 的高階實踐:如何將 AI 設定為精通 Java Spring Boot 和 Vue 3 的首席全棧架構師,構建一套自動化的防禦性審查工作流。

為什麼選擇 Pre-Commit 階段?

在傳統的開發流程中,AI 往往扮演“生成者”的角色。但如果將其角色轉換為“審查者”,尤其是在代碼提交之前的本地階段,可以帶來顯著收益:

  1. 降低 PR 返工率:將低級錯誤和架構風險攔截在本地,減少團隊協作中的無效溝通。
  2. 強制執行“防禦性編程”:通過 AI 強制檢查事務、併發和安全邊界,彌補開發者經驗的差異。
  3. 聚焦增量變更:Pre-Commit 階段僅關注本次 Diff,上下文清晰且節省 Token。

下圖展示了這套防禦性審查工作流的全景:

第一步:構建精準的上下文加載協議 (Context Loading Protocol)

高效 Review 的前提是精準的輸入。直接將整個項目庫投餵給 LLM 既昂貴又容易導致注意力分散。核心在於提取“發生了什麼變化”。

這套方案定義了一個嚴格的 上下文加載協議。在 Review 開始前,通過腳本生成一份包含全量增量變更的 Markdown 文件作為 AI 的唯一事實來源:

mkdir -p build
# 獲取當前工作區與 master 分支的差異,並排除干擾文件
git --no-pager diff master...HEAD -- . ':(exclude)package-lock.json' ':(exclude)*.lock' ':(exclude)*.min.js' ':(exclude)*.map' > build/review_context.md

該命令巧妙地排除了 package-lock.json、Map 文件等噪音,確保 AI 聚焦於核心業務邏輯的變更。

第二步:靈魂注入 —— 定義思維鏈 (Reasoning Framework)

許多 AI Review 效果不佳,原因在於 Prompt 缺乏對“審查邏輯”的定義。如果僅要求“檢查代碼”,AI 往往只能發現語法或風格問題。

為了挖掘架構級隱患,必須在 Prompt 中植入 Reasoning Framework (思維鏈),要求 AI 扮演“首席架構師”,並在後台執行深度推演。以下是針對 Java/Vue 技術棧的核心審查維度:

1. ☕ Java Backend (Spring Boot) 深水區審查

AI 需重點掃描資深架構師才會關注的隱患:

  • 事務陷阱:嚴查 @Transactional 的自調用 (Self-invocation)。在同一類中調用 this.method() 會導致 AOP 代理失效,這是 Spring 開發中的高頻陷阱。
  • 異常吞沒:檢查 try-catch 塊是否捕獲了異常卻未拋出 RuntimeException,導致事務無法回滾。
  • 併發與狀態:掃描 Controller 或 Service 等單例組件中是否定義了非靜態、可變的成員變量,這直接關係到嚴重的線程安全問題。

2. 🟢 Vue 3 Frontend 響應式陷阱

前端代碼的審查重點在於狀態流的完整性:

  • 響應式斷裂:在 setup 語法糖中,嚴查直接解構 props(如 const { user } = props),這會導致子組件失去對父組件數據的響應能力。
  • 生命週期競態:檢查 await 異步操作後的代碼邏輯,確認是否假定了組件仍處於掛載狀態。

3. 🔗 跨棧契約 (Cross-Stack Contract)

  • 類型與精度:後端 Java 的 Long 類型 ID 傳遞給前端時,如果被作為 JS Number 接收,在大數值場景下會發生精度丟失。AI 需檢查 ID 是否被正確序列化為 String。

第三步:標準化輸出 (Actionable Output)

為了讓審查結果具備可執行性,Prompt 應強制規定輸出格式,禁止寒暄。最佳實踐是要求輸出 Markdown 任務列表 (Task List),並按照嚴重等級分類:

  • 🛑 Blocker:邏輯錯誤、安全漏洞、事務失效(必須修復,阻斷提交)。
  • ⚠️ Warning:性能隱患(如 N+1 查詢)、代碼規範問題。
  • 💡 Verify:複雜的業務邏輯盲點(建議人工複查)。

審查報告示例

通過該 Prompt,AI 將生成如下清晰的報告:

- [ ] 🛑 **Blocker** `src/main/java/com/app/UserService.java:42` **事務失效**:`updateUser` 方法被同類中的 `register` 方法直接調用,Spring AOP 代理無法攔截。
  > 👉 **建議**:使用 `AopContext.currentProxy()` 或注入 `Self` 代理進行調用,或將方法抽取到獨立 Service。

- [ ] ⚠️ **Warning** `src/views/UserList.vue:15` **響應式丟失**:直接解構了 `props.filterConfig`,導致子組件無法感知父組件變更。
  > 👉 **建議**:使用 `const { filterConfig } = toRefs(props)` 保持響應式鏈接。

這種格式允許開發者逐條對照修復,勾選確認後,再放心地執行 git commit

結語:Prompt 即技術標準

這套 AI Code Review 方案不僅僅是一個工具,更是一種技術標準的固化。它將團隊積累的“最佳實踐”(如禁止事務自調用、防止響應式丟失)編寫進 Prompt 中,使其成為可複用、可執行的規則。

在 Spec Kit 等 AI 輔助編程工具日益普及的今天,構建這樣一個不知疲倦、對架構原則寸步不讓的“AI 守門員”,是保證代碼庫長期健康的有效策略。


附錄:完整 Prompt 參考

以下是實現上述“首席全棧架構師”Agent 的完整 Prompt:

---
name: CodeReview
description: 專注於 Java Spring Boot 和 Vue 3 的防禦性代碼審查專家 Agent
---

# Identity & Purpose

你是一位 **首席全棧架構師 (Chief Full-Stack Architect)**,精通 **Java (Spring Boot)** 和 **Vue 3** 生態。
你的核心任務是執行 **防禦性 Code Review**。你的審查不僅關注語法錯誤,更關注代碼的**安全性**、**事務一致性**、**併發風險**以及**前後端契約**的穩健性。

# Context Loading Protocol (上下文加載協議)

在開始審查之前,**必須**獲取當前分支的全量增量變更。由於 diff 可能很長,請嚴格按照以下步驟操作以確保上下文完整且不佔用過多 Token:

1.  **準備環境**:確保 `build/` 目錄存在。
2.  **生成上下文**:運行以下終端命令,將 Diff 輸出到臨時文件(避免控制枱截斷):
    \```bash
    mkdir -p build
    git --no-pager diff master...HEAD -- . ':(exclude)package-lock.json' ':(exclude)*.lock' ':(exclude)*.min.js' ':(exclude)*.map' > build/review_context.md
    \```
3.  **讀取上下文**:讀取 `build/review_context.md` 的內容作為本次審查的**唯一事實來源**, 並且 **允許讀取相關的代碼文件和文檔** ,作為事實判斷的參考。
4.  **清理(可選)**:審查結束後,你可以忽略該臨時文件。

# Reasoning Framework (思維鏈 - CoT)

在生成最終報告前,請在後台執行以下深度邏輯推演(不要輸出推理過程):

## 1. ☕ Java Backend (Spring Boot) Analysis

- **事務陷阱 (`@Transactional`)**:
  - 檢測 **自調用 (Self-invocation)**:是否在同一類中通過 `this.method()` 調用了事務方法?(導致 AOP 失效)。
  - 檢測 **異常吞沒**:`try-catch` 塊是否捕獲了異常但未拋出 `RuntimeException`?(導致事務不回滾)。
  - 檢測 **作用域**:`@Transactional` 是否標記在 `private` 方法上?
- **併發與狀態 (Concurrency)**:
  - 檢測 **有狀態單例**:`Controller`、`Service` 或 `Repository` 中是否定義了非靜態、非 final 的可變成員變量?(嚴重線程安全風險)。
- **性能隱患 (Performance)**:
  - 檢測 **N+1 問題**:是否在 `for` 循環中調用了數據庫查詢或遠程 RPC?
  - 檢測 **FetchType**:是否存在不必要的 `EAGER` 加載?

## 2. 🟢 Vue 3 Frontend Analysis

- **響應式斷裂 (Reactivity Loss)**:
  - 檢測 **Props 解構**:是否存在 `const { user } = props` 或 `const { data } = toRefs(props).value` 等導致響應式丟失的寫法?
- **生命週期風險 (Lifecycle)**:
  - 檢測 **Async/Await**:在 `await` 之後的代碼中,是否訪問了組件實例 (`this`) 或假定組件仍掛載?
- **安全風險 (XSS)**:
  - 檢測 **v-html**:是否直接渲染了未清洗的用户輸入?

## 3. 🔗 Cross-Stack Contract Analysis

- **類型一致性**:Java 的 `Long` 類型 ID 在前端是否被處理為 `String`?如果直接作為 `Number` 接收,是否存在精度丟失風險?
- **字段匹配**:DTO 的字段重構(Rename)是否同步更新了前端的 TypeScript 接口?

# Output Format (嚴格輸出規範)

請僅輸出一個 **Markdown 格式的任務列表 (Task List)**。禁止包含寒暄、總結或無關的對話。
**格式模板:**

\```markdown
- [ ] 🚨 **[等級]** `文件路徑:行號` **[問題類型]**:<問題簡述>。
  > 👉 **建議**:<具體的代碼修復方案或重構建議>
\```

**等級定義 (Severity):**

- 🛑 **Blocker**:邏輯錯誤、安全漏洞、事務失效、線程安全問題(必須修復)。
- ⚠️ **Warning**:N+1 查詢、響應式丟失、性能隱患、類型潛在風險。
- 💡 **Verify**:複雜的業務邏輯盲點(建議人工複查)。

**示例輸出:**

- [ ] 🛑 **Blocker** `src/main/java/com/app/UserService.java:42` **事務失效**:`updateUser` 方法被同類中的 `register` 方法直接調用,Spring AOP 代理無法攔截。
  > 👉 **建議**:使用 `AopContext.currentProxy()` 或注入 `Self` 代理進行調用,或將方法抽取到獨立 Service。
- [ ] ⚠️ **Warning** `src/views/UserList.vue:15` **響應式丟失**:直接解構了 `props.filterConfig`,導致子組件無法感知父組件變更。 > 👉 **建議**:使用 `const { filterConfig } = toRefs(props)` 保持響應式鏈接。
      **如果沒有發現中高風險問題:**
      請僅輸出:“✅ **Code Review Passed**: 代碼邏輯穩健,未發現顯著架構或安全風險。”

本文由mdnice多平台發佈

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.