aire.
·6 分鐘

我以為找到更好的模型,後來發現只是它比較不愛說話

我要替一個工具挑一個便宜的模型當第一道關卡,於是拿 48 道有標準答案的題目讓兩個候選對打。第一版數字差了十五個百分點,看起來勝負分明——直到我攤開那些答錯的題目,發現落後那個大多是答對了、只是話比較多。這篇記錄我怎麼一步步發現自己量錯了東西,以及把場子拉平之後那個沒料到的代價。

收進
本文涉及工具

前言

這是一篇過程記錄,不是方法論。

起因很單純:我在維護一個小工具,它會先用便宜的模型處理任務,處理不好才往上升級。便宜的那一階原本用某個模型,另一家剛好降價,我想知道換不換划算。

做法也很單純——找 48 道有標準答案的題目(算式、程式輸出預測、數論題這類,對錯可以用程式判定,不需要人來評分),讓兩個候選各跑三次取多數,比答對率和花費。

第一版數字出來,看起來勝負分明。然後我花了一整天,把自己的結論推翻了兩次。

下面是那個過程。

第一版:差十五個百分點

答對 答對率
候選 A 40 / 48 83.3%
候選 B 47 / 48 97.9%

差七道題。如果我在這裡停手,報告會寫「候選 B 明顯較佳」,而且還會補一句它比較便宜。

我停手前多做了一件事:把答錯的題目攤開來看

攤開來看:大部分是答對的

候選 A 那八道錯題,我一題一題讀它的回答。其中六道,答案是對的

問題出在計分規則。那批題目要求「最後一行只寫答案」,計分方式是取回答的最後一個非空行去比對。而候選 A 的習慣是答完之後再補一段解釋:

因此字典只有一個鍵值對,len(d)1

答案 1 就在那裡,只是它不在最後一行的位置上,最後一行是這整句解釋。另外幾題是它把答案包進程式碼區塊,於是最後一行變成區塊的結束符號。

候選 B 的這類問題少很多,48 題裡只有一題,因為它習慣直接給答案、不多話。

這跟誰比較聰明沒什麼關係,比較像是誰的話比較少。

同一批答案,換個計分方式

我寫了一版容忍格式的計分:折疊異體字、去掉程式碼圍欄和反引號,並且把「最後一行必須相符」放寬成「任何一行相符即可」。

關鍵是沒有重跑。用的是同一批已經存下來的回答,只是重新評分一次。

嚴格計分 容忍計分
候選 A 40 / 48 46 / 48 6
候選 B 47 / 48 48 / 48 1

差距從七道題縮到兩道。原本那個「十五個百分點」,大半是計分方式造成的。

這裡有一個地方我試過但退回來了。我一度想乾脆改成「答案有出現在回答裡就算對」,那樣這一類格式問題就會消失。不能這樣做——「這題的答案不是 3」這種句子也會被判成答對。容忍格式可以,容忍語意不行,這條界線一旦越過,計分器就完全失去意義。

那到底誰比較好?把場子拉平再打一次

換個計分方式只是換一把尺。更公平的做法是讓兩邊都有機會把格式做對,再比一次。

我在系統提示裡加了一段格式要求——說明寫在前面、最後一行只放答案、不要用程式碼圍欄。兩個候選吃的是同一段字串。

⚠️ 這是另外重跑的一批,不是拿前面那批答案重評,所以「原本的提示」這欄的數字跟前面那張表會有一兩題出入——模型輸出本來就不是每次一樣。

原本的提示 加上格式要求
候選 A 40 / 48 46 / 48
候選 B 48 / 48 47 / 48

加提示這一批候選 A 的嚴格分數是 46/48,剛好等於原批的容忍分數。但逐題比對之後我發現不是同六題被修好:原批那六題裡有一題加了提示仍然錯,而原批一題真的答錯的反倒轉對了。兩個反向變化剛好抵銷成同一個總分。候選 B 的變化很小:這一輪它從 48 題全對變成 47 題,輸出長度也降了約兩成。

到這裡看起來皆大歡喜。直到我看了成本。

沒料到的代價:修好格式,多花六成六的錢

候選 A 輸出 token 花費
原本的提示 14,464 基準
加上格式要求 22,007 1.66 倍

加了那句「說明寫在前面、最後一行只放答案」之後,它把推理寫得更完整了:輸出長度增加五成,成本增加六成六。

所以「把候選 A 拉到只差一題」這件事是做得到的,但要用 token 買。 如果我只比調平後那一輪的分數,會得到「差距很小」的結論;只比原本的分數,會得到「候選 B 大勝」的結論。兩個都不完整。完整的說法是「在這組設定下候選 A 追到只差一題,但追上的代價要算進去」。

這是整個測試裡我覺得最有價值的一段,而它在第一版數字裡完全看不到。

另外兩件我沒測乾淨的事

這篇是過程記錄,所以我也把沒做好的部分寫出來。

取樣次數可能不夠。 我每題跑三次取多數。後來我在另一組題上把次數拉到五次、跑了 50 個樣本,其中一個模型在那一輪的觀測正確率是 68%。而如果一個模型的單次正確率是七成、每次獨立,三次裡至少對兩次的機率是 78.4%。換句話說,三次多數決有可能把偶然命中放大成滿分。我只有這一輪觀測,沒有做次數對照實驗,所以這裡只能當成提醒:k 太小可能放大偶然命中。這不是通則,我沒有資格下。

兩邊的推理設定可能不一樣。 現在有些模型你不特別設定就會先做一段內部推理,有些則要明確打開。我檢查程式碼時發現整個測試從來沒設定過這個參數,也就是說兩邊可能開在不同狀態下。我後來把它拉出來當變數重跑,關著推理的那一邊表現仍然很好,因為它把推理寫在了看得見的回答裡。所以影響沒有我擔心的大。但在我把它揪出來之前,我並不知道自己在比什麼,這件事本身就值得記一筆。

那結論到底是什麼

寫到這裡該回答一開始那個問題了:換不換?

換。但理由跟第一版數字給我的不一樣。

第一版說候選 B 大勝七道題。那七道裡有六道是格式,把提示補齊之後只剩一到兩道。在這 48 道題、這兩種提示與計分設定下,可觀測的分差從七題縮成一到兩題。(縮小不等於相同——候選 B 在每一種設定下都還是小幅領先。)

真正沒有變的是花費。候選對打那一輪,候選 B 的花費約為候選 A 的 15%,而它在沒有那句格式提示的情況下,嚴格分數就已經是 47/48。至於候選 A,把它拉到只差一題是做得到的,但那一輪它的成本變成原本的 1.66 倍。

所以這個決定的重心,從「B 準很多」移到「殘餘分差只剩一兩題、成本差很大」。結論一樣,但支撐它的理由換了。而理由才是下次還能不能複用的東西。

(後續補記:我後來另外造了一組 modexp 題目,拿候選 B 跟更高一階的旗艦模型對打,五十次取樣裡候選 B 答對 34 次,旗艦五十次全對。那組題我沒有讓候選 A 跑,所以這不是 A 與 B 的比較,也不是一次難度邊界測試。兩組題沒有共用的難度標尺,我不能把差異唯一歸因於「更難」。它只說明一件事:在那組 modexp 題上,候選 B 對旗艦是 34/50 對 50/50。 我原本那 48 題得到的結論不會自動套到別的題組上。)

這次測試教我的三件事

一、先看失敗的題目長什麼樣,再看百分比。 這是唯一一件我做對而且救了整份測試的事。如果我只看那張 83% 對 98% 的表,後面這些發現大概都不會出現。

二、計分方式要當成變數,不是背景。 同一批答案兩種評分方式各跑一次,差值就是形式扣分。差值大的時候,先問自己在意的是能力還是格式服從度。兩個都是合理的答案,但你要知道自己在量哪一個。

三、把場子拉平之後,要順便看成本,也要看題庫的邊界。 「調一調就追上了」跟「調一調、多花六成六追上了」是兩個不同的結論,而只看答對率的報告只會給你前面那個。另外,任何「分差很小」的結論都只在你測過的那組題、那種計分設定下成立。我換一組題再測,同一個便宜模型對旗艦就出現明顯落差。題組換了,結論不會跟著走。

順帶一提,這幾個現象在公開研究裡都有人做過。例如 FBI: Finding Blind Spots(EMNLP 2024)研究了 AI 評審漏看植入錯誤的情況,No Free Labels 則探討 AI 評審的判斷在哪些題目上才與人類一致。有興趣可以直接看原文,我這裡不轉述它們的數字。我這次撞到的雖然是機械比對規則而不是 AI 評審,機制不同,但指向同一件事:分數會被回答的形式左右,而形式跟對錯無關

給非工程師的一句話

看到「A 模型比 B 模型準幾個百分點」這種數字時,值得多問一句「那些答錯的題目,是真的答錯,還是答對了但沒照格式寫」。這一問在我這次測試裡,讓七道題的差距縮成兩道。

常見問題

為什麼同一批答案,換個計分方式分數會差這麼多?

因為很多自動計分規則是在比對輸出的形式,而不是判斷內容對不對。例如「取回答的最後一行跟標準答案比對」這種規則,遇到模型答對之後又補一段解釋,最後一行就變成解釋而不是答案,於是判錯。答案本身沒問題,是規則沒接住。

那我該用寬鬆的計分方式嗎?

不是二選一,是兩種都跑一次然後看差多少。差距大就代表你的計分規則在量格式服從度,這時要判斷你在意的到底是什麼。如果模型的輸出要餵給後續程式處理,格式不合就是真的不能用,嚴格計分是對的;如果是給人看的,那就不該因為多寫一段解釋而扣分。

把格式要求寫進提示詞,是不是就沒問題了?

問題會換一種形式出現。我實測把格式要求寫死進去之後,原本落後的模型追到只差一題,但它的輸出長度增加了五成、成本增加超過六成。品質是用 token 買回來的,這筆帳要算進選型裡,不能只看答對率。

做這種測試最基本該注意什麼?

至少三件事:一、題目的標準答案要能被程式判定,不要用需要人主觀評分的題;二、把 API 錯誤跟答錯分開記錄,被限流的呼叫算成答錯的話,你量到的是服務穩定度不是模型能力;三、每題跑不只一次,並且把每次結果都留著,不要只留平均值。

📚 收進你的工具

For AI Reading Era

把這篇文章交給你日常用的工具——做研究、整理筆記,或當 AI 的 context。

 
延伸閱讀