把 AI 編程代理的帳單推高的,不是模型有多聰明,而是它在程式碼庫裡的走法。以靜態分析聞名的 Sonar 公開了自家儲存庫的實測數字。一次約 800 行的變更,累計吃掉 1.56 億個脈絡 token。代理靠 grep 與讀檔蒐集到的內容會一直留在對話裡,之後每一輪都被重新計費,這套結構終於有了具體的數字。
代理繞的每一次遠路,每輪都要付錢
大型語言模型每次規劃下一步,都會把先前的整段對話重新當成輸入接收一遍。提示快取能把這些重送 token 的單價壓到輸入價格的一成左右,卻不會歸零。因此一個 token 的真實成本不是它的大小,而是大小乘上它存活的輪數。
在第 40 輪打開一個 600 行檔案的代理,並不是為 600 行付了一次錢,而是為 600 行付了剩下 470 輪的錢。讀的檔案越多、對話拖得越久,早期多讀的部分就越像利息一樣滾上來。
800 行變更燒掉 1.56 億 token
Sonar 本身就是用 AI 代理在開發自家的語意分析引擎,並完整保留了過程紀錄。這次拿出來的樣本,是一個含約 800 行後端變更的拉取請求。
這個 PR 消耗了 1.56 億個脈絡 token,其中快取讀取占 1.528 億。脈絡視窗峰值達到 45.9 萬 token,費用約 41 美元(約 6,400 日圓)。而最終的程式碼差異,人來看五分鐘就讀得完。
代理做的事,其實就是整合開發環境免費提供的「跳到定義」。為了找出呼叫的目標,它敲下這樣的指令:
grep -rn "resolve_return_type"
回來的是 Python、TypeScript、Java、Rust、C# 與共用核心各版實作混在一起的清單。正規表示式沒有辦法判斷某次呼叫究竟繫結到哪一個。於是它打開檔案、寬鬆地讀一大段,再去找產生回傳值的輔助函式,再打開一個檔案。這些讀取全都留在對話裡。
一次多讀,膨脹成 270 萬 token
其中一個案例算得很清楚。代理只想弄懂一個 67 行的函式,但因為分不出函式從哪裡開始到哪裡結束,它把整份 618 行的檔案讀了下來。載入 6,472 個 token,真正用上的約 700 個,當場浪費約 5,770 個。
這次讀取在第 42 輪進入對話,之後又待了 470 輪。5,770 乘以 470,約等於 270 萬 token。快取讀取的價格約為每百萬 token 0.2 美元(約 31 日圓),所以光是這一次就花掉約 0.54 美元(約 85 日圓)。同類的過度讀取在這一個 PR 裡發生了約 10 次,另外還有數十次全樹 grep,其中好幾次一無所獲,只能放寬條件再搜一次。
把同一儲存庫中 18 個同等規模的 PR 平均起來,每個約消耗 2.34 億個脈絡 token、約 65 美元(約 1 萬日圓),中位數約 52 美元(約 8,000 日圓)。與模型的往返約 700 次,脈絡視窗峰值散布在 45 萬到 97.5 萬 token 之間。一旦碰到 100 萬 token 的上限就得壓縮,先前的脈絡也隨之流失。這個落差反映的不是最終差異有多大,而是代理被迫在程式碼庫裡走了多遠。
※1 美元 = 157 日圓(截至 2026 年 9 月 3 日)
grep 找得到字串,找不到語意
比錢更棘手的是另一個副作用。正規表示式只找得到你想得到的那個寫法。經由介面的呼叫、透過別名的參照、來自另一種語言的呼叫,只要檢索字不同就會漏掉。
這次的 PR,正是要把 C# 裡已經實作的呼叫點型別解析搬到 Python。可是 C# 那邊的函式叫 resolve_type_node,與 Python 側的 resolve_return_type 用字不同。搜其中一個,永遠帶不出另一個。漏掉的呼叫點會以建置失敗的形式回彈,帶來持續整合的重跑與返工,而每一輪都要再繳一次脈絡稅。
把文字搜尋換成圖查詢
Sonar Vortex 想替換掉的正是這套查找方式。它進入代理的處理迴圈內部,不再問檔案系統,而是向程式碼庫的圖發出查詢並取回答案。
建立這張圖的,是 Sonar 自行開發的語意分析引擎 SemSitter。它把函式、方法、類別、欄位、參數當成節點,用 calls、references、returns、has-param、is-type、contains、extends 等帶型別的邊連接關係,形成統一相依圖(UDG),並在每次變更時即時更新。
代理的問法也跟著改變。不再是「哪些檔案提到 resolve_return_type」,而是「給我這次呼叫繫結的定義、擁有它的型別、回傳值以及呼叫端」。回來的只有一個方法本體,加上能回答其餘問題的幾條邊。周圍的檔案不會被帶進來,也不需要放寬條件重搜。前面那次過度讀取,換成圖查詢只相當於約 33 萬 token,大約是九分之一。
效果更大的是結構關係之外的兩類邊。一是連結程式碼與文件的 documented_by,碰到某個函式時只浮現設計文件中相關的那一段,把「讓代理讀文件反而被帶偏」的老問題反過來解決。二是跨語言的 semantically_related,即使名稱不同也能把等價實作連起來。有了這條邊,上面 C# 與 Python 的錯位就只是順著邊走一步的事。
可以後補接進現有的編程工具鏈
Sonar Vortex 以 MCP(模型脈絡協定)為核心進行整合,能後補接進 Claude Code、Cursor、GitHub Copilot、Windsurf、Google Gemini CLI、OpenAI Codex CLI 等手邊既有的工具。判定所用的規則直接沿用 SonarQube 現有的品質設定檔,不必另寫一套規範。寫程式前注入脈絡與限制、寫的過程中即時驗證,這兩件事當成一個迴圈運轉。
總結
在大型程式碼庫裡讓 AI 編程代理卡住的,不是推理品質,而是移動方式。Sonar 的實測顯示,一個約 800 行的 PR 消耗 1.56 億個脈絡 token,18 個 PR 平均每個約 65 美元(約 1 萬日圓),脈絡視窗一再逼近 100 萬 token 的上限。加上文字檢索會漏掉其他語言中的等價實作,這部分最後以返工的形式回彈。把查找換成圖查詢,是一種減少而非增加代理所攜帶資訊的最佳化思路。由於程式碼庫越大差距越明顯,日常大量使用代理的團隊,或許值得把帳單的明細重新看一遍。
※ 縮圖為 AI 生成的示意圖。
