iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0
AI Engineering

AI 寫的測試,誰來測?系列 第 2

【Day2】三招驗證法,為什麼一招都沒中?

  • 分享至 

  • xImage
  •  

TL;DR

  • 昨天的三種驗證法各有各的盲區,但它們的盲區是同一種:都只能檢查我事先想得到的東西
  • 其中最根本的一招——請 AI 檢查它自己寫的程式碼——不是不夠聰明,是結構上就不成立
  • 有一篇論文替這件事做了實驗,但它證明的東西比你以為的窄,我會把界線劃清楚

https://ithelp.ithome.com.tw/upload/images/20260902/20103826Nwm92iZCsB.jpg


前言

昨天留了一個問題:特定值驗證、邊界測試、AI 自我解釋,三招都做了,四個缺陷零個被抓到。為什麼?

就讓我們看下去~

盲區一:我只驗了一條路

那個退休試算其實同時算兩件事。

一條路是資產累積——從現在到退休,每年存多少、滾多少,畫出圖表上那條往上爬的曲線。另一條路是退休目標金額——退休後每年要花多少,換算成退休那一刻該準備好的金額。

最後把兩個數字相減,就是「缺口」。

我那時的特定值驗證,測的是「65 歲會累積到多少錢」。只有第一條路。

更正說明:
昨天說過,我驗的那一版後來被覆蓋了。但兩條路徑這個結構是共通的:去年那版用 4% 法則反推目標金額,現在這版用逐年折現,方法不同,但都是不同於累積路徑的第二條路。在這兩版都只驗了累積那條。

缺陷 A 不住在任何一條路裡面,它住在兩條路之間:兩邊對「錢是年初進出還是年底進出」的假設不一樣。

補充說明:
四個缺陷分別是:輸入打錯字靜默丟棄(缺陷 D)壽命倒掛反而恭喜準備金充足(缺陷 B)超壽命的幽靈大筆支出(缺陷 C),以及最深層的跨期假設不一致與負值遮蔽(缺陷 A / A')

其中 D、B、C 都是輸入與邊界沒防好,之後會逐一驗屍。但今天我們要聊的是那三招驗證法看似嚴密,為什麼連致命的「缺陷 A」都抓不到。

這種缺陷有個很討厭的性質:兩邊各自算都是對的。 把第一條路單獨拿出來驗,它是對的;把第二條路單獨拿出來驗,它也對。錯的是它們「沒有對齊」,而對齊這件事不屬於任何一條路,它屬於兩條路的關係,是要兩個都要有的共識,這樣計算才有基準點。

所以不是我測得不夠多,是我測的維度不對。所以,我們再多測一百組累積期的數字,也不會有任何一組告訴我這件事,因為數值都是對的

盲區二:我挑了一組會讓缺陷消失的數字

邊界測試那招,我做了兩件事:把報酬率和通膨率都設成 0%,看資產總額是不是等於單純加總;再用一組心算得出來的數字(30 歲、一年、100 萬、10% 報酬)確認它算得出 110 萬。這就是問題所在。

為什麼呢?

期初投入和期末投入的終值,關係是這樣:

期初投入的終值 = 期末投入的終值 × (1 + r)

同一筆錢,年初放進去比年底放進去,多滾一年的利息,就是多一個 (1 + r) 倍。而缺陷 A 造成的偏差,正好就是這個倍數。

現在把 r = 0 代進去:

(1 + 0) = 1

倍數變成 1,兩邊完全相等。

我為了「簡化驗證的複雜度」把報酬率設成 0,而報酬率設成 0,正好是這個缺陷在數學上唯一會完全消失的地方。

我用一組讓缺陷隱形的數據,去測那個缺陷。而且我還在文章裡說,這樣做是為了讓驗證更單純。

邊界測試不是萬靈丹。它的前提是你已經知道邊界在哪、也知道爆掉會長什麼樣。當缺陷是「兩條路對不齊」的時候,邊界在哪?沒有邊界。歸零反而是最安全的地方。

盲區三:我請作者當裁判

前兩個盲區還算好懂——測錯維度、挑錯數字,下次注意就好。第三個不是這樣,它沒有「下次注意」的版本。

我把程式碼貼回一個新的 Gemini 視窗,要它解釋自己的計算邏輯。

今年八月,ryanvale 在一篇談 coding agent 的文章裡,把這件事的結構寫得很清楚。他講的是 agent 會自己開瀏覽器跑 E2E 測試然後附上一張成功截圖的情境:

程式由 agent 修改,瀏覽器由 agent 操作,成功證明還是 agent 自己挑的。速度確實變快,但實作者與驗收者也合併成同一個信任來源。

他還有一句更精闢的點出盲點:這種情況下,它驗證的是「自己做出來的東西能不能照自己的理解運作」,而不是使用者要的功能。

這正是我去年做的事。

回頭看去年 Gemini 那份解釋,它的第二步在講資產累積,把假設交代得一清二楚——「年初的總資產加上今年投入的新資金,得到本利和,再乘上報酬率」,標準的期初投入;第三步在講退休目標金額,講的是 4% 法則、乘 25 倍、通膨換算。

兩步都對,兩步都清楚,但沒有任何一步在問「這兩步的假設一致嗎」。

因為沒有人問。我要它做的是逐段翻譯,它就逐段翻譯了,翻得又快又好。而缺陷躺在段落與段落的接縫上,那個位置不屬於任何一段,所以任何一段的翻譯都不會經過它,就這樣大家都忽略了。

ryanvale 那篇還有一句可以直接搬過來當標語:截圖是證據材料,不是驗收結論。 我當年那個 20,281,460 對得上,也是證據材料,不是驗收結論。

論文說了什麼,沒說什麼

有一篇論文常被拿來講這件事:Large Language Models Cannot Self-Correct Reasoning Yet(arXiv:2310.01798),Google DeepMind 與 UIUC 的團隊,2023 年底發表。

它做的實驗是:讓模型先答一次,再叫它「檢查一下你的答案」,然後看準確率怎麼變。結果是:

the accuracies of all models drop across all benchmarks

所有模型、所有測試集,準確率全部下降。 不是沒有提升,是往下掉。GPT-3.5 在 GSM8K 從 75.9 掉到 74.7,在 CommonSenseQA 從 75.8 掉到 41.8。

論文對原因的說法很直接:

LLMs cannot properly judge the correctness of their reasoning

模型沒辦法正確判斷自己的推理對不對。這跟「模型很笨」是兩件事,AI 模型答得出來,但它分不出自己答得對不對,而「檢查一下」這個指令會把它從原本的答案推開,推向另一個不見得更好的答案。

然而,這篇論文測的是數學應用題(GSM8K)、常識問答(CommonSenseQA)、多跳問答(HotpotQA),還有一個受限生成任務。它沒有測任何程式任務。 論文自己在第 7 節劃了界:「our work focuses on evaluating reasoning of LLMs」,並明說在其他領域可能存在有效的自我修正策略。

所以不能說這篇論文證明了「AI 看不出我的精算 bug」。它證明的是更基礎、也更難反駁的一件事:在沒有外部回饋的情況下,叫模型再檢查一次,是無效的,而且經常有害。

而我當年做的,正好就是沒有外部回饋的自我檢查。

論文在討論章節倒是提到了一個關鍵詞,值得完整引用,包括它的前提:

when the problem description clearly specifies the intended code execution behavior, e.g., with unit tests, the code executor serves as the perfect verifier

程式執行器可以是完美的驗證者,但前提是「問題描述清楚指明了預期的執行行為」。順帶一提,這句話在論文裡是轉引 Chen et al.(2023b)的成果,不是它自己跑的實驗。

那個前提值得提一下。「執行器是完美 verifier」聽起來像是把程式碼丟進去跑就沒事了,但真正在做事的是清楚的規格。執行器只負責忠實地執行;它判斷不出你的規格本身是不是漏了一條。

我的退休試算沒有規格,它上線一年,沒有任何一份文件說過「錢應該在年初還是年底進出」,因此那個前提沒被滿足,這才是四個缺陷能活一年的真正原因。

於是乎...

三個盲區看起來各不相同,但它們共用同一個結構:

特定值驗證,測的是我挑的那組數字;邊界測試,測的是我認得出來的那些邊界;AI 自我解釋,問的是一個跟被檢查對象同源的證人。

三招合起來,覆蓋的仍然是我腦中那張已經存在的地圖

要跳出這張地圖,方法只有一種:引進一個不是我、也不是它給的判準。 這也是整個系列接下來三十天在做的同一件事,只是換了三種形式——用另一個實作當參照、用不變的數學關係當參照、用故意弄壞的程式當參照。

明天開始拉開簾子,逐個解剖那四個缺陷。

後記

這篇的初稿,我是請 AI 幫我寫的。

它交回來一篇結構工整、術語精確的文章。裡面有一段我跟 Gemini 的對話,加了引號,寫著我去年問它「這段程式碼有沒有潛在的 Bug?」,它回我「這段程式碼邏輯清晰,完整實現了退休金規劃的核心精算流程」。

我沒問過這句話,Gemini 也沒回過。去年我問它的是「請用白話文和條列式,向一個完全不懂程式的人,解釋這段 JavaScript 的計算邏輯」,原文還掛在去年鐵人賽文章 上,一查就知道。

它替我編了一段除錯經歷,還有兩段標著行號的原始碼。

我盯著那份初稿看了很久。文章在講:AI 會生出一份流暢的、術語正確的、看起來無懈可擊的合理化。而我手上這份初稿,就是如此的合理化。

我沒有生氣,我甚至有點感謝它:省下我編一個例子的力氣,直接把例子做出來了。

思索這件事後,發現讓我背後發涼的事實:那份初稿裡有引號、有行號、有具體到小數點的數字。 而正是這些具體性,讓它讀起來比一段模糊的猜測可信得多。有行號的幻覺,比說不出行號的幻覺危險。

我花了幾分鐘把原文翻出來對照,就知道那段對話是假的。問題是,我剛好會去翻。

https://ithelp.ithome.com.tw/upload/images/20260902/20103826jg0qejQ5zU.jpg


只帶走一件事
我當年不是沒有驗收者,我只是找了一個跟被驗收對象同源的驗收者。


免責聲明:本文提及之退休試算工具與所有數字皆為假設性試算,不構成任何投資建議。該工具目前已知存在計算偏差,修正版製作中,結果僅供參考。


上一篇
【Day1】我的退休試算上線一年,我檢查過,它「沒問題」?
下一篇
【Day3】四個缺陷的驗屍報告
系列文
AI 寫的測試,誰來測?3
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言