在上篇文章中,我們詳細介紹了 Discussion API 方案的前五個步驟,包含多專案管理、條件判斷、權限控管、diff 資料獲取和精確定位系統。今天我們將著重於 AI Agent 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)
}
}
]
}
五維度分析框架:
嚴格分級制度:
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: []
}
}];
}
GitLab Discussion Request
標題定位回應區塊json
代碼塊中的內容今天處理了 Code Review 核心邏輯,透過 Json 幫忙匹配與做判斷,下一篇會講解雙重留言機制設計。