Gemini 3.8 Flash 升級前,準備把 production 從 gemini-3.7-flash換到 gemini-3.8-flash時,最有用的第一步不是看總榜,而是先畫出一張 3 類任務 × 2 個模型 × 3 個 thinking level 的 18 格回歸表。每一格用同一份輸入、同一個驗收器與同一個重試上限,版本差異才不會和測試差異混在一起。
這篇提供三張可直接改成自己資料的 fixture 卡:程式修補、文件抽取、工具呼叫;再用一段 Python measurement spine 記下 token、首 token 延遲、總時間、模型版本與驗收結果。最後不是選一個全域冠軍,而是為三類任務各填一列暫定路由。
Gemini 3.8 Flash 的發布內容、Flash Cyber 與首日成本快照,AlphaLab 已在前篇深度解讀完整整理;本文不重複那條新聞線。以下是待你執行後填入結果的驗收協定,不會用假想分數冒充實測。
Gemini 3.8 Flash 升級先畫 18 格:每題先比 effort,再比版本
這份工作表有固定的閱讀順序。先在同一版本內看 low → medium → high 的 effort 曲線;找到能反覆通過該題硬門檻的最低檔。接著才在相同 effort 下比較 3.7 與 3.8,避免把「模型升級」和「多給推理資源」混成一個效果。
本文的決策錨點:每一類任務,都選擇能穩定跨過硬門檻、且每次通過成本最低的模型 × effort 組合。
- 版本內比較:3.8-low 對 3.8-medium 對 3.8-high,回答「這題需要多少 effort?」
- 同檔跨版比較:3.8-low 對 3.7-low,依此類推,回答「升級本身改變了什麼?」
- 不要跨檔下結論:3.8-high 贏 3.7-low,無法分開版本效果與 effort 效果。

開跑前鎖死 8 個欄位,只讓模型與 effort 改變
截至 2026 年 9 月 3 日,Google 的官方模型頁把穩定 ID 列為 gemini-3.8-flash;官方thinking 文件列出的支援檔位是 low、medium、high,預設 medium,而 minimal會回傳錯誤。3.7 Flash 也支援相同三檔,因此可以做 matched-effort 對照。
把下列資訊寫進每一次 run 的 receipt:API surface 與版本、精確 model ID、effort、完整 prompt hash、輸入資產 hash、工具 schema hash、timeout/retry 上限,以及帳號區域與服務層級。官方模型版本說明中的 stable不是不可變的日期版號,所以還要保存 response 回傳的 model_version與 response_id。兩個模型必須在同一測試窗口內隨機交錯重跑,不能拿舊 baseline 直接對新結果。
Gemini 3.8 的模型專屬遷移清單目前把 temperature、top_p、top_k列為 deprecated,並要求遷移時移除;因此這份最小對照不塞取樣旋鈕。只改模型與 thinking_level,其他差異另開實驗。
Fixture 1|程式修補:乾淨快照、固定測試、限制改檔
先從一個你有權使用的小型 repository 挑一個真實 bug。下面的路徑只是可複製格式;在第一次執行前換成自己的檔名,之後 18 格都不能再改。
task_id: patch-01
input: repo@COMMIT_SHA,起始狀態為 tests/test_money.py::test_round_twd 失敗
prompt: 修好這個失敗測試;不得新增套件、不得更改公開介面,只能修改 src/money.py
hard_gate:
1. 目標測試 exit code = 0
2. 完整測試 python -m pytest -q exit code = 0
3. git diff --name-only 只能出現 src/money.py
4. 不得刪除既有測試
reset: 每次 run 建立新的 clean worktree,指向同一 COMMIT_SHA
cap: timeout 120 秒;失敗最多重試 1 次
這題的 pass 由程式判定,不看回答語氣。第一次輸出若只是建議、沒有可套用 diff,或改了白名單外檔案,都記成明確的 failure reason;重試不能覆蓋第一次失敗列。
Fixture 2|文件抽取:一段固定文字、逐欄 exact match
先用純文字 fixture 排除 OCR 與影像解析變因。確認 runner 正確後,再把同一協定換成你有權使用的 PDF;屆時要把檔案 hash 與 media resolution 一起固定。
task_id: extract-01
input: |
供應商:青禾設計;發票編號:INV-2026-017;
應付金額:TWD 42,800;付款期限:2026-09-30。
prompt: 只輸出符合指定 schema 的 JSON,不得推測輸入中沒有的欄位
expected:
{"vendor":"青禾設計","invoice_id":"INV-2026-017",
"currency":"TWD","amount":42800,"due_date":"2026-09-30"}
hard_gate:
1. JSON 可解析且沒有額外 key
2. 五個欄位逐一 exact match
3. amount 必須是 number,不是字串
reset: 每次都送同一份 UTF-8 文字與同一份 JSON Schema
cap: timeout 45 秒;失敗最多重試 1 次
這是一個人造測試 fixture,不是帳單範例。它刻意讓幣別、千分位與日期格式都可自動驗收;換成真實資料時,先去識別化,再鎖定標準答案。
Fixture 3|工具呼叫:只准一個 mock 工具與一次副作用
不要拿正式訂單、郵件或資料庫測模型。先做本機 mock,讓錯工具、錯參數、多餘回合與最終回答都能被程式抓到。
task_id: tool-01
input: 使用者問「請查訂單 A-017 的目前狀態」
available_tool: lookup_order(order_id: string)
mock_return: {"order_id":"A-017","status":"已出貨","carrier":"黑貓"}
expected_call: lookup_order({"order_id":"A-017"})
hard_gate:
1. function name 與 arguments 完全正確
2. lookup_order 只呼叫 1 次,沒有其他工具呼叫
3. 最終回答包含「已出貨」且不得捏造到貨日
reset: 每次重建相同 mock state;不連任何 production service
cap: 最多 2 個模型回合;失敗最多重試 1 次
若要測真正的寫入工具,把「是否只產生預覽」與「是否需要人類確認」放進 hard gate;不要因為最終文字看似正確,就忽略中間已經造成的錯誤副作用。
建立 RUN_LEDGER:18 格是設定,不是只跑 18 次
每個 task 都有六個設定格;每格還要重複執行,才能看見輸出與服務延遲的波動。先每格跑一次 smoke test 找接線錯誤,再決定正式樣本數。小樣本只報原始值、中位數與範圍;不要用幾次嘗試假裝有可靠的 p95。
先把下面這列存成 runs.csv。每一次 API 嘗試新增一列,包括 timeout、被驗收器拒絕的輸出與重試:
attempt_id,task_id,run_order,model,model_version,response_id,api_surface,effort,input_hash,prompt_hash,tool_schema_hash,grader_version,input_tokens,cached_tokens,output_tokens,thought_tokens,tool_prompt_tokens,ttft_ms,total_ms,tool_turns,retry_no,passed,failure_reason,api_cost,tool_cost,human_minutes
另建一張 EFFORT_SUMMARY,key 固定為 task_id + model + effort,只放 attempts、passed、pass rate、總成本、cost per pass、時間中位數與範圍。最後一張 DECISION只有三列,分別對應 patch、extract、tool。

用 Python 3.10+ 建立 measurement spine
現行官方 Google Gen AI SDK需要 Python 3.10 以上。先確認版本;以下啟用指令適用 macOS/Linux,Windows PowerShell 則使用 .\.venv\Scripts\Activate.ps1:
python3 --version
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U google-genai
把獲授權的 key 放在環境變數 GEMINI_API_KEY,不要寫進程式、CSV 或 prompt。安裝後把 python -m pip freeze的版本存進 run manifest。下面依官方串流介面量一個純文字 request 的 TTFT 與總時間:
from time import perf_counter
from google import genai
from google.genai import types
client = genai.Client()
def run_once(task_id, model, effort, prompt):
started = perf_counter()
first_text_at = None
usage = None
model_version = None
response_id = None
output = []
stream = client.models.generate_content_stream(
model=model,
contents=prompt,
config=types.GenerateContentConfig(
thinking_config=types.ThinkingConfig(
thinking_level=effort
)
),
)
for chunk in stream:
if chunk.text:
if first_text_at is None:
first_text_at = perf_counter()
output.append(chunk.text)
if chunk.usage_metadata:
usage = chunk.usage_metadata
if chunk.model_version:
model_version = chunk.model_version
if chunk.response_id:
response_id = chunk.response_id
ended = perf_counter()
return {
"task_id": task_id,
"model": model,
"model_version": model_version,
"response_id": response_id,
"effort": effort,
"ttft_ms": None if first_text_at is None else round(
(first_text_at - started) * 1000
),
"total_ms": round((ended - started) * 1000),
"usage": usage.model_dump() if usage else None,
"output": "".join(output),
}
先用 extract-01測通這段骨架,再替 patch 與 tool 任務接上自己的 sandbox/function adapter。Google 的Interactions API 說明建議新專案使用 Interactions;這裡選仍受支援的 generateContent,是因為它能用一個短例子把串流與 usage_metadata攤開。多回合工具任務必須逐 hop 保存 request、response、function call 與用量,不能只記最後一輪。
正式跑矩陣時,建立全部 cell 後再隨機洗牌;3.7 與 3.8 要在同一窗口交錯,不要先跑完整批 3.7、隔天才跑 3.8。模型請寫精確 ID,不用可能被重新指向的 latest別名。
一份 ledger 做兩種比較:effort 曲線與 matched-effort 差
第一輪只看版本內曲線:例如 extract-01的 3.8-low、medium、high,各自有多少次通過、每次通過花多少、時間分布如何。品質未達門檻的格子直接淘汰;剩下才比成本與速度。
第二輪做 matched-effort:3.8-low − 3.7-low、3.8-medium − 3.7-medium、3.8-high − 3.7-high。每項差值都分開列 pass rate、cost per pass 與總時間,不把三個 task 平均成單一總分。

工作表只需要三條公式:
- pass rate=該格通過次數 ÷ 該格全部嘗試次數。
- cost per pass=該格所有嘗試的 API+外部工具成本 ÷ 通過次數;若通過數是 0,標記為不可用,不填 0。
- matched-effort delta=同 task、同 effort 下的 3.8 指標減 3.7 指標;需要百分比時,再除以 3.7 baseline。
官方token 文件會分列輸入、快取、候選輸出、thinking 與 tool-use prompt 等欄位。保存原始 usage;除非該 API surface 的現行文件明確定義,勿自行加總診斷欄位,實際成本並應按當天服務層級的官方價格與帳單核對。人工修正分鐘數可另列,但要事先決定是否折算成本,不能看完結果才改口徑。
Gemini 3.8 Flash 升級的 DECISION 只輸出三列
每一列都填:task → 3.7 最低通過 effort → 3.8 最低通過 effort → matched-effort 差 → 暫定選擇 → fallback。判讀順序固定如下:
- 程式修補:先守住完整測試與改檔白名單;若 3.8 只有提高 effort 才通過,就把新增成本與時間明列,不說成單純版本收益。
- 文件抽取:JSON 與逐欄 exact match 是硬門檻;若 low 已反覆通過,medium/high 只有變慢,就保留最低通過檔。
- 工具呼叫:錯工具、多呼叫或捏造欄位任何一項都淘汰;結果正確但路徑錯誤,仍不能進 production。

三個 runner 細節,最容易讓 18 格失去可比性
- patch 沒有真的 reset:上一格留下的 diff、cache 或依賴,會讓下一格看起來更快。每次從同一 commit 建新 worktree,測完保存 diff 再丟棄工作目錄。
- extract 的 schema 只驗格式:JSON 合法不代表金額與日期正確。格式 gate 和逐欄答案 gate 都要過,才算 passed。
- tool 只看最終一句:把 function name、arguments、呼叫次數、順序與 mock state 納入 grader;所有實際副作用保持關閉。
若同一輸出需要人工判讀,先隱藏 model、effort 與 run order,再讓評審依預先寫好的 rubric 選 pass、fail 或無法判定。完整的 cases、grader、traces 與 evaluator receipts,可接著讀AI Evals 入門;不要在這個 18 格工作表裡重造整套通用評測系統。
Gemini 3.8 Flash effort 工作表 FAQ
1. 為什麼是 18 格,不是 6 格?
因為三類任務不能共用一個勝負。每個 task 有 2 個模型 × 3 個 effort,共六格;patch、extract、tool 三題合計 18 格。每格重複幾次是另一個維度。
2. 為什麼不能只比 3.8-high 與 3.7-high?
因為你看不到甜蜜點。high 只顯示其中一檔;如果 low 已穩定通過,額外 effort 未必值得。三檔曲線先完成,matched-effort 比較才有上下文。
3. 可以把 3.8 Flash 設成 minimal嗎?
不可以。目前官方文件列出 low、medium、high,minimal 對 3.8 Flash 會回傳錯誤;low 也不等於完全關閉 thinking。
4. 為什麼範例沒有設定 temperature?
因為 3.8 的模型專屬遷移清單目前把這些傳統 sampling 參數列為 deprecated,並要求遷移時移除。這個回歸只比較 model 與 thinking level,不混入已要求移除的旋鈕。
5. 每格到底要重複幾次?
沒有脫離風險與差異大小的通用數字。先每格一次 smoke test 抓 wiring bug;正式測試再按錯誤成本與可接受不確定性增加重複。樣本很少時公開原始值與範圍,不宣稱穩定 p95。
6. tool_use_prompt_token_count要再加到總 token 嗎?
不要自行猜測欄位間的算術關係。保存原始 usage;只有在該 API surface 的現行文件明確定義時才據此加總,並用官方價格與實際帳單核對。
7. 為什麼不用 gemini-flash-latest?
因為 alias 可能改指向。回歸測試要寫精確 model ID,並保存回傳的 model version;否則兩次 run 可能不是同一個服務版本。
8. 沒有 Gemini API key,現在能先做什麼?
先完成三張 fixture 卡與 grader。固定輸入、prompt、hash、timeout、retry、pass gate 與 reset;拿到獲授權的 key 後,先跑 extract-01 的六格 smoke test,再開完整矩陣。
給新手的 5 個重點
- 三個 task 各有六個設定格;18 格不是只執行 18 次。
- 先在版本內找最低通過 effort,再做同 effort 的 3.7/3.8 比較。
- 每次嘗試都保存 model version、response ID、hash、usage 與 grader receipt。
- patch、extract、tool 各有自己的硬門檻,不能平均成一個模糊總分。
- DECISION 只輸出三列任務路由;沒有一個 effort 必須統治全部工作。
接著閱讀
左右滑動查看更多推薦
結語:今天先封存三張 task card
Gemini 3.8 Flash 升級的第一個可交付物,不是「新版比較強」的一句話,而是三張不會在看完結果後變動的 task card。先固定 patch-01、extract-01、tool-01 的 input、prompt、gate、reset 與 cap,再跑六格 smoke test。
等 18 格都有可重播 receipt,再依固定順序讀結果:版本內 effort 曲線、同檔跨版差、三列 DECISION。若你想把這個小型回歸延伸成可維護的 AI 工作流,可從 AlphaLab 的課程與實作資源繼續往下做;今天先把第一張 task card 寫完整。





