讓 AI 找 bug,真的比較快嗎?
上週在做課程專題的 API 時,我又遇到那種很欠揍的 bug。正常查詢都過,只有使用者輸入一段帶引號的名稱時,回傳會直接變成 500。
我一開始很直覺地把錯誤 log 貼給 AI,叫它幫我找原因。它很快列出 5 個可能性,還順手改了一版 ORM 查詢。我複製貼上,測試原本那個案例,欸,真的不 500 了!
然後我換了一個輸入,整個結果又壞掉。救命,AI 修 bug 修到像把地上的垃圾掃到床底下而已 XD
我後來改成兩個角色
我把流程拆開,不再叫同一個 AI 同時當偵探和修理工。第一個角色只准寫「可以穩定重現問題的 test」,不准改 production code。提示詞大概是:
請只分析這個錯誤,新增一個最小可重現的測試。
不要修改任何 src/ 下的檔案,測試必須在修復前失敗。
請說明預期結果、實際結果,以及重現指令。
它最後幫我產出:
def test_quote_in_name_is_saved(client):
response = client.post('/users', json={'name': 'O_Reilly'})
assert response.status_code == 201
assert response.json()['name'] == 'O_Reilly'
我先自己跑,確認修復前確實是 500。這一步超重要,因為 AI 有時候會寫出看起來很合理,但其實根本沒有碰到 bug 的測試。我之前就被它騙過,test 顯示 passed,結果只是因為 fixture 裡的資料根本沒有走到那條查詢。大三了還會被這種東西陰 QQ
第二個角色才拿這個 failing test,要求它修程式,而且修完要跑完整測試。這次它把字串組 SQL 的地方改成參數化查詢,也沒有亂動其他 endpoint。修好後,我額外測了空字串、Unicode 名稱和兩筆同名資料,原本 18 個測試全過,新增的 1 個也過。
為什麼拆開後比較可靠
我覺得關鍵不是多開一個聊天視窗,而是把「問題到底存在嗎」和「要怎麼修」分成兩個可檢查的交付物。沒有 failing test 時,AI 很容易根據錯誤訊息猜一個看似漂亮的修法。猜對了算運氣,猜錯了就只是讓錯誤換一種形式。
最近看到 Datasette 的安全修補流程,也有類似的精神。人類先建立能重現漏洞的自動測試,另一位人類才實作修復,另外讓多個 frontier model 協助 audit。我的理解是,AI 很適合增加檢查角度,但不能讓它自己決定「我修好了」。能不能在修復前失敗,修復後成功,這個證據要留下來。
我現在做專題會固定走這 5 步:
- 先把錯誤縮成一個輸入和一個預期結果。
- 叫角色 A 只新增最小 failing test。
- 人工確認測試真的會失敗,而且失敗原因和 bug 一致。
- 叫角色 B 只修到測試通過,不能順便重構半個專案。
- 跑完整 test suite,再用 2 到 3 個相鄰案例打臉它。
最後那個打臉步驟很有用。AI 修好引號問題後,可能把單引號修好,雙引號或換行又爆掉。測試不是終點,是把 AI 從「我覺得應該好了」拉回「請證明給我看」。哇這個觀念我以前真的沒有想過,現在反而覺得比直接叫 AI 找 bug 更省時間。有人也會把 debug 拆成不同角色嗎?好想知道大家怎麼寫那個第一個 test ><
作者:小萱