衡量程式碼粗糙度:指標、發現與社群洞見

TL;DR

LLM 產生的程式碼雖可為形式正確,卻明顯比人類撰寫的程式碼更粗糙;簡單的指標如 LOC 變化、冗長度與腐蝕度顯示,代理程式產生的冗長度與腐蝕度約為既定程式庫的兩倍,而現有的評估方法無法察覺此類退化。


為何衡量粗糙度至關重要

透過隱藏測試的程式碼仍可能包含不必要的抽象、重複的邏輯與不良的架構決策。在每月新增數百萬行程式碼(LOC)的大規模專案中,這種「粗糙度」會侵蝕開發者的主導權,因為開發者無法跟上隱藏的技術負債。作者主張,代理程式無法自主解決粗糙度問題,因此量化評估至關重要。


天真的評估方法失敗

AI 作為審判者不可靠

  • 要求 LLM 對其自身程式碼以 1–10 分評分,行為類似隨機數產生器。
  • 成對比較(「A 對 B」)不穩定:更名解決方案可使模型偏好翻轉,如 arXiv:2604.16790 所示。
  • 即使是複雜的評分標準或 LLM 產生的測試,仍無法消除粗糙度。

"要求 LLM 評估其撰寫的程式碼,並不能取代適當的評估。" – 作者

人工介入無法擴展

  • 人工審查可確保可讀性,但無法擴展至訓練或基準套件所需的規模。
  • 審查數百萬行 LOC 的成本遠高於持續排名模型提供者的效益。

簡單指標:LOC 變化

在程式碼修改後計算 LOC 的淨變化,被證明在標記粗糙度方面出人意料地有效。然而,作者警告,若針對此指標進行優化,將觸發古德哈特定律——一旦指標成為目標,它便不再是一個良好的衡量標準。


基於研究的指標:SlopCodeBench

論文 SlopCodeBench(arXiv:2603.24755v1)引入兩個指標,可區分傳統程式碼庫與 LLM 產生的粗糙程式碼。

冗長度

衡量重複或不必要的冗長程式行數:

$$ \text{冗長度} = \frac{|\text{AST‑Grep 標記的程式行} \cup \text{複製程式行}|}{\text{LOC}} $$ 透過 AST‑Grep 中的手動設計啟發式方法實作。

腐蝕度

量化有多少程式碼質量集中在少數大型且複雜的函數中:

$$ \text{mass}(f) = \text{CC}(f) \sqrt{\text{SLOC}(f)} $$ $$ \text{腐蝕度} = \frac{\sum_{f:,\text{CC}(f)>10}\text{mass}(f)}{\sum_{f}\text{mass}(f)} $$ CC(f) 為循環複雜度;SLOC(f) 為原始程式碼行數。


實證發現

資料集 冗長度(平均 ± 標準差) 腐蝕度(平均 ± 標準差)
已建立的人類程式庫 0.15 ± 0.06 0.31 ± 0.17
由代理程式產生的程式碼(SlopCodeBench) 0.33 ± 0.10 0.68 ± 0.20

代理程式產生的冗長度與腐蝕度約為人類程式碼的兩倍。

作者對自身「直覺式撰寫」的專案進行額外的個案檢查,發現冗長度最高達 0.4,腐蝕度最高達 0.75,確認此效應不僅限於基準測試。


為何代理程式無法自我修正粗糙度

  • SlopCodeBench 在迭代設定中評估代理程式:每次指令-測試回合後,模型的上下文會被清除,模擬現實世界中程式碼經過多步演進的使用情境。
  • 錯誤決策累積,導致最先進模型的「嚴格解決率」為 0 %——即無模型能在每個檢查點通過所有隱藏測試。
  • 這種明顯的失敗警示我們,僅靠 AI 驅動的無限 LOC 增長是危險的。

社群反應與延伸

"粗糙度最重要的問題是全局性質,而非局部性質。需要像關注分離關注點之類的架構指標。" – dherman

"優化最小 LOC 可能反而增加程式碼 golfing,產生難以維護的一行程式碼。" – cjalmeida

"像循環複雜度、變更頻率與作者資訊等指標,已在內部儀表板中實用;結合它們可提供更豐富的粗糙度圖像。" – pbjerkeseth

"古德哈特定律被引用卻未討論;我們需要檢視最小化 LOC 是否真會導致更粗糙的程式碼。" – drsopp

"目前討論中缺少全局架構指標(例如耦合度、內聚度),對大型程式碼庫而言可能至關重要。" – dherman

"即使使用代理程式,仍需人類設計工作;否則程式碼庫將變成由臨時功能堆疊而成的意大利麵。" – cheney_2004

這些評論突顯出三個反覆出現的主題:

  1. 需要全局架構指標(耦合度、內聚度、分層)。
  2. 指標操弄的風險(古德哈特定律)以及多指標套件的重要性。
  3. 人工監督仍至關重要,特別是在設計與可維護性方面。

開放的研究方向

作者列出未來研究的潛力途徑:

  • 函數的耦合度 – 衡量函數之間依賴的緊密程度。
  • 程式碼變更頻率 – 追蹤快速新增或移除作為不穩定性的代理。
  • 內聚度 – 評估模組的職責是否集中。
  • 反饋迴路 – 將冗長度/腐蝕度分數回饋至 LLM 訓練中,以引導生成更乾淨的程式碼(同時監控古德哈特效應)。

實務工作者的實用建議

  1. 追蹤 LOC 變化 作為快速的合理性檢查,但應視為啟發式方法,而非硬性目標。
  2. 使用 AST‑Grep 或類似靜態分析管道 實作冗長度與腐蝕度,以標記重複或過於複雜的程式碼。
  3. 結合多個指標(複雜度、變更頻率、耦合度),以降低單一指標被操弄的風險。
  4. 維持人工審查週期 用於架構決策;自動化指標可揭露問題,但無法取代設計判斷。
  5. 設計模擬迭代開發的基準(如 SlopCodeBench 所做),以揭露僅在多次精煉步驟後才出現的粗糙度。

結論

像 LOC 變化、冗長度與腐蝕度等量化指標,為程式碼粗糙度提供了具體的觀察視角,揭示目前的 LLM 代理程式產生的程式碼,其冗長度與腐蝕度約為人類撰寫程式碼的兩倍。儘管這些指標具有價值,但必須作為更廣泛、多維度評估策略的一部分,包含全局架構性質與人工監督,以避免古德哈特定律,並確保軟體的可維護性。

Sources

相關