你讓 Gemma 4 修程式,等了很久,SWE-bench 的結果卻是一排 LimitExceeded。這篇 Gemma 4 SWE-bench 除錯教學先問一件事:是模型找不到解法,還是工具往返、訊息封裝或執行上限,讓它連交卷都走不到?
專為第一次讀 Agent 日誌的讀者寫。先用白話理解每一站,再照六步留下版本、四題清單與 Trace(一次任務的往返紀錄)。動手部分需要你已有能服務 Gemma 4 的 llama-server、SWE-bench/mini-SWE-agent 環境與可用的隔離容器;還沒備妥的人,可以先拿既有失敗紀錄完成判讀。
截至 2026 年 10 月 12 日,原始求助提供啟動設定與四個 Astropy 題號,聲稱多個範本都碰到同樣錯誤。這是單一使用者的回報;本文依官方程式碼建立排查方法,尚未取得該跑次的完整 Trace,也沒有執行 Gemma 4 端到端評測,因此不給修正成功率或模型排名。
先說結論:Gemma 4 SWE-bench 除錯先找哪一站停了
未交卷=停止出口;根因=停止前第一個異常。把 Agent 想成修車師傅,模型負責想做法,Harness(執行層)負責派工具、記錄結果及喊停。工時到期只說明師傅被叫停,不能單憑這句話判斷零件、工具或師傅哪個出了問題。
- 先看完整錯誤字串、版本與最後幾輪,再分步數、費用、時間及單次輸出。
- 先用一題找第一個異常,再把原貼四題當小型回歸組;四題結果不外推成完整榜單。
- 先證明歷史真的送回、動作真的解析及執行,再測一個有依據的修正。
原理:一個工具往返,其實有五張收據
使用者交出 issue,模型回傳想法與動作,適配器把回應轉成 Harness 看得懂的指令,工具執行後交回結果,下一輪把必要歷史再送給模型。Chat Template 是把對話裝成模型讀得懂格式的「信封」;parser 是從回應找出動作的「收件員」。信封對了,不代表收件員有拿到工具指令。

這五張收據分別是:送出的 request、原始 response、解析出的 action、工具 observation、下一輪 request。推理文字 reasoning_content、一般回答 content、工具動作 tool_calls 是不同欄位。看聊天畫面,可能只看見其中一張。先補概念可讀 Agent Harness 是什麼。
①「鎖材料」:保留原始失敗設定與確切版本
怕換了設定卻找不回原點?先建一個只放收據的資料夾。保留原始 config、完整 server 啟動指令、GGUF 檔案 SHA-256、Template 原始檔與來源 commit、llama.cpp commit、mini-SWE-agent/LiteLLM 版本、硬體和有效採樣。GGUF 是本機模型常用的權重檔格式;同樣標 Q4,仍要看實際檔案。
mkdir -p gemma-debug/original
cp config.yaml chat_template.jinja gemma-debug/original/
./llama-server --version > gemma-debug/original/server-version.txt
./llama-server --help > gemma-debug/original/server-help.txt
python -m pip show swebench mini-swe-agent litellm > gemma-debug/original/packages.txt
shasum -a 256 chat_template.jinja model.gguf > gemma-debug/original/hashes.txt
上面的 model.gguf 換成你實際使用的檔案路徑;大型檔案算雜湊需要讀完整檔案。啟動指令另外存成文字,別把 API 金鑰寫進可分享的收據。若是 Git checkout,再在各專案目錄執行 git rev-parse HEAD;套件安裝則保留版本及來源。
SWE-bench CLI 文件說明 swebench infer 會呼叫 mini-SWE-agent,生成預測及 trajectory;真正控制 Agent 的不是題集名稱。先執行 swebench infer --help,確認本機有這條子命令。原貼沒有提供完整版本,因此不能把本文查核的最新版當成原貼實際使用版。
②「先看出口」:LimitExceeded 與 LimitsExceeded 別直接畫等號
原貼寫的是單數 LimitExceeded。本文查核的 mini-SWE-agent v1 與目前主線則使用複數 LimitsExceeded;目前 DefaultAgent 程式在查詢前檢查模型呼叫數或累計費用,任一達有效上限就走這個出口。主線另把總牆鐘時間上限寫成 TimeExceeded。先核對你安裝版本的例外類別,別把所有限制都塞進同一個名字。
牆鐘時間是從開始到結束真正經過的時間,包含等待;單次工具 timeout 是某一個命令最多等多久;單次輸出上限則限制一個回答生成多少 token。像修車總工時、每次檢查的等待時間與每張工單的篇幅,是三個不同旋鈕。輸出被截短可能讓後面反覆重試,但仍需逐輪證據才能連到最終停止。
先讀 Trace 的 info.exit_status、info.config.agent 與 info.model_stats。下面程式只做唯讀摘要,適用這兩條已查核分支的常見保存結構;欄位缺失顯示 null,不猜數字。保存結構可對照 serialize 的實作。
import json, sys
from pathlib import Path
j = json.loads(Path(sys.argv[1]).read_text())
info = j.get("info", {})
summary = {
"exit_status": info.get("exit_status"),
"agent": info.get("config", {}).get("agent"),
"model_stats": info.get("model_stats"),
"messages": len(j.get("messages", [])),
}
print(json.dumps(summary, ensure_ascii=False, indent=2))
for m in j.get("messages", [])[-6:]:
print(json.dumps(m, ensure_ascii=False))
存成 trace_summary.py,執行 python trace_summary.py 路徑/題號.traj.json。原始回應可能很長,輸出先存本機檔案;分享前移除金鑰、私人路徑與專案內容。若呼叫數等於步數上限,先記「符合步數停止條件」;若費用也同時到線,就把兩者都列出,不任選一個根因。
③「縮考卷」:先一題,再用原貼四題驗收
怕一次跑太多,卻只有四個錯誤名字?先固定一題與一個 worker。原貼指定的是 astropy__astropy-12907、astropy__astropy-13033、astropy__astropy-13977、astropy__astropy-13579。這是排錯切片,題目是否成功載入要看本機篩選日誌,不能只看指令寫了四個名字。
先把原 config 複製為 config.safe.yaml,把 environment.environment_class 改成 docker,核對題目容器可用、工作目錄是 /testbed,再開始。官方 SWE-bench 設定以 Docker 隔離任務;原貼的 local 是直接在本機執行動作的路線,單有題號不會替你準備正確 repo。這份隔離基準與原始 local 設定分開命名,避免把環境改動算成範本效果。
config 裡的模型名稱與 -m 都需對上你服務的實際 model ID。若 server 在主機、Agent 在容器,確認模型請求由哪個程序送出;容器裡的 localhost 與主機不是同一個網路位置。以下 gemma-4-31b 是範例名稱,先依你的端點改妥。
swebench infer verified -c config.safe.yaml -r gemma-baseline-01 \
-m gemma-4-31b -w 1 --filter "^astropy__astropy-12907$" --dry-run
先讀 dry-run 展開的命令,確認 interpreter、設定合併順序、輸出目錄與題集。移除 --dry-run 才真的執行。若你的版本沒有這個選項,先依同版本 CLI 文件核對呼叫鏈,不為了套本文指令而同時升級整套軟體。每次實際跑次用新 run ID,保存 stdout、stderr 和 Trace,避免沿用已有結果。
swebench infer verified -c config.safe.yaml -r gemma-four-01 \
-m gemma-4-31b -w 1 \
--filter "^astropy__astropy-(12907|13033|13977|13579)$"
只有在第一題收據齊全、容器與預算已核對後,再執行四題。篩選日誌要顯示四個實際 instance IDs;若數量不同,先修題集版本或 regex。依目前 CLI,預設收據在 logs/inference/<run_id>;若你另給 -o,以實際展開目錄為準。
④「查信件」:Gemma 4 SWE-bench 除錯要追到下一輪 request
怕「有開 reasoning preserve」仍一直忘記前文?沿五張收據逐站對帳。先查 response 是否有推理欄位,再查適配器保留什麼,最後查下一輪 request 與 server 實際渲染的 prompt。Trace 保存了原始 response,不等於這些欄位都已送回。
一個可直接核對的版本例子是 mini-SWE-agent v1 的 LitellmModel:送出前只重建每則訊息的 role 與 content。推理若在別的欄位,這條路徑就不會把該欄位帶進下一輪;是否影響你的題目,要看你實際的回應與 adapter。目前主線適配器則保存模型訊息、排除內部 extra 後準備 API 歷史,不能把 v1 行為套到所有版本。
llama.cpp server 文件區分 --reasoning-format 如何呈現推理,以及 --reasoning-preserve 對相容範本的歷史保留。它們應與 client 實際送出的欄位一起驗。若需檢查模型真正讀到什麼,先確認鎖定版本支援 --log-prompts-dir,再在只含公開題目的隔離跑次開啟;prompt 檔案可能包含完整歷史。
Gemma 的 本次固定 revision 範本還有依最後 user turn、preserve_thinking 及 tool_calls 決定推理是否渲染的 gate。#137 的社群修改提案針對這段條件提出變更;它的存在只證明有人提出可檢查的候選差異,不是原貼 LimitExceeded 根因的確認,也不是已證實可解四題的修正。
⑤「查動作」:先分 Bash 文字協議與原生 Tool Call
怕工具名字看起來正確,Harness 卻一直退件?先找有效 parser 與 system prompt。查核的 v1 預設 Agent 從一般回答解析一個 Bash code block,工具觀察再以 user 訊息加入;目前主線的預設 LiteLLM 路徑解析原生 tool_calls。兩者都是工具工作流,格式契約不同。
以 v1 parse_action為例,它依 regex 找 Bash 區塊;零個或多個就進格式錯誤處理。若模型只回原生 tool call,而這個 parser 等的是文字區塊,先修協議配對。相反地,原生工具路線要核對工具 schema、arguments、call ID、工具結果及下一輪對應關係。別同時換模型、parser 和範本,讓改善失去歸因。
想像一個教學示意:第一輪模型叫工具讀檔,工具回「路徑不存在」;第二輪仍讀同一路徑。先看第二輪 request 是否包含那個錯誤。若有,重複行動可能是策略問題;若缺了,先修歷史;若動作根本沒執行,先修解析。這不是本文實際觀察到的 Gemma 跑次,而是一套能把假說拆開的判讀方法。
⑥「只改一項」:把候選修正與完成驗收分開
怕加大上限,看起來變好卻不知道為什麼?每個候選只改一個相關變因。例如確認費用門檻先到,就只調該門檻;確認歷史欄位在 client 被丟掉,就只改適配器;確認是格式退件,就只改協議配對。每一項都保存修改前後 request、Trace 與新 run ID。
本次查核的 官方 bundled config寫 step_limit: 250、cost_limit: 3.,原貼留言則談 200 步。有效配置才是你這一輪的上限,不把任一數字說成全部版本的標準。原貼的 cost_tracking: ignore_errors 用於處理成本計算錯誤;在已查核 LiteLLM 程式裡,算不出費用時可記零,並不等於關閉步數門檻。
比較每題時留下六欄:終止狀態、呼叫數、重複動作、累計輸入/輸出 token、牆鐘時間、patch 與 grader 結果。token 數優先用各輪 response 的 usage;缺失就標未知,別把字數冒充 token。工具執行數與模型呼叫數可能不同,也分欄保存。
「交卷」與「修好」分兩關:Submitted 或有 patch,表示走到提交;resolved 要經 SWE-bench 評估測試。先算交卷題數/實際執行題數,再算通過題數/實際執行題數,並保留提交題內的通過比例。四題各自列出,不拿一題變好就宣稱整個模型變強。想擴展正式評測,可接著讀 Coding Agent 同題驗收。
常見坑:從第一個異常回推,不追最後一行
- 直接調高步數:先看最後十輪是否有新檔案、新測試或新判斷;同一失敗反覆出現,增加預算只是延長同一行為。
- 一直換網路範本:保留原版與候選 commit,核對模型讀到的格式;來源名稱與熱門度不能取代 diff。
- 一次改 context、量化與 KV:三個旋鈕分開測。大 context 是容量,不是工具解析、歷史或解題品質的保證。
- 跑次覆蓋或共用環境:新 run ID、乾淨容器與完整失敗紀錄一起留。原始 local 設定可保存供診斷,實際命令放在隔離任務裡執行。
FAQ:Gemma 4 SWE-bench 除錯的八個直接答案
1. 全部 LimitExceeded,就證明 Gemma 4 不會寫程式嗎?
證據不足。先確認完整字串、有效限制與停止前的行為;這個回報尚不足以把錯誤歸到模型能力。
2. 先把 200 步加到 500 步嗎?
先查 Trace。若沒有新的進展,加大步數只能測「多給預算是否改變結果」,不能替格式或歷史問題提供解法。
3. 換成 #137 範本就能修好嗎?
尚未證實。它是有明確 diff 的候選;先確認你的訊息路徑會碰到該 gate,再做單變因比較。
4. –reasoning-preserve 開啟就夠嗎?
仍需對帳 client 與 Template。推理欄位若在送出前被丟掉,server 旗標無法替那次 request 補回原欄位。
5. cost_tracking: ignore_errors 代表沒有上限嗎?
不是。已查核版本把成本計算錯誤處理與步數、費用停止條件分開;讀保存的有效配置。
6. 四題都交卷,就能公開 SWE-bench 分數嗎?
先標清四題切片,並經 grader 驗收。交卷比例與 resolved 比例是不同數字,不能外推到完整題集。
7. 工具結果必須是 tool role 嗎?
依協議。查核的 v1 文字路線以 user 訊息放觀察;原生工具路線則有 call ID 與工具結果契約。先讀同版本 adapter。
8. 沒有大顯卡,今天能做什麼?
可以先讀已有 Trace、鎖版本、列四題與停止條件。這些是唯讀整理;模型跑次留到硬體與隔離環境備妥。
給新手的三個重點
先認出口,再看第一個異常;先一題,再四題;先改一項,再看交卷與測試。可比較的收據,比一張沒有版本與失敗過程的分數更有用。若你還在排除本機與雲端差異,本機 LLM 可比性五關能補足模型、採樣與 runtime 的對齊;本篇則把焦點收在未交卷的那條往返鏈。
接著閱讀
左右滑動查看更多推薦
下一步:把一個錯誤名字,變成一份排查收據
今天先打開一題的 Trace,寫下完整終止狀態、有效上限、最後一個成功動作,以及第一個異常出現在哪張收據。若仍查不到,就寫「未知:缺哪份 request 或 response」,接著補證據。未交卷=停止出口;根因=停止前第一個異常。等這一題說得清楚,再跑同樣四題,讓每個候選修正都留下能被核對的理由。
想繼續把本機模型接成完整工作流,可從 AlphaLab AI 教學專區挑下一個練習,或到 AlphaLab 課程循序建立開發與驗收能力。






