AI 只拿得到 diff:我用 sem 補上改動影響面
讓 AI 改程式碼一陣子之後,我開始覺得哪裡怪怪的:它看得到 diff,卻看不到這次改動會炸到誰。起初我以為是模型不夠強,或是 prompt 沒下好,後來才發現它手上根本沒有「影響面」這份資訊。
關鍵字搜尋、語意檢索可以找到檔案跟片段,卻不會直接整理出「改了 X 之後誰可能受影響、哪些地方有測試守著」。
這篇記錄的不是一次事故。我手上沒有「AI 漏改呼叫端害我上線爆炸」這種案例,而是把一項預防性投資跑了兩個月,試用期結束後留下來當日常工具。成績單跟坑一起講。
sem 補的是哪塊
sem 是把 git diff 從「行」抬到「函式/類別」層級的命令列工具。它先辨識哪些程式實體被改動,再沿靜態相依關係列出呼叫端與相關測試。這裡列的是相依圖能連到的測試,不是執行期覆蓋率。Rust 寫的,靠語法解析器支援多語言,採開放原始碼授權,也可以自行安裝。核心就三件事:diff 看改了哪些程式實體、impact 看相關相依項與測試、entities 看專案裡有哪些符號。
它追得到什麼、追不到什麼
我曾在一個正式專案裡,逐一比對少數幾個直接 import 的函式。sem 列出的呼叫端跟手動比對一致,解析度細到函式層級。這只代表受測樣本沒有漏報或誤報,不能推成全庫準確率。
起初我最擔心的是統一出口檔(barrel):一堆檔案先導到同一支出口檔再轉出去,依賴圖會不會斷在這裡?實測追得穿,這條擔憂不成立。
真正追不到的是一部分動態載入寫法:匯入後才從執行期物件取出成員,或在回呼裡決定要拿哪個名稱。這次形態對照得到的規律是,名稱直接出現在 import 語法時比較容易追到;名稱藏到執行期才決定就容易斷。
因此我把它回報的呼叫端數字視為下限值。採用上述動態載入形態的程式碼分割路徑可能被低報,不代表所有程式碼分割都追不到。
接法:不讓 AI 自己查
接法上,有一條路我先否決:讓 AI 自己去呼叫 sem。AI 不一定會在對的時機想起要查,每次現查也有成本,而且查回來的內容未必屬於這次 diff。最後我改用固定腳本先計算,再把影響面摘要塞進 prompt。AI 不必知道工具名稱,也不用主動呼叫它。
我把腳本掛在兩個人會停下來判斷的時機:
- AI 寫完計畫文件時,摘要會補上預計修改的既有函式、外部呼叫端,以及依賴圖裡沒有相關測試的項目,交給接下來審計畫的人看。
- PR 進入審查流程時,摘要會列出這次 diff 改到的既有函式、各自的呼叫端與相關測試,交給 AI 審查者一起判讀。
砍掉第三支 hook
本來還有第三支,每次 commit 就算,後來被我砍了。在我的代理分工流程裡,一個功能常被拆成數十個 commit;逐 commit 重複注入同一批影響面,只會塞滿正在執行任務的子代理脈絡。更根本的是時機錯,commit 是自動檢查點,通常沒有人會停下來判斷整個功能。
補強型接點最後只留在計畫文件完成與 PR 送審這兩個時機。
成績單
兩個月試用期內,PR 審查流程成功注入了 20 次影響面摘要,其中 13 次被 AI 審查者在回報裡明確提及。正向用途幾乎全集中在同一件事:看到哪些改動沒有相關測試,就把它們排到前面查驗。
試用期結束後它也沒有被丟掉。接下來一個月,約三分之二的日子仍能在工作紀錄看到 PR 注入標記;這只能證明流程持續執行,不等於每次都被採用。我自己的體感是現在幾乎每天都會碰到這段摘要。
計畫那支接點則近乎沒有真實注入紀錄。它目前只證明了放著沒壞,實際增益還沒驗出來。
一個真缺陷,跟它的修法
這套注入一開始有個真缺陷:同一台機器多個工作目錄共用快取,摘要會夾帶不屬於這次 PR 的函式。AI 審查者每次都有排除,審查方向沒有因此偏掉,但仍浪費了注意力。
修法不複雜:注入前把工具輸出跟「這次 diff 實際動到的檔案」取交集,不相交就靜默跳過。修正後的追蹤期裡,AI 審查回報不再出現「這跟本 PR 無關」這類排除語;至少在留下的回報中,沒有再觀察到同類雜訊,但這不代表輸出已達到全量正確。
這次經驗留下的判準比較窄:共用索引的結果要塞進單次 PR 前,先縮到當次 diff 的範圍。
踩坑
兩個月踩了不少坑,有些來自上游版本,有些來自我的安裝與接法:
- 早期版本把快取留在專案目錄,一不小心就 commit 進去。
- 我設過一個當時尚未生效的快取路徑環境變數;後來上游開始支援,反而造成兩處快取並存。
- 我從原始程式碼安裝執行檔,它會動態連結套件管理器提供的函式庫。相依套件被自動清掉後,sem 就無法啟動。
- 每個專案快取是數十 MB,累積數十個專案後會進到 GB 等級。
- 升級前要驗輸出流有沒有混進新的提示訊息,不然吃輸出的腳本會炸。
值不值得裝
它只是審查時的參考訊號,不替人或 AI 判定程式錯誤。整段觀察期沒有出現工具成功抓包的案例,也沒有看到它指出人工原本會漏掉的程式錯誤。
兩支 hook 現在都還留著,但只有 PR 那支證明了實際用途。它的運算便宜、雜訊已壓低,而且偶爾能幫審查者決定先查哪裡;這三件事少一件,維護成本就可能不值得。
適合安裝的條件也很具體:AI 已大量參與改程式碼或審 PR、專案大到人腦記不住呼叫關係,而且流程裡已經有一個人會停下來看的審查關口。小專案、沒有固定審查關口,或期待它主動抓出程式錯誤,裝了會失望。