AI 一天寫的程式,你三天看不完:Meta、Google 驗證 AI 程式碼的 7 道關卡

很多團隊看到測試覆蓋率 80%、90% 就放心讓 PR 過關。但這其實是個錯覺。

打個比方:你家裝了 10 支監視器,涵蓋了 80% 的角落。今天小偷從那 20% 沒裝的角落進來,監視器再多也沒用。測試覆蓋率也是一樣——80% 是看「整個房子」的覆蓋,但 AI 剛寫的那段新程式碼,可能正好落在沒被照到的那 20%

舊的測試是針對舊功能寫的。AI 新寫的邏輯、新分支、新情境,舊測試根本碰不到。報表上數字漂亮,實際上新程式碼可能完全沒被驗證過。

這也是為什麼有研究指出,AI 一起寫的 PR,出問題的機率比純人寫的多 1.7 倍。不是測試太少,是測試沒對到地方

更糟的是,2025 年的一個學術研究發現:當研究員把程式碼小幅改寫(意思一樣,但寫法不同),AI 寫的測試突然就大量失敗了。失敗的測試裡,99% 在原本沒改過的程式碼上反而會通過

這代表什麼?AI 寫測試其實是在「背題目」,不是真的理解程式在做什麼。題目稍微變一下,它就答錯了。

那怎麼辦?人來不及看,AI 寫的測試又不能完全相信,新程式碼到底要怎麼守?這篇文章就在回答這個問題。

先把兩件事分清楚:守舊功能 vs. 驗新程式碼

很多人把「測試」當一件事談,但對 AI 寫程式來說,這其實是兩個完全不同的問題:

問題在處理什麼像什麼
守舊功能確認舊的東西沒被改壞大樓的消防演習,定期跑一遍
驗新程式碼確認新蓋的房間是安全的新建工程的驗收檢查

大廠常公布的「測試時間砍 50%」這類成績,主要是在講第一件事——讓既有的測試跑得更聰明。但這完全沒回答:這次新蓋的這間房,有人驗收過嗎?

接下來要講的,全都是第二件事。

大廠做法一:Meta 的「不信任,只驗收」哲學

Meta 不相信 AI 寫的測試,所以他們做了一套機制——任何 AI 產出的測試,都要先通過嚴格的考試,沒過就直接丟掉。他們把這套方法叫做 Assured LLMSE,意思是「有保證的 AI 軟體工程」。

簡單說就是:不管 AI 寫得多漂亮,沒通過驗收就當作沒寫。Meta 為此做了三套工具,層層把關。

工具一:TestGen-LLM——只收「真的有用」的測試

AI 寫完測試後,Meta 會用機器自動檢查這個測試是不是:

能跑(編譯得過)

穩定(跑十次都會過,不是運氣好才過)

真的有測到東西(不是寫了等於沒寫)

不會把舊功能弄壞

實際成績有點驚人:在 Instagram 的測試活動中,AI 生出來的測試,只有 25% 真的「有效」。其他 75% 都被自動丟掉了。

這就是大廠面對 AI 寫測試的態度——不是相信它,是用機器無情地考它

工具二:TestGen-obs——把「現在的行為」變成保護網

這個比較特別,要解釋一下才看得懂。

它不是在驗證新程式碼,而是在「保護舊行為不被改壞」

舉個例子:你有一個「計算運費」的函式,已經在正式環境跑了一年,每天被呼叫幾百萬次。沒人寫過單元測試,但它一直運作正常。

現在 AI 要改它,怎麼確保改完之後,那些原本好好的行為不會被弄壞?

TestGen-obs 的做法分三步:

第一步:偷看它平常怎麼跑。在程式裡裝感應器,記錄真實的呼叫情況——「台北 2 公斤回傳 80 元」、「高雄 5 公斤回傳 150 元」、「台北 0.5 公斤回傳 60 元」⋯⋯記下幾千筆真實情況。

第二步:把這些「實際發生過的事」變成測試。每一筆紀錄都變成一個斷言:「台北 2 公斤,答案就是 80 元」。

第三步:這些測試變成保護網。之後 AI 不管怎麼改這個函式,都必須通過這些測試。改完如果台北 2 公斤變成 90 元,測試立刻失敗——因為過去明明是 80 元,你不能說改就改

所以這個工具解決的不是「新功能對不對」,而是「舊行為會不會被 AI 不小心弄壞」這個更大的問題。

實際成績:這套工具到 2024 年已經放了 518 個測試到正式環境,被執行 960 萬次,抓到 5,702 個 bug。在 16 個會讓 Instagram 沒辦法上架的嚴重問題裡,它本來可以擋下 13 個。

重要限制:這個方法只能保證「行為跟以前一樣」,不能保證「行為本來就是對的」。如果原本就有 bug,它會把 bug 也當成「正確答案」記下來,以後改對反而會被擋下來。所以 Meta 的策略是多套工具一起用:TestGen-obs 守舊行為,TestGen-LLM 和 ACH 驗新行為對不對。

工具三:ACH——故意把程式碼弄壞,看測試會不會發現

這套最狠。它的邏輯是:故意把好的程式碼小小改壞(比如把「大於」改成「小於」),然後看現有的測試會不會抓到。如果抓不到,就代表測試是假的,要再補

這就像考駕訓班的時候,教練故意設陷阱看你會不會犯錯。沒被抓到的錯,代表你真的沒這個能力,不是運氣好。

實際數據:Meta 把這套方法用在 1 萬多個 Android 程式檔案上,做了 9 千多次「故意弄壞」,結果產生 571 個強化測試。其中將近一半(48%),如果只看覆蓋率根本不會被寫出來

這個數字直接打臉「覆蓋率高就安心」的想法。


大廠做法二:Google 的「邊寫邊審」策略

Google 走另一條路。他們的想法是:與其等 AI 寫完再審,不如在寫的當下就有另一個 AI 在旁邊盯著

Jules 的「批評者」功能(2025 年 8 月)

Google 的 AI 工具 Jules 有個內建的「批評者」(critic),它的工作就是在 AI 寫程式的同時,即時挑毛病:邏輯有沒有錯、有沒有漏掉必要的欄位、寫法有沒有效率。

Google 的官方說法很有意思:「等你看到程式碼的時候,它已經被審問過、修正過、壓力測試過了。」

換句話說,送到人面前的不是 AI 的初稿,是 AI 互相校對過的版本。就像你交給編輯的稿子,已經先給朋友看過、修過一輪了。

Conductor 的「強制驗收」(2026 年 2 月)

更新的 Conductor 工具加了一個強制步驟:AI 完成任務後,一定要產出一份驗收報告,自動檢查:

  • 有沒有把密碼或 API key 寫死在程式裡
  • 有沒有可能洩漏個資
  • 有沒有不安全的輸入處理
  • 有沒有違反團隊規範

這就像新房子蓋好不能直接住,一定要請人來驗屋。Google 把這個動作從「人工選擇做不做」變成「機器強制做」。


大廠做法三:Diffblue 的「用試的,不用想的」路線

Diffblue 是個有趣的對照組。要看懂它,得先知道它跟 LLM 的根本差異。

LLM 寫測試 vs. Diffblue 寫測試

LLM(像 Copilot、Claude)是「用想的」。它讀過幾百萬份程式碼和測試,根據經驗「猜」這段程式應該怎麼測:

「這段程式長得像我看過的某種計算函式,過去類似的程式都是這樣測,所以我也這樣寫。」

問題是,它有時候會猜錯。寫出來的測試可能編譯不過、跑起來會失敗、或根本沒測到重點。這就是為什麼 LLM 寫的測試有 30-45% 跑不起來。

Diffblue 是「用試的」。它直接把程式碼當輸入,實際跑跑看,從結果反推出測試。

舉個例子,有個「判斷數字是否為偶數」的函式 isEven(),Diffblue 的流程是:

第一步:嘗試各種輸入,觀察結果

試 input = 2  → 結果 true 試 input = 3  → 結果 false 試 input = 0  → 結果 true 試 input = -4 → 結果 true

第二步:用「強化學習」決定哪些測試最有價值

「強化學習」聽起來抽象,其實就是「不斷試錯,從成功的嘗試中學習」。就像訓練狗坐下:做對了給零食,做錯了不給,重複幾百次牠就學會了。重點是你沒教牠肌肉怎麼動,只給了目標和回饋

Diffblue 的回饋機制是:這個測試能不能編譯?能不能穩定通過?有沒有測到新的程式分支? 高分的留下,低分的丟掉。

第三步:產出已驗證過的測試

每個輸出的測試都是先跑過、確認過才產出來的

為什麼能 100% 跑起來?

關鍵就一句話:Diffblue 是「跑過才產出」,LLM 是「想過就產出」

打個更生活化的比方:

LLM 像廚師憑記憶寫食譜:「這道菜應該加 3 大匙鹽。」可能對,可能不對,實際煮過才知道。

Diffblue 像廚師邊煮邊記錄:「我剛加了 3 大匙鹽,試過味道 OK,寫進食譜。」每個步驟都已經驗證過。

實際數據:

LLM 工具(像 Copilot)寫的測試,有 30-45% 跑不起來

Diffblue 接近 0% 失敗

速度比 Copilot 快 10 倍,比人工快 250 倍

但這個方法也有兩個明顯弱點

弱點一:它記錄的是「現狀」,不是「應該怎樣」

如果 isEven() 原本就有 bug,比如 isEven(-4) 錯誤地回傳 false,Diffblue 會把這個錯誤當成「正確答案」記下來。跟前面的 TestGen-obs 是同樣的弱點——記錄的是「現在發生什麼」,不是「應該發生什麼」。

弱點二:它看不懂業務邏輯

LLM 看到 calculateTax(income) 這個函式名,可以猜到「這跟稅務有關」,然後寫出合理的情境(高收入、低收入、免稅額)。Diffblue 只看程式碼結構,完全不懂業務語意。

所以最新趨勢是「兩種混合」

這就是為什麼 Diffblue 最新版加了「LLM 增強」模式——讓 LLM 出主意、處理業務邏輯,但用強化學習的驗證機制保證每個產出都能跑。兩者結合才是最強的。

三種工具的差異整理

工具類型怎麼產出測試能跑保證懂業務邏輯
LLM(Copilot 類)用想的(從訓練資料推測)30-45% 失敗
Diffblue 強化學習用試的(實際跑過驗證)接近 100%
Diffblue + LLM 混合LLM 出主意,強化學習驗證接近 100%



換個角度:讓「測試本身」變得更聰明

前面講的都是大廠在做的事。學術界提供了另一個關鍵答案,叫做 Property-Based Testing(屬性測試,PBT)。聽起來抽象,但概念其實超簡單。

比喻:傳統測試 vs. 屬性測試

傳統測試像是出考題:「2+3 等於多少?答案要是 5。」

屬性測試像是出規則:「不管什麼數字 a 和 b,a+b 應該等於 b+a。」然後讓電腦自動丟幾百個隨機數字進去試。

你寫一個規則,電腦幫你想出幾百種你沒想到的情況。對 AI 來說特別有用,因為 AI 寫測試最大的盲點就是「只會想到典型情況」

真實案例:用屬性測試找出 AI 寫的西洋棋程式的 bug

2026 年有個工程師用 AI 寫了個西洋棋配對程式(300 行,規則複雜)。他沒花時間 review 那 300 行,而是寫了幾條簡單的規則:

  • 「同一個玩家不能連續用同色三次」
  • 「兩個玩家不能配對兩次」
  • 「人數奇數時,輪空的分配要公平」

每條規則都是 15 行內的小函式,他自己一眼就能看懂。然後用屬性測試丟幾百種情況進去,結果抓到三類 AI 沒想到的 bug

他的工作流程是這樣的:

自己只寫規則(15 行),這部分人腦來

AI 寫實作(300 行),完全不看

跑屬性測試,失敗就會給出具體例子

把例子丟回 AI,讓 AI 自己修

這就是「人省力」的關鍵——人只負責想清楚規則,實作 300 行交給 AI,驗證交給機器


把所有東西整合起來:七道關卡

把大廠和學術界的做法整合,完整的驗證流程是這樣:

第一道關:邊寫邊審——AI 寫程式時,另一個 AI 在旁邊挑毛病(Google 模式)

第二道關:只看新程式碼的覆蓋率——不要看整體 80%,要看「這次改的部分」是不是 90% 以上有測到

第三道關:測試也要被審查——AI 寫的測試,要通過「能跑、穩定、真有用、不破壞舊功能」四個檢查(Meta TestGen-LLM 模式)

第四道關:故意把程式弄壞看測試抓不抓得到——讓測試證明自己真的有用(Meta ACH 模式)

第五道關:屬性測試找 AI 沒想到的情況——你定規則,機器幫你窮舉

第六道關:從真實使用紀錄產生測試——確保測到的是「實際會發生的事」(Meta TestGen-obs 模式)

第七道關:人只看規則和意圖——前面六道過了,人只需要確認「規則對不對」「需求懂得對不對」,不用看程式碼細節

到這裡,「人來不及 review」這個問題的答案才清楚:因為人從一開始就不該 review 細節,人該 review 的是規則和意圖


中小團隊版:四週上手,月費不到 100 美元

不是每個團隊都有 Meta 的資源。但好消息是,每一道關卡都有便宜或免費的對應工具。下面是務實的四週計畫。

第一週:從「只看新程式碼覆蓋率」開始

做什麼:把 PR 的「新增/修改部分覆蓋率」設成必過門檻。

用什麼:

  • Python 用 diff-cover(免費)
  • 通用用 Codecov 的 Patch Coverage(免費版就能用)
  • 公司內網用 SonarQube 的「New Code」規則

門檻:新程式碼覆蓋率 85% 以下不能 merge。

為什麼最該先做這個:這一招就直接打中你最擔心的問題——確認新東西真的有被測到。整體覆蓋率會騙人,新程式碼覆蓋率不會。

第二週:讓測試「被測試」

做什麼:每週對重要模組跑一次「故意改壞」的檢查,看測試會不會抓到。

用什麼(都免費):

  • JavaScript / TypeScript:Stryker
  • Python:mutmut
  • Java:PIT

起步建議:不要一開始就全部跑(會超慢)。挑最重要的 5-10 個模組(金流、登入、權限),每週跑一次就好。

會抓到什麼:AI 常寫的「假測試」——比如那種 assert true == true 永遠會過、或是只測順利情境完全不測錯誤處理的測試。

第三週:用屬性測試補強重要的函式

做什麼:對「邊界情況容易出包」的函式,加上屬性測試。

用什麼(都免費):

  • Python:Hypothesis
  • JavaScript / TypeScript:fast-check
  • Java:jqwik

最該加的場景:

  • 金額計算(大數、負數、零、四捨五入)
  • 日期時間(時區、閏年、夏令時間)
  • 字串處理(中文、空字串、超長字串)
  • 排序、配對、合併等演算法

起步建議:挑 3-5 個最重要的函式就好,每個寫 2-3 條規則。不用一次到位。

第四週:用 AI 反過來審 AI

做什麼:在 PR 流程加一個步驟,讓另一個 AI 檢查這次的 PR

怎麼做(用 Claude 或 GPT 的 API,一個 PR 大約幾分錢):

給 AI 看: 1. 這次 PR 改了什麼 2. 對應的測試改了什麼   問 AI: 1. 這段程式碼想做什麼?用一句話說 2. 測試有真的驗到這件事嗎? 3. 有什麼情況沒被測到?具體列出來 4. 有沒有明顯的 bug 或不好的寫法?

把這個寫成 GitHub Action,每個 PR 自動跑。AI 標出有疑慮的地方,人就只看那幾個地方


成本表:很便宜,而且馬上看得到效果

項目月費(美元)設定時間
新程式碼覆蓋率(Codecov)0-3030 分鐘
故意改壞測試(Stryker / mutmut)02 小時
屬性測試0每個函式 30 分鐘
AI 反向審查(Claude / GPT API)20-502 小時
合計20-80 美元約 1-2 個工作天

對比每個工程師每週可以省下的 review 時間,這個投資 ROI 高到不用算。


三個常見的陷阱,千萬要避開

陷阱一:把覆蓋率當作信心指標

整體覆蓋率會騙人,要看新程式碼覆蓋率。「故意改壞」的測試分數比覆蓋率更接近真相。

陷阱二:讓同一個 AI 同時寫程式和測試,沒有獨立檢查

這會出現「自己騙自己」的情況——測試和程式有相同的盲點,兩個都錯但互相通過。至少要讓測試用不同的提示語,或是用另一個 AI 來寫

陷阱三:覺得屬性測試太抽象就跳過

屬性測試確實需要先想清楚「這個函式的規則是什麼」,但這個思考本身就是釐清需求的過程。AI 想不出來的部分,正是值得人花時間想的部分。


結語:把信任放在系統上,不是放在 AI 身上

整篇文章想講的只有一件事:讓人敢省下 review 時間的關鍵,不是相信 AI 寫得好,而是建立一套機器化的關卡,讓「過關的程式碼」帶有可驗證的保證

Meta 之所以叫他們的方法 Assured(有保證的)LLMSE,就是這個意思——不靠感覺,靠機械化的證明。Google 把驗證提前到生成的當下。Diffblue 用確定性的方法保證每個測試都能跑。學術界用兩個獨立 AI 互相挑毛病。

這些做法都在講同一件事:機器在每一道關卡守住,人只在最後判斷需求對不對

中小團隊不需要 Meta 的資源,從新程式碼覆蓋率開始,一週加一個工具,四週就能建立完整的關卡系統。月費不到 100 美元。

到那時候,「人來不及看」這個煩惱才真正解開。因為人本來就不該看細節,人該看的是規則和需求。其他的事,交給機器去守就好。

這就是 2026 年面對 AI 寫程式時,真正可靠的做法。

發表迴響

探索更多來自 轉念學 - 敏捷三叔公的學習之旅 的內容

立即訂閱即可持續閱讀,還能取得所有封存文章。

Continue reading