iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Software Development

AI 驅動的 Code Review:MCP 與 n8n 自動化實踐系列 第 21

[Day 21] 團隊使用 n8n + AI + API 做 Code Review 的最終方案:Discussion API 實戰 (中)

  • 分享至 

  • xImage
  •  

團隊使用 n8n + AI + API 做 Code Review 的最終方案:Discussion API 實戰(中)

前言

在上篇文章中,我們詳細介紹了 Discussion API 方案的前五個步驟,包含多專案管理、條件判斷、權限控管、diff 資料獲取和精確定位系統。今天我們將著重於 AI Agent prompt 資訊處理。

流程完整架構圖

AI 智能分析與回應處理

步驟 6:AI Agent 核心配置 (AI Agent 節點)

https://ithelp.ithome.com.tw/upload/images/20250923/20121499GqeHz48Erm.png

Model 與 Memory 設定

  • Model 選擇:專案採用 Gemini 作為主要分析引擎
  • Memory 配置:Simple Memory 設定為 20 個 Context Window Length,確保足夠的上下文記憶

Code Review Prompt 設計

我設計了一個結構化的 prompt,確保 AI 能夠提供專業且一致的 Code Review 建議:

請你扮演一位資深軟體工程師,針對程式碼進行全面性的 Code Review。請依照以下面向給出具體建議:

1. ✅ 程式邏輯是否正確、是否有潛在錯誤或邊界條件未處理
2. 🧹 是否符合的慣用寫法,例如錯誤處理、命名風格、簡潔性
3. 🔒 是否有安全性問題,例如硬編碼、未處理的錯誤、資源洩漏等
4. 🚀 是否有效能瓶頸,例如不必要的記憶體分配、重複運算、goroutine 使用不當
5. 📚 是否具備良好的可讀性與可維護性,包括註解、結構清晰度、模組化程度

在評估每個檔案時,請遵循以下結構化步驟:
1. 先逐個面向分析問題,並列出證據。
2. 綜合所有問題,決定 severity 等級。
3. 只在有明確證據時提升 severity,避免過度評估。

severity 等級的詳細定義(必須嚴格遵守):
- high(高風險):問題可能導致系統崩潰、安全漏洞、資料洩漏、嚴重效能衰退,或在生產環境造成重大損失。例如:未處理的 nil 指標、SQL 注入風險、無限迴圈。
- medium(中風險):問題可能引起偶發錯誤、非最佳實踐,但不立即危險。例如:未優化的迴圈、缺少錯誤檢查、輕微資源浪費。
- low(低風險):小問題,如命名不一致、缺少註解、多餘空白,但不影響功能或效能。
- no problem(無問題):不用輸出到 JSON,所有面向皆符合最佳實踐,無任何可改進點或者單元測試的 error 寫底線也是可以,放到 no problem 例如: req, _ := http.NewRequest("GET", "/ping", nil)

範例:
假設程式碼片段:
func add(a, b int) int { return a + b } // 簡單加法,無問題。
- 分析:邏輯正確、無錯誤;慣用寫法符合;無安全問題;效能佳;可讀性高。
- severity: no problem(不輸出到 JSON)。

另一範例:
func connectDB() { db, _ = sql.Open("mysql", "user:pass@tcp(host)/db") } // 硬編碼密碼。
- 分析:邏輯正確,但安全問題(硬編碼憑證);其他面向 OK。
- severity: high(高風險,因為安全漏洞)。
- issues_found: ["硬編碼憑證"]
- comment: "檔案中存在硬編碼資料庫憑證的安全漏洞,建議使用環境變數或秘密管理工具。"

以下是程式碼內容:

{{ $json["changes_with_first_line"].toJsonString() }}

---

你的回覆必須嚴格遵守以下結構,且不得包含標題與 JSON 塊以外的任何文字:
1. 先輸出標題:GitLab Discussion Request
2. 然後立即輸出以 ```json

JSON 格式如下(抓取元 input json 資料不要異動):

每個檔案最多一個討論

討論行對應該檔案的第一個變更行

comment 必須包含該檔案所有重要問題的綜合評論,使用繁體中文

issues_found 為陣列,每項為短字串描述主要問題,不可用段落文字

severity 分為四個等級:high(高風險)、medium(中風險)、low(低風險)、no problem(無問題)。請分析所有檔案,但只在 JSON 回應中輸出 severity 為 high、medium、low 的檔案。
如果檔案評估為 no problem,則不要在 gitlab_discussions 陣列中包含該檔案。

回應的 position 拿取原本的資料 {{ $json["changes_with_first_line"].toJsonString() }}

```json
{
  "gitlab_discussions": [
    {
      "file_path": "<檔案完整路徑>",
      "comment": "<針對整個檔案的重要問題綜合評論,繁體中文>",
      "severity": "high|medium|low|no problem",
      "issues_found": ["短字串描述主要問題"],
      "position": {
        "base_sha": "<base sha>",
        "head_sha": "<head commit sha>",
        "start_sha": "<start commit sha>",
        "position_type": "text",
        "new_path": "<檔案完整路徑>",
        "old_path": "<檔案完整路徑>",
        "new_line": null or 數字(依照 input),
        "old_line": null or 數字(依照 input)
      }
    }
  ]
}

Prompt 設計精髓

五維度分析框架:

  1. 邏輯正確性 ✅:核心功能邏輯和邊界條件處理
  2. 程式品質 🧹:代碼風格和最佳實踐遵循
  3. 安全性 🔒:潛在安全風險和漏洞識別
  4. 效能 🚀:性能瓶頸和資源使用優化
  5. 可維護性 📚:代碼可讀性和架構清晰度

嚴格分級制度:

  • 採用四級風險評估(high/medium/low/no problem)
  • 提供具體範例避免主觀判斷
  • 只輸出有問題的檔案,減少雜訊

步驟 7:Discussion 資訊解析 (程式節點)

https://ithelp.ithome.com.tw/upload/images/20250923/20121499WysVl97zVu.png

挑戰與解決方案

AI 回應的是自然語言文本,需要可靠地提取其中的結構化 JSON 資訊。我們採用關鍵字匹配 + JSON 解析的混合策略:

// ===== 只抓 GitLab Discussion Request =====
function extractGitlabDiscussion(text) {
  if (!text) return null;

  // 找到 GitLab Discussion Request 標題
  const marker = 'GitLab Discussion Request';
  const markerIndex = text.indexOf(marker);
  if (markerIndex === -1) return null;

  // 從 marker 開始找 ```json ... ```
  const jsonStart = text.indexOf('```json', markerIndex);
  const jsonEnd = text.indexOf('```', jsonStart + 1);
  if (jsonStart === -1 || jsonEnd === -1) return null;

  // 擷取區塊,去掉 ```json
  const jsonStr = text.slice(jsonStart + 7, jsonEnd).trim();

  try {
    return JSON.parse(jsonStr);
  } catch (err) {
    console.error('GitLab Discussion JSON 解析失敗:', err);
    return null;
  }
}

try {
  // 取得 AI 回應字串
  const aiResponse = $json.output 
    || $json.response 
    || $input.all()[0]?.json?.output 
    || $input.all()[0]?.json?.response 
    || '';

  if (!aiResponse) {
    return [{
      json: {
        summary: '錯誤:未收到 AI 回應',
        discussions: []
      }
    }];
  }

  // 解析 GitLab Discussion JSON
  const parsedData = extractGitlabDiscussion(aiResponse);

  if (parsedData && parsedData.gitlab_discussions?.length > 0) {
    return [{
      json: {
        summary: `找到 ${parsedData.gitlab_discussions.length} 個討論項目`,
        discussions: parsedData.gitlab_discussions
      }
    }];
  }

  return [{
    json: {
      summary: 'AI 回應中沒有需要討論的異常檔案',
      discussions: []
    }
  }];
} catch (error) {
  return [{
    json: {
      summary: `執行失敗:${error.message}`,
      discussions: []
    }
  }];
}

解析策略說明

  1. 標題匹配:透過 GitLab Discussion Request 標題定位回應區塊
  2. JSON 提取:精確提取 json 代碼塊中的內容
  3. 容錯處理:完整的錯誤處理和異常回饋機制
  4. 結果分類:根據解析結果決定後續處理流程

小結

今天處理了 Code Review 核心邏輯,透過 Json 幫忙匹配與做判斷,下一篇會講解雙重留言機制設計。


上一篇
[Day20] 團隊使用 n8n + AI + API 做 Code Review 的最終方案:Discussion API 實戰 (上)
下一篇
[Day 22] 團隊使用 n8n + AI + API 做 Code Review 的最終方案:Discussion API 實戰 (下)
系列文
AI 驅動的 Code Review:MCP 與 n8n 自動化實踐22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言