# gemini-3.7-flash-high 對 sonnet-5-medium

> 2026-08-14，三輪各一題。gemini-3.7-flash-high 對 sonnet-5-medium，同一份凍結契約與 prompt。blind test 分數、Opus 的缺陷，以及實作和 review 的 USD。

- Date: 2026-08-14
- Tags: model-routing, gemini-3.7-flash-high, sonnet-5-medium, blind-test

同一份凍結契約，三輪各一題。blind test 分數、Opus review 找到的缺陷，以及 2026-08-14 兩邊花掉的 USD。

## 這次量了什麼

這篇筆記是三輪，每一輪只有一題。樣本就是這些。它不是排行榜，也不是對任一模型的統計結論。

跑的日子是 2026-08-14。兩邊實作的是 `gemini-3.7-flash-high` 和 `sonnet-5-medium`。拿到的是同一份凍結契約、同一份逐字相同的 prompt，只換了輸出目錄。兩邊各自實作。評分用的 blind test 沒看過任何一份實作。之後各派一隻 context 乾淨的 Opus 5 medium 做 review：找出缺陷、寫成會失敗的測試、修到那條測試通過。

下面的金額是 2026-08-14 的價格，單位 USD，算的是實作加上它自己的 review。公開價目會變。現在對過的卡片在 [LLM Pricing](https://bytescope.dev/zh-Hant/llm-pricing/)。這裡不推薦任何一家，也不是在替這個網站打廣告。

## 三個題目

第一輪是 photo-organizer 的純函式：EXIF 日期、是不是截圖、歸檔計畫。契約寫到一份事實清單的程度。

第二輪是能拆開循環的搬檔排程：把循環拆掉、精準的 `undo`、避開 O(n²)。介面凍結，演算法留白。

第三輪是用純 TypeScript 做 raw DEFLATE 的 inflate，RFC 1951。正確性放在 prompt 外面。prompt 裡沒有格式表格。

| 輪次 | 題目 | 難度怎麼設計 | 裁判 |
| --- | --- | --- | --- |
| 1 | photo-organizer 純函式（EXIF 日期、截圖判斷、歸檔計畫） | 契約寫到事實清單的程度 | blind test 104 題 |
| 2 | 能拆開循環的搬檔排程（拆循環、精準 undo、避開 O(n²)） | 介面凍結，演算法留白 | blind test 118 題，加上虛擬檔案系統模擬器 |
| 3 | 純 TypeScript 的 raw DEFLATE inflate（RFC 1951） | 正確性在 prompt 之外（沒有格式表格） | blind test 109 題，加上跟 zlib 逐 byte 對照 |

## 兩邊拿到的東西

兩邊拿到的是同一份凍結契約，prompt 也逐字相同。prompt 裡唯一的差別是輸出目錄。

blind test 寫的時候，兩份實作都不在眼前。review 不是實作者本人：每一邊各一隻 context 乾淨的 Opus 5 medium，負責找缺陷，並且用一條會失敗的測試把它釘住，直到修好。

## 花了多少

一輪的價錢，是那一邊花在實作、以及 review 自己的 code 上的錢。表上是記錄下來的 USD。沒有估算，也沒有為了好看而四捨五入。

第一輪打平。review gemini 的 code 比較貴，因為 reviewer 得從零寫一份參考實作，才能證明那個缺陷。第二輪和第三輪，gemini 的 code 乾淨到 reviewer 比較省力，帳單才真的降下來。

| 輪次 | gemini USD | sonnet USD |
| --- | --- | --- |
| 1 | $6.00 | $5.98 |
| 2 | $4.18 | $7.82 |
| 3 | $6.54 | $10.38 |
| 合計 | $16.72 | $24.18 |

## 結果對不對

每一個分數都只代表一題。三題湊不出合格率。某一題滿分，也不等於那個模型就是這樣。

第一輪，blind test 104 題，兩邊都是 104/104。Opus 在 gemini 的 code 找到 1 個缺陷，嚴重程度 medium；sonnet 1 個，嚴重程度 low。契約疑問的回報：gemini 0、sonnet 3。

第二輪，blind test 118 題，旁邊有一個虛擬檔案系統模擬器，兩邊都是 118/118。Opus 兩邊都找到 0 個缺陷。契約疑問：gemini 0、sonnet 3。第三輪是 blind test 109 題，再加上跟 zlib 逐 byte 對照。記錄下來的分數是 gemini 106/108、sonnet 104/108。記錄寫的是 109 題，分母卻是 108，而當時的暫存套件已經刪掉、沒辦法回頭數，所以兩個數字照原樣並陳，不挑一個看起來合理的。Opus 在 gemini 的 code 找到 3 個缺陷，其中 1 個是 silent corruption；sonnet 2 個。契約疑問還是 gemini 0、sonnet 3。

最後那一欄被當成分數之前，先補一句：被動的指令量到的是主動性，不是能力。三輪的 prompt 都只寫「發現矛盾就回報」，沒有一輪把「先把契約讀過一遍」列進工作步驟。gemini 五次都沒開口，但這跟「叫它去審也審不出來」是兩回事。

| 輪次 | gemini 分數 | sonnet 分數 | Opus 缺陷，gemini | Opus 缺陷，sonnet | 契約疑問，gemini | 契約疑問，sonnet |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | 104/104 | 104/104 | 1 (medium) | 1 (low) | 0 | 3 |
| 2 | 118/118 | 118/118 | 0 | 0 | 0 | 3 |
| 3 | 106/108 | 104/108 | 3 (其中 1 個是 silent corruption) | 2 | 0 | 3 |

## 什麼情況派誰

規格已經定了，而且想快、不想多花錢的時候，這三題指向 `gemini-3.7-flash-high`。三輪跑下來記錄的是便宜 31%、快 1.9–2.6 倍。31% 就是上面那張費用表。至於那個速度倍數是拿什麼量的，記錄裡沒有寫；它不是這頁最後那幾個解碼時間，那幾列的比例是另一組數字。

需求是速度的時候，像協定解碼、一批一批的處理，派 gemini。inflate 那題它自己就去做真正的最佳化：查表，以及整塊複製，而不是一位一位走。

錯一個位元組就收不回來的時候，寫檔、刪檔、蓋掉原檔，誰寫都可以。Opus 的 review 不能省。第三輪就是這個 review 抓到一個回報成功、卻吐出錯誤位元組的解碼器。

規格才寫好、還沒有人 review 過的時候，先把規格交給 Opus，再交給寫程式的人。這篇裡的三份契約，這樣審出來的漏洞一共 12 個。別指望寫的人順手幫你抓出漏洞。

blind test 維持交給 `sonnet-5-high`。同一個家族寫自己要考的卷子，那就不算裁判。上面這些都是三題、每輪一題的讀法。

## 同一個錯，犯了兩次

gemini 兩次犯同一個錯，所以這是那份 prompt 的習慣，不是手滑。第一輪它把 `trim()` 套到 `"."` 和 `".."` 的判斷上。契約只對空字串做 trim。`" . "` 這種檔名被當成不合法。

同一份 prompt 跑了兩次，兩次都錯。修好的那一份跟 sonnet 的實作對打，行為處處相同，0 個分歧；沒修的第二份差了 40 處。

## 會舉手，不等於舉對

會把疑問提出來，不等於那個疑問讀對了。第三輪 `HLIT` / `HDIST` 的上限，sonnet 有回報這個模糊的地方，可是方向判錯了：它把 alphabet 的槽位數 288/32 當成合法上限。gemini 沒有回報這一點。即便如此，gemini 解碼器的 `HLIT` 那一半是對上的那一半。

真正成立的上限是已定義的符號數 286/30。這個數字是拿 `zlib.inflateRawSync` 當權威裁決出來的，不是挑一個比較好實作的讀法。

## 為了快而複雜，邊界沒測乾淨

gemini 為了快，選了比較複雜的設計，複雜度多出來的邊界卻沒測乾淨。第三輪它用 2-level 的位元反轉查表。對上 sonnet 那種 `puff.c` 式、一個 bit 一個 bit 走的做法，這張表快了 3–27 倍。

這張表的代價是 silent corruption。單一符號表的特例會接受任何宣告長度，卻一律把那個符號裝成 1 bit。後面的 bit 流整個錯位，函式回傳 `ok: true`，外加垃圾位元組。跟這份 code 一起寫的 65 個測試沒抓到。context 乾淨的 Opus review 抓到了。

## review 佔了大半費用

review 大約佔了九成的費用。實作便宜，本身省不了錢。code 乾淨到 review 變短，才省得下來。

第一輪沒有省到。兩張帳單差不多，而且 gemini 的 review 比較貴，因為 reviewer 得從零寫一份參考實作，才能證明缺陷。第二輪和第三輪，gemini 的 code 乾淨到 reviewer 比較省力，費用表上的合計才降下來。

## 8MB 輸出的解碼時間

這篇唯一的計時來自第三輪，輸出 8 MB，只算解碼。ZIP 裡最常見的 stored block，gemini 是 1 ms，sonnet 是 32 ms。literal 多的輸入是 59 ms 和 218 ms。match 多、或是全零的輸入，gemini 21 ms，sonnet 13 ms，這一列是 sonnet 比較快。

| 輸入 | gemini | sonnet |
| --- | --- | --- |
| stored block（ZIP 裡最常見） | 1 ms | 32 ms |
| literal 多 | 59 ms | 218 ms |
| match 多，或是全零 | 21 ms | 13 ms |
