大促備戰中的代碼評審困境與破局
雙十一大促是系統穩定性的終極“大考”。為規避上線風險,技術側會啟動系統封板管控,主動將非緊急需求的發布窗口前置。這一舉措在保障系統穩定性的同時,也必然導致研發需求的前置與集中,使得封板前的代碼評審任務量顯著增加。我們面臨著一個嚴峻的“量與質”的挑戰:
如何在時間緊、任務重的雙重壓力下,確保代碼評審的效率與質量,從而前置發現潛在風險,有效攔截線上BUG?
傳統的代碼評審模式在此場景下效率低、質量差(風險遺漏的可能性高),而現有的AI輔助工具又因誤報率高而陷入尷尬:產生的多數評審意見并無實質幫助,工程師仍需花費大量時間進行判斷與篩選。
正是在此背景下,【供應鏈技術部-商家導入研發組】在AI代碼評審方面進行了一些探索,嘗試將知識工程代碼知識檢索能力與AutoBots(已更名為:JoyAgent)知識庫檢索能力相結合,構建了一套代碼評審系統。這套雙RAG架構為我們的代碼評審工作提供了一些新思路,在此分享出來,希望與各位同行交流探討,共同進步。
現有技術方案的局限性
技術1:基于流水線的AI代碼評審方案
核心技術路徑: 在通過公共流程(Webhook觸發、解析MR、獲取Diff)得到代碼變更內容后,該方案的核心處理流程如下:
1.文件類型過濾:僅保留.java、.yaml和.md文件進行后續分析,并明確優先級的處理順序。
2.上下文截斷:為避免觸及大模型上下文窗口上限,采用了一種基于固定行數的上下文截斷策略。該策略僅截取代碼變更處附近預設行數(如10行)的文本內容。
3.Prompt驅動評審:將經過過濾和截斷后的代碼片段,與預設的評審規則Prompt組合,發送給通用大語言模型。
4.輸出評審意見:解析大模型的返回結果,通過coding平臺API將評審結果添加到MR中。
核心問題識別:
1.全局上下文缺失:其采用的“固定行數截斷”策略是導致問題的根本原因之一。這使得評審完全喪失了項目架構、模塊依賴和完整業務邏輯的視野,如同“管中窺豹”,評審深度和準確性受到嚴重制約。
2.提示詞天花板:所有評審規則與知識硬編碼于Prompt中,規則膨脹后極易觸及模型上下文長度上限,可維護性與擴展性差。
3.知識無法沉淀:效果提升完全依賴于“更換更強的基礎模型”與“調整Prompt”,自身缺乏可持續積累、沉淀和復用領域知識的機制。
技術2:基于JoyAgent知識庫的RAG代碼評審
核心技術路徑: 在通過公共流程獲取代碼差異后,該方案的核心流程如下:
1.知識歸納:將格式化后的Diff內容發送給JoyAgent,由LLM智能體對其進行初步的“知識歸納”,以理解此次變更的核心意圖。
2.規則檢索:基于歸納出的知識,通過RAG機制從自定義知識庫中召回相關的代碼評審規則。此知識庫支持在線文檔(Joyspace)、離線文檔(PDF/Word)等多種格式。該方案的核心靈活性在于其“自定義知識庫綁定”機制。接入者可以在JoyAgent平臺上自定義智能體,通過工作流綁定自定義知識庫。這使得在召回評審規則時,系統能動態地查找并應用接入者自定義的評審規則,從而實現了無需修改Prompt即可定制評審規則的能力。
3.行級評審:JoyAgent將代碼Diff與召回的具體規則相結合,再次調用LLM進行精確評審。利用Git Diff信息中包含的代碼行信息,能夠將評審意見精準關聯到具體的代碼行。
4.輸出結果:直接使用JoyAgent的輸出結果,通過coding平臺API將評審結果添加到MR中。
核心問題識別:
1.知識歸納失真:核心問題源于其“知識歸納”步驟。該步驟依賴底層大模型對Code Diff進行總結,此過程不穩定,經常遺漏或曲解原始代碼變更的關鍵上下文,導致后續流程建立在一個不完整或失真的信息基礎之上。
2.檢索與生成聯動失效:基于失真的知識歸納結果進行RAG檢索,導致召回的規則與真實代碼場景匹配度低。此外,檢索結果未經有效的重排序,直接與不完整的代碼上下文一并送入大模型,這使得模型缺乏進行準確判斷的可靠依據,最終必然生成大量不可靠甚至錯誤的評審意見。
從線上問題到技術突破
問題1:三方系統空值處理異常
示例:
// 問題代碼:三方系統地址編碼字段處理
request.setAddressCode(String.valueOf(address.getCode()));
// 當address.getCode()為null時,String.valueOf(null)返回"null"字符串
// 導致三方系統Integer.parseInt("null")拋出NumberFormatException
技術1的問題:
理論上,可以通過在Prompt中硬編碼“三方接口地址編碼須為數字類型字符串” 的規則來識別此問題。然而,隨著業務場景增多,所有規則都被擠壓在有限的上下文窗口內競爭。當代碼變更觸發自動壓縮(如截斷至10行)時,被保留的上下文具有極大的隨機性,與當前評審強相關的評審規則很可能被其他無關規則擠掉或因自動壓縮而被截掉,導致其無法被穩定觸發,從而漏報。
技術2的問題:
該方案雖然理論上能夠通過知識庫檢索到相關規則,但其不穩定的知識歸納過程導致代碼上下文的理解時好時壞,使得規則檢索的準確性波動較大。同時,未對檢索結果進行重排序,進一步放大了這種不確定性。最終,由于缺乏穩定、可靠的上下文支撐,系統無法持續、準確地識別此類問題,其評審結果表現出顯著的隨機性。
問題2:EDI項目中的語法錯誤
示例:
!-- 錯誤:使用變量而非字面常量 --?>
!-- 正確應使用字面值: -->
EDI平臺介紹:
EDI(電子數據交換)是用來解決京東物流與多樣化商家系統間的對接難題的技術,其關鍵功能包括協議轉換、數據格式轉換、數據校驗和流程編排。這意味著EDI配置文件必須嚴格遵守預定義的語法和標準,任何偏差都可能導致平臺的核心轉換與校驗功能失效。
技術1的問題:
由于其缺乏對EDI配置語法與規范的領域知識,如果自定義規則,會遇到問題1一樣的提示詞天花板和上下文截斷的問題。
技術2的問題:
除了上面提到的知識歸納過程的不穩定問題,技術2也面臨一個更前置的的挑戰:它缺乏對項目身份的感知能力。系統在處理一個XML配置文件時,無法自動識別它隸屬于“EDI項目”而非普通Java應用。因此,在后續的RAG檢索過程中,它極有可能使用通用的Java代碼評審規則,而無法精準命中“EDI專用配置規范”這一關鍵上下文,導致檢索方向錯誤,最終無法識別出必須使用字面常量這一特定于EDI領域的合規性要求。
解決方案:雙RAG架構
?

?
?
1. 識別項目類型
?特征識別:基于文件擴展名(.flow, .dt)進行精準判斷。
?優先級設定:EDI項目識別優先于普通JAVA項目,確保領域特殊性得到優先處理。
?策略影響:項目類型直接決定后續評審規則的選擇與RAG知識庫的檢索策略,從源頭保障了評審的針對性。
2. 代碼分塊處理
2.1 Token估算算法
由于我們使用的底層大模型是JoyAI,并沒有公開tokenizer的細節,根據官網文檔提供的token計算API: http://api.chatrhino.jd.com/api/v1/tokenizer/estimate-token-count
測試了幾組數據:
| 測試文本 | 字符長度 | 實際Token數 | 內容Token增量 |
|---|---|---|---|
| 空字符串 | 0 | 63 | 0 |
| "a" | 1 | 64 | +1 |
| "hello" | 5 | 64 | +1 |
| "code" | 4 | 64 | +1 |
| "hello world" | 11 | 65 | +2 |
| "測試" | 2 | 64 | +1 |
| "編程編程" | 4 | 65 | +2 |
| "測試測試測試測試測試" | 10 | 68 | +5 |
| "hello世界" | 7 | 65 | +2 |
| "programming代碼" | 13 | 66 | +3 |
| 重復"programming代碼"3次 | 39 | 72 | +9 |
推導過程
通過分析測試數據,我們發現了以下關鍵規律:
1.基礎系統開銷:所有請求都有63 tokens的固定開銷
2.英文單詞分級:
?1-5字符單詞 = 1 token("a"、"hello"、"code")
?6-10字符單詞 ≈ 2 tokens(推測值)
?11+字符單詞 = 3 tokens("programming")
3.中文分詞規則:每2個中文字符 = 1 token
4.空格處理:空格作為分隔符,不增加額外token
5.混合內容:按字符類型分段計算后求和
基于上述規律,我們構建了以下估算公式:
總Tokens = 63 + ∑(單詞token)
單詞token計算:
- 單字符單詞: 1 token
- 英文單詞(≤5字符): 1 token
- 英文單詞(6-10字符): 2 tokens
- 英文單詞(≥11字符): 3 tokens
- 中文文本: (字符數 + 1) / 2 tokens
- 混合內容: 分段計算后求和
2.2 分塊閾值與安全設計
?觸發閾值:當預估Token數 > 100,000時,自動觸發分塊處理流程。
?JoyAI的上下文窗口是128K,由于JoyAI沒說明1K是1024還是1000,保守估計使用1000
?128K = 128000,為了避免超過上下文窗口,留個富余量,使用80%,12800*0.8=102400 ≈100000
?

?
?
?單塊容量:設定 MAX_TOKENS_PER_CHUNK = 60000,為模型輸出及上下文預留40%的安全余量。
?設計理念:通過嚴格的容量控制,確保單次處理負載均在模型窗口的安全范圍內。
2.3 智能分塊策略
系統采用兩級分塊策略,確保代碼語義的完整性:
2.3.1 文件級分割
通過git diff指令識別文件邊界,確保單個文件的代碼完整性,避免跨文件分割。
Pattern.compile("diff --git a/(.+?) b/(.+?)n")
2.3.2 代碼結構感知分割
利用方法簽名模式識別代碼結構邊界:
Pattern methodPattern = Pattern.compile(
"([+-]\s*((public|private|protected)\s+)?(\w+\s+)?\w+\s*\([^)]*\)\s*\{)",Pattern.MULTILINE);
在方法或類的自然邊界處進行分割,最大限度保持代碼塊的語義完整性。
3. RAG增強與重排序機制
3.1 基于知識工程的代碼片段、業務上下文的檢索
在 RAG增加服務中實現多維度檢索增強:
?業務領域識別:基于代碼內容識別是倉業務(WMS)、倉配接入業務(ECLP)、轉運中心業務(TC)等。
?關鍵詞提取與過濾:從變更文件中提取并凈化關鍵術語。
?通過執行語義搜索。
重排序優化:對檢索結果使用BGE模型進行重排序,提升相關性。
3.2 重排序
在RAG系統中,檢索(召回)這一步通常使用向量相似度搜索。這種方法追求的是高召回率——即盡可能不遺漏任何可能相關的文檔。但這就帶來了一個問題:
?數量過多:可能會返回大量候選文檔,全部送入大模型會導致超過上下文窗口限制,成本高昂且速度慢。
?質量不均:向量搜索是基于語義相似度,但“相似”不一定等于“有用”。它可能會召回一些:
?主題相關但內容泛泛的文檔。
?包含關鍵詞但邏輯不匹配的文檔。
?相關性排名不高但實際至關重要的“珍寶”文檔。
例如檢索“如何做番茄炒蛋”,向量相似度查詢結果可能會找到:
?《番茄炒蛋的最正宗做法》 (極度相關,排名第一)
?《100道家常菜譜》 (相關,但范圍太廣)
?《雞蛋的營養價值》 (部分相關)
?《番茄種植指南》 (僅關鍵詞相關,實際無用)
如果不經處理,把這四篇文檔塞給大模型,模型需要費力地從大量文本中辨別哪些是真正有用的信息,不僅增加了Token消耗,更嚴重的是,無關信息會形成“噪聲”,干擾模型的判斷,導致生成質量下降——模型幻覺。
為了節省成本,我們使用了本地重排序方案:
?模型文件: bge-reranker-base.onnx (BGE重排序模型)
?分詞器: HuggingFaceTokenizer
?運行時: ONNX Runtime Java API
// 核心流程
public List> rerankBatch(String query, List documents) {
// 1. 文本預處理和分詞
// 2. 構建查詢-文檔對
// 3. ONNX模型推理
// 4. 相關性評分計算
// 5. 按分數降序排序
// 6. 返回排序結果
}
示例:
?

?
?
4. 實際應用效果驗證
案例1:成功預防空值處理事故
?

?
?
案例2:EDI配置規范檢查
?

?
?
?
總結與展望
我們探索出的雙RAG架構,其價值核心并非追求極致的簡單或敏捷,而是它既能像資深的一線研發一樣,深度理解業務及代碼變更的具體語境與潛在影響,又能像嚴謹的架構師一樣,嚴格遵循成文的規范與最佳實踐。
通過結構化的協同機制,系統將兩種不同質、不同源的知識(深度的代碼語義與精準的評審規則)進行融合,實現了 “1+1 > 2” 的智能涌現,從而具備了識別并預防那些復雜、隱蔽代碼缺陷的深度推理能力。這正是我們在高并發、高可用要求極為嚴苛的大促等場景下,為夯實系統穩定性基石所做出的關鍵性架構決策。
這一成功實踐,為我們奠定了代碼評審工作中堅實的技術基石,并清晰地指明了未來的演進路徑:
1.邁向多模態代碼理解:從純文本代碼評審,擴展至對架構圖、時序圖等非結構化設計產物的理解與合規性檢查。
2.構建全域業務知識庫:自動抓取并融合產品經理的歷史PRD、設計文檔等非技術知識,將其轉化為知識工程中的關鍵上下文。這使得AI在評審時,不僅能理解“代碼怎么寫”,更能判斷“代碼為何而寫”,實現對業務意圖的精準校驗,從源頭規避偏離產品設計的實現。
3.實現需求上下文的自動關聯:通過規范研發流程,約束在提交代碼時于commit信息中嵌入需求編號。系統在評審時自動提取該編號,并主動獲取對應的PRD詳情。這使得每一次代碼評審都能夠在完整的業務背景中進行,AI能夠直接對照需求文檔,判斷代碼實現是否完整、準確地滿足了所有功能點與業務規則,提供前更加精準的上下文。
雖然探索的道路并非坦途,我們曾在具體的技術細節中陷入困境,例如,為了在 CentOS 7.9 的環境中支持高版本 ONNX 運行時以啟用重排序功能,不得不手動編寫docker腳本從源碼編譯高版本的cglib依賴。這段經歷,恰恰印證了弗雷德里克·布魯克斯在《人月神話》中所揭示的那句箴言:
The only way to accelerate software work is to simplify the product and the process, and to face the essential complexity of the software task itself with courage and skill.
-
代碼
+關注
關注
30文章
4967瀏覽量
73960 -
京東云
+關注
關注
0文章
205瀏覽量
254
發布評論請先 登錄
RAG(檢索增強生成)原理與實踐
夢之墨藍牙音響工程實踐課程開啟電子專業實訓新體驗
基于知識工程&JoyAgent雙RAG的智能代碼評審系統的探索與實踐
【社區之星】石建華:勤于探索,不斷實踐學習新知識
RAG實踐:一文掌握大模型RAG過程
電子發燒友工程師看!電子領域評職稱,技術之路更扎實
JoyAgent綜合測評報告
軟通動力發布智慧園區RAG解決方案
基于知識工程JoyAgent雙RAG的智能代碼評審系統的探索與實踐
評論