整個跑完了訊息沒送出去才是最惡心的
看到 Reddit 上那篇 gpt-5.5 via Codex runtime 的 bug report,有幾個細節一直在腦袋轉
情境是這樣的:用 gpt-5.5 跑 OpenClaw,短的 conversational turns 會觸發一個奇怪的狀況,agent 好像在思考,打字指示跑了一下,然後什麼都沒有
但沒有 error
trajectory log 比對起來很神奇。正常的跑法是 session.started → context.compiled → prompt.submitted → tool.call(message, action=send) → tool.result → model.completed → session.ended
壞掉的時候是 session.started → context.compiled → prompt.submitted → model.completed → session.ended
就少了中間那段 tool.call。然後重點是,模型其實有產生 coherent 的文字回覆,它只是沒有去呼叫 message tool
觸發條件是 6-16 chars 的短訊息,像 hello?、u back?、summarize X 這種。session 已經跑到 138k tokens
切到 deepseek/deepseek-v4-pro 立刻好。但從 Telegram /model 切換沒用,因為 codex-app-server.json 的 thread binding 還把那個 session 鎖在 gpt-5.5,得 SSH 進 server 手動 restart thread 才真正換掉
好,這不是我今天要講的重點
重點是「整套流程看起來成功,其實最後一棒沒送出去」這件事
agent 類的 bug,最容易處理的其實是有明確 error 的那種。traceback 出來,exit code 不是 0,你知道去哪裡找,麻煩但有方向
可怕的是這種:整條 pipeline 跑完,log 全部 green,沒有任何 exception,session 也 ended 了,然後你盯著那個對話框,什麼都沒有
然後你開始懷疑:是我沒按到嗎?網路斷了嗎?是我 config 哪裡漏掉了嗎?
這種東西搞死人,因為「成功」這個訊號是假的
agent workflow 的問題是,它通常是一長串的 chain。你有 context 編譯、有 prompt submission、有 model completion、有 tool call、有 tool result、再回到 model。每一段都可以「看起來 ok」,然後最後一棒沒動,結果什麼都沒出去
最後一棒就是那個 tool.call(message, action=send)。它沒跑,前面全部都是白費
我的判斷是:debug agent bug 的順序應該倒過來。不要從頭往後找,先確認最後要對外送出去的 action 有沒有真正觸發。在這個 case 裡,就是看 log 裡有沒有出現 tool.call,沒有的話,前面跑得再順都沒用
你可以把「expected final action」當成一種 assertion 去監控,不是「有沒有出錯」,而是「有沒有完成最終動作」,概念上有點像 e2e test,只是放在 agent trace 上面。這東西大部分 framework 預設不給你,得自己加
那篇 Reddit post 最有意思的地方是換模型立刻好這件事。問題不是 runtime,是 gpt-5.5 在 context 跑到 138k、遇到短訊息的時候,它「決定」不呼叫 tool,直接 complete 了
這不是 code bug,是模型在那個 context 下的決策出了問題。你很難從系統層去修,能做的大概就是換模型、縮 context、或在 system prompt 裡加強制呼叫的指示
但這也說明了一件事:會 throw error 的 bug,代表系統偵測到異常了。不 throw error 的,代表系統覺得一切正常,只有你知道結果是錯的
後者才是真正難找的那種,因為它不會主動告訴你它壞了
現在如果有人跟我說「agent 好像跑了但沒有回覆,也沒有 error」,我的第一個動作都是去看 trajectory 的最後面,確認那個對外的 tool call 有沒有出現
沒有的話,前面那些 session.started、context.compiled 全部都是幌子
作者:島民No.9527