光靠 LLM 評測哪裡不好?如何在現階段就把沙盒的未來契約預留好
為什麼光靠 LLM 評測會讓人心虛?因為在真實程式執行的世界裡,有太多的邊界狀況是「用眼睛看」看不出來的:
| 評測情境 | LLM 推測(現行方案) | 沙盒環境(未來規劃) |
|---|---|---|
| 執行機制 | 用眼睛看:靠 Prompt 讓 Gemini 腦補推演 | 真正跑一遍:丟進獨立容器實跑 python run.py |
| 無窮迴圈 | 只能靠眼睛猜「這好像會無窮迴圈」 | 實跑 Timeout:超時直接強制終止並抓包 |
| 記憶體爆掉 | 完全看不出來 | 記憶體溢位 (OOM):容器實測爆記憶體 |
| 語法/邏輯細節 | 有微小機率產生 AI 幻覺(看走眼) | 100% 精準:吐出真正的 Python Traceback 報錯 |
為了不讓未來的沙盒升級變成一場「砍掉重練」的災難,我在 LangGraph 架構中將評測節點(grade node)採用了 Closure 工廠與依賴注入模式:
Python
# 第 2 期現行:注入 Gemini API(用眼睛看)
make_grade_node(client)
# 未來升級規劃:注入沙盒 Runner(真正跑一遍)
make_grade_node(runner)
這樣設計的好處是:
這是消除違和感、接軌未來沙盒最重要的一步!LLM 很聰明,光用眼睛看就能理解鬆散的自然語言測試;但未來沙盒拿去「真正跑一遍」時,只認得真正的 Python 程式碼。
如果第 3 期「出題 Agent 」產出的測試題目長這樣:
tests: ["輸入 5 要拿到 10", "空字典要回傳 Not Found"]
未來一旦接上沙盒,沙盒執行這段中文會直接爆掉,我就必須把 Prompt、評測 Node、資料庫全部重寫!
因此,我從現在開始就將 tests 欄位釘死為「可獨立執行的 Python assert 程式碼契約」:
Python
# 題目與測試的形狀 (problem schema)
{
"title": "字典鍵值搜尋",
"description": "請撰寫一個函式 `find_value(data, key)`...",
"entry_point": "find_value",
"tests": [
"assert find_value({'a': 1}, 'a') == 1",
"assert find_value({}, 'x') == 'Not Found'",
"assert find_value({'a': None}, 'a') is None",
]
}