7 道必掛題的病因清單

過去跑的評測結果:gemma4 E2B v3 fused 在 16 題裡有 7 道一致失敗(3/3 rep 全掛)。 今天的目標是先把病因分類清楚,再決定要不要投資微調資料。逐題診斷:

09_multifile_add_field:aider 的 whole-file parser 把 gemma 輸出的 - models.py(帶項目符號破折號)整個當成檔名,建出錯誤的新檔,真正要改的檔案完全沒動到。格式解析 bug,非能力問題。

06_refactor_dedup:gemma 把檔名寫成 show_report.py,真實目標是 report.py。追到根源:aider 內建 few-shot 範例的示範檔名就是 show_greeting.py,前綴汙染造成幻覺。格式層問題,不是訓練造成的,大概率訓練也難治。

03_add_function:docstring 明寫「單位不分大小寫」,實作沒做 .upper()規格遵循不全。

14_fix_level_count:用 "WARN" in line 子字串比對,誤判 WARNING 和訊息內文裡含 WARN 的行。規格遵循不全。

16_parse_duration:只吃最後一個時間單位,沒做多單位累加、沒擋重複單位輸入。實作不完整,歸入規格遵循精確度。

12_write_tests_stack:測試寫了 from stack import OverflowError,把 Python 內建例外名當作模組自訂例外 import。符號幻覺,與 v5c/v5d 治的工具清單 grounding 同款病,只是從工具名換成程式碼符號。

13_trace_qa:複合問題「哪個函式+哪個例外類別」只答對後半,漏答 apply_coupon多重提問遺漏。

分類完後,扣掉 06(外部汙染)和 09(格式解析 bug),真正值得投資微調的落在三類: 規格遵循精確度(03/14/16/11)、符號幻覺(12)、複合提問完整性(13)。

09 的格式 bug 在哪

09 要同時改兩個檔,gemma 的輸出長這樣:在 whole-file 格式的檔名行前面多了個 - 項目符號(Markdown 條列)。 aider 的 parser 做字串匹配時直接把整行(含破折號)當成檔名, 結果磁碟上多了一個叫 - models.py 的新檔,真正的 models.py 原封不動。

這不是模型「不懂多檔」,是輸出格式比預期多了一個前綴字元,然後 parser 沒有 strip。 根源:aider 內建的 whole-file 範例只示範單檔,沒有示範多檔情境下裸檔名的樣子。 2.3B 模型拿著單檔示範去類推多檔,混入了 Markdown 條列的慣性。

Monkeypatch 實驗:修好了 09,全套退步

為了修 09,寫了 evals/aider_wholefile_wrapper.py: monkeypatch WholeFilePrompts.example_messages, 在 aider 內建的單檔示範後面多加一組兩檔案的範例 (B 檔 from models import User 引用 A 檔名字), 讓 gemma 看到多檔情境下裸檔名應該長什麼樣。

單題結果很好:09 從 3/3 全掛修到 3/3 穩定過關,而且一發就過、不需要 test-feedback loop。

然後跑全套 16 題 × 3 rep 守門。結果:

all-pass 7/16 → 5/16pass@3 9/16 → 7/16——淨退步。 09 確實修好(0→3/3),但 01 和 02 這兩道自評測集建立以來從未失手的題目,全套崩掉(3/3 全 FAIL)。 另外 15 題從穩定過變不穩(1.0→0.333)。

新失敗模式:pager.py(01 題的目標檔)裡出現 from pager import get_page, page_count—— 把「B 檔 import A 檔名字」的示範模式套進了定義那個名字的檔案本身,造成 circular import。 slugify.py(11 題)也是同款自我 import。 這個副作用不限於多檔任務,擴散到完全無關的單檔題。

2.3B 的 prompt 餘裕是這樣消失的

這不是第一次看到這個現象。2026-07-03 的 system_prompt_prefix 實驗(在 system prompt 開頭加 CRITICAL 檔名規則): 單題救回了 06 的檔名問題,全套卻從 6/8 掉到 3/8。 今天的 wrapper 是同一課——不是前綴,是在 few-shot 示範中段多加一組範例,同樣造成全套干擾。

2.3B 的注意力分配沒有 7B 的餘裕。往格式示範區塞任何內容,就算邏輯上是「多一個正確示範」, 對模型來說都可能是「我現在要學一條新的組裝規則」。 那條新規則一旦被過度概化——比如「B 檔要 import A 檔」——就會滲入不相關的題目。

處置:run_eval.py 還原成直接呼叫 aider; aider_wholefile_wrapper.py 保留在 repo 但加 REJECTED banner,比照 v5e converter 的做法。 09 的真正修法得從訓練資料下手,不能是「往 prompt 塞更多東西」。

值得投資的三類,不值得的兩類

這次診斷比之前的粗略分類更精確,讓後續投資決策更有根據:

值得投資 contrastive minimal-pair 訓練資料: 規格遵循精確度(03/14/16/11——大小寫、比對錨定、多單位累加、字元迴圈邏輯)、 符號幻覺(12——把 Python 內建名當自訂名 import,治法同工具清單 grounding)、 複合提問完整性(13——多重問題遺漏,prompt 層加計數提示先試)。

不值得現在投資:09(格式解析 bug,prompt 修不了、只能訓練資料,但成本高)、 06(aider 內建範例的既有汙染,大概率訓練也難脫身)。

單題驗證通過 ≠ 全套安全:09 的 wrapper 單題 3/3,全套淨退步 2 題——這已是第二次同樣的課(第一次是 07-03 的 system_prompt_prefix)。任何 prompt 層變更必須跑全套守門才能算數。

2.3B 的 prompt 餘裕極小,任何新增內容都有外溢風險:不是前綴才有風險,中段的 few-shot 示範同樣會波及完全無關的任務。往 aider prompt 塞東西的路已經走到盡頭。

病因分類比分數分類更有投資價值:7 道必掛題裡,2 道是外部框架問題(06、09),投資訓練資料的 ROI 低;剩下 5 道才是真正的能力落差。不分類就直接訓練,等於亂撒資源。

負結果要誠實入庫並加 banner:wrapper 沒達標就是沒達標;保留檔案 + REJECTED banner 比藏起來有用——下次遇到類似修法衝動時能直接找到前車之鑑。

符號幻覺和工具幻覺是同款病:12 題的「幻覺 import 內建名」與 v5c 前的「幻覺不存在工具名」,根因都是「模型覺得這個任務語意應該對應到這個名字」,沒有 ground 在「清單裡真的有什麼」。Contrastive minimal pairs 在工具上有效,應該也能用於程式碼符號。

來源:個人開發日誌 2026-07-09 · gemma4-e2b-agent-kit MD 微調評估 · eval 16 題 / gemma v3 fused 7/16 一致失敗 / wrapper 實驗 REJECTED / 7 題病因已分類