今天本來要修一個我以為存在的問題。
導師每輪會判斷學生顯露了哪些錯誤觀念,寫進 Firestore 黑板,
第 3 期的出題 agent 再拿黑板上次數最多的觀念去挑下一題。
整條閉環的準確度,全押在那個判斷上。
而我的認知是:那個判斷從第 1 期到今天,都是模型讀著程式碼猜的。
即使從 Day 21 開始,旁邊就擺著一份真的跑過的結果。
結論先講:這個前提是錯的,而我是花了八次 API 額度才知道的。
兩處,都在 agents/tutor.py:
EVIDENCE_RULE,只在真的執行過而且有失敗時放進 user prompt,第 2 條裡我還做了一個自認漂亮的決定:不給完整對照表。
最誘人的做法是九個代碼全部配上典型症狀(逾時→loop、只印一筆→io-eof⋯)。
但 CPE 一星題最常見的逾時長這樣:
while True:
n = int(input())
沒處理 EOF,輸入讀完了還在讀。症狀是逾時,觀念是 io-eof,
跟迴圈一點關係也沒有。照表操課會把這種最典型的錯誤系統性地記錯。
所以只列例外名稱直接指向觀念的那三條(EOFError→io-eof、IndentationError→indentation、int() 的 ValueError→io-parse),
其餘給原則:症狀不是觀念,指不出程式碼裡的成因就不要記。
測試 314 → 323 支,全綠。寫完我還挺滿意的。
單元測試全綠只證明「那些字串有進 prompt」,不證明它有用。
所以接了真模型,把同一個情境跑改動前/改動後兩次。
| 情境 | 改動前 | 改動後 |
|---|---|---|
崩潰 EOFError |
— | io-eof ✅ |
逾時(賭它不會誤記成 loop) |
io-eof ✅ |
io-eof ✅ |
程式碼表面像沒處理 EOF、實際崩在 int() |
io-parse ✅ |
io-parse ✅ |
同上,但把 explanation 拿掉只剩 traceback 原文 |
io-parse ✅ |
io-parse ✅ |
四個情境,改動前後一模一樣。
第二列是最打臉的:那正是我整條設計的賣點——「照表操課會把逾時記成 loop」。
結果沒有表的時候,模型自己就答對了 io-eof。
我防的是一個不存在的錯誤。
看第四列。我刻意拿掉 explanation,只留執行器吐出的原文:
ValueError: invalid literal for int() with base 10: '1 10'
模型照樣對到 io-parse。
所以真相是:Day 22 加的 explanation 早就讓導師在讀證據了,
而且就算沒有 explanation,traceback 原文本身對模型也夠清楚。
我以為缺的那條資料管線,兩天前就已經接好了,只是沒有人(包括我)
明講過它現在也是判斷觀念的依據。
我讀了程式碼、確認了資料有沒有到,卻沒確認行為有沒有變。
資料流的完整不等於行為的缺陷。
留下第 1 條(那行「依據是程式碼與評測結果」——它只是把實際已經在發生的事寫進合約,
幾乎不花 token),刪掉 EVIDENCE_RULE 與它的六支測試。
刪掉的理由不是它錯,是它沒有掙到自己的位置。
每一句進 prompt 的話都是成本:佔 token、多一個要維護的東西、
多一個以後有人改壞了也沒人發現的角落。沒量到好處的東西不該留著佔位子。
留著也有說法——「換模型時可能有用」「測試能擋住日後有人拿掉證據」。
但這兩個理由的共通點是:它們講的都是想像中的未來,不是量得到的現在。
真到了那天再加,成本是今天的十分之一。
今天的淨產出是:一行 prompt、三支測試、以及一個被證偽的假設。
第三個最貴,也最值得寫下來。
測試 314 → 317 支,全綠。