「幫我退掉 order 123。」Agent 查了訂單、查了規則,也呼叫了退款工具。第一次逾時(Timeout)後,它再試一次,最後宣布完成;系統裡卻留下兩筆退款。它每輪都有下一步,任務反而越走越錯。這篇要用三個問題分辨「有動作」與 Progress,讓執行控制器知道何時繼續、改路、停止、等待或交接。
- 工具呼叫、Turn 與最終回答為什麼只代表系統有活動
- 如何用新證據、外部狀態與完成條件判斷 Progress
- 為什麼 Planning、Replanning 與停止其實是同一個判斷的不同結果
先看 order 123 的執行紀錄:
1. get_order → 訂單已付款
2. get_refund_policy → 符合退款資格
3. issue_refund → 逾時,結果未知
4. issue_refund → 成功
5. 最終回答 →「退款完成」
外部結果:refund_records = 2
這個 Agent 看起來很勤奮。它有五個 Turn、四次工具呼叫,還給了完整答案。若監控面板只顯示請求數、執行時間與是否正常結束,這次執行甚至可能是一片綠色。
但使用者要的不是「Agent 做了很多事」,而是 order 123 恰好存在一筆正確退款。前面的查詢、呼叫與回答都只能證明系統有活動。只有最後的真實退款狀態,才能回答任務是否前進與完成。
OpenAI 拆解 Codex Agent Loop 的工程文章說明:模型產生工具呼叫,Harness 執行後把結果送回下一輪;模型不再呼叫工具、改為輸出訊息時,該 Turn 就結束。這套機制能判斷「要不要再跑一輪」,卻不會自動證明外部任務成功。文章也指出,Software Agent 的主要輸出可能是寫入電腦的檔案,而不是最後一句文字。
退款任務也是如此。最終回答只是 Agent 把控制權交還給使用者;真正的答案在退款帳本。
工具呼叫表示 Agent 做了動作,Turn 表示執行層還在運作,最終回答表示這輪對話停了;它們都不等於 Progress。
這對設計自己的 Agent 有什麼用?先不要用 Turn 數、工具呼叫數或「有沒有最終回答」當成功指標。它們適合觀察成本與執行狀態,不適合證明任務結果。每個重要任務都要另外指出:完成時,Agent 外面的世界應該長什麼樣子?

要讓執行控制器判斷是否值得繼續,不必先發明一套複雜分數。對每個動作問三個問題就夠了:
新證據是執行前不知道、而且會影響下一步的事實。第一次查到「訂單已付款」是新證據;第一次查到「符合退款資格」也是。但用相同參數重查,若得到完全相同結果,就只增加活動。
對 order 123 而言,退款呼叫發生逾時後,真正缺少的證據是:支付服務到底有沒有建立退款?再呼叫一次退款,不會回答這個問題。查詢退款帳本才會。
有些動作的價值就是改變世界,例如建立退款;另一些動作是把未知狀態變成已知,例如查詢退款帳本。兩者都要記錄執行前後的差異。
如果 Agent 連續搜尋、點擊或重試,外部狀態與已知事實都沒有改變,它就是忙碌,不是前進。OpenHands 的 StuckDetector 原始碼會檢查重複的「動作—觀察結果」、相同的「動作—錯誤」、Agent 自說自話與 A-B-A-B 往返模式。這類偵測很適合抓出明顯迴圈,但合法的輪詢也可能重複,所以不能只靠字串相同就宣判失敗。
「更接近」不是模型覺得有希望,而是未完成的條件變少了。退款任務可以先寫成兩個可檢查條件:
order 123 的退款筆數恰好為 1。查到退款帳本中的退款 ID 與金額後,兩個條件才從未知變成可驗證。若只得到另一段解釋文字,即使文字更長、更有自信,距離完成也沒有縮短。
Anthropic 的 Agent 工程指南同樣強調,Agent 執行時要持續從外部環境取得真實狀態,才能評估進展;遇到阻礙或需要判斷時,則應停下來向人取得回饋。這裡的重點不是選哪個框架,而是把「事實由誰提供」說清楚:模型提議下一步,工具接觸外部環境,執行控制器比較前後差異,完成條件決定能不能停。
這三問就是本文的 Progress Contract:
有沒有新證據?外部狀態有沒有改變?是否更接近完成條件?
不是每一步都要讓三題同時得到「有」。讀取型工具可能只增加證據,不改變外部世界;寫入型工具可能先改變狀態,之後才由另一個查詢確認。重點是執行控制器在執行前知道這一步要推動哪一題,執行後也能檢查承諾是否發生。若三題都沒有預期變化,就沒有足夠理由自動執行。
它不是業界共同制定的結構格式,而是本文建議的執行層檢查方式。對自己的 Agent,先替一個關鍵動作寫出這三題的預期答案;若答不出來,這個動作很可能只是「做點什麼」,而不是一個可驗證的下一步。

回到第三個 Turn。issue_refund 回傳逾時,最危險的做法是把它直接翻譯成「退款失敗」。逾時只表示呼叫端沒有及時收到結果;它沒有告訴我們服務端是否已完成副作用。
此時套用三個問題:
因此執行控制器不該讓原計畫自動滑到「再退款一次」。它應把下一步改成 reconcile_refund(order 123),從退款帳本取得退款 ID、筆數與金額。
issue_refund → 逾時
↓
結果是 unknown,不是 failed
↓
reconcile_refund → 找到既有 refund_id 與正確金額
↓
verify → 退款筆數 = 1,金額正確
這才是 Replanning:不是要求模型再想一次,而是新的觀察結果推翻了原本的假設,所以換一條能取得缺失證據的路。已確認的事實仍然保留,例如訂單已付款、符合退款資格;只有「逾時等於沒有執行」這個錯誤假設被撤回。
若 reconcile_refund 查不到任何紀錄,執行控制器也不該立刻重試。它還要考慮支付服務的一致性延遲、工具的正常重試規則與副作用風險。第一次等待或重查可能合理;連續得到相同結果,卻仍沒有新證據與狀態變化,就應換策略、等待或交接。
研究中的 ADaPT提供了相近的方向:不是一開始全面分解,而是在執行器無法完成當前子任務時才遞迴增加規劃深度。它是在特定基準測試上的結果,不能直接保證退款 Agent 也會提升;但設計原則很實用——把額外 Planning 成本投在已證明困難的節點。
這對設計自己的 Agent 有什麼用?為工具結果保留 success、failed、unknown 等不同語意;再替 unknown 設計「如何取得真實狀態」的路徑。沒有這條路時,正確結果是等待或交接,不是讓模型猜一個最像完成的答案。

看到 Agent 迷路,我們很容易分別加入規劃器、反思、停止條件與預算控制器,最後得到更多元件,卻沒有共同的判斷中心。Progress Contract 的價值,就是把它們收斂成執行控制器每一輪都會做的同一件事。
對 order 123,執行控制器問完三個問題後,只需要在幾種控制選項中選一個:
Planning 在這裡不是一份不能更改的長劇本,而是「下一段怎麼取得進展」的暫時假設。ReAct 論文把推理與動作交錯,讓新的觀察結果能更新行動計畫。對工具結果未知、環境會變的任務,這種短承諾通常比預先鎖死全部步驟更能吸收現實變化。
只有當基準執行軌跡已經出現遺漏步驟、依賴關係混亂、跨資源協調或長程目標漂移,較完整的 Planning 才有明確價值。若任務只有一到三個可逆步驟,下一步主要取決於最新觀察結果,先做完整計畫反而增加 Token、延遲與過期假設。
預算也只是同一個判斷的限制條件。max_turns 可以避免無限執行,卻不能證明任務成功。OpenAI Agents SDK在模型產生最終回答且沒有工具呼叫時結束;超過 max_turns 則拋出例外。Google ADK 的 Loop 文件也明說 Loop 本身不會決定何時停止,範例同時使用完成訊號與最大迭代數。前者回答「為何完成」,後者只是成本保險絲。
所以執行控制器不能等到預算歸零才硬停。它要在每輪一起看:目前取得多少進展、下一個動作預期帶來什麼、剩餘 Turn/時間/成本是否值得。若不值得,就保存已確認的證據,轉為等待或交接。
反思也不需要固定每輪執行。只有失敗帶來新的工具錯誤、測試結果或外部回饋時,反思才有材料可以改變下一步;沒有新證據的自我批評,很可能只是更昂貴的原地踏步。
這對設計自己的 Agent 有什麼用?不要先問「要不要加規劃器」,而要拿一條失敗執行軌跡來問:當時缺的是新證據、外部狀態,還是明確完成條件?只有當答案顯示現有路徑不足,才加 Planning 或反思;否則先修工具、觀察結果或驗證方式。

現在固定同一個目標、模型、工具與初始狀態,對照兩條路徑。這是設計示意,不是已實跑的基準測試。
查訂單 → 查規則 → 退款
↓
逾時
↓
再退款
↓
最終回答
外部結果:兩筆退款
查訂單 → 新證據:已付款
查規則 → 新證據:符合資格
退款 → 逾時;外部狀態未知
對帳 → 新證據:已有 refund_id;狀態已確認
驗證 → 退款筆數 = 1、金額正確
停止 → success_verified
兩條路徑沒有更換模型。改變的是執行控制器不再把「模型還能產生下一步」當成繼續理由,也不再把最終回答當成成功證據。
這個差異也說明,什麼時候不該加入複雜 Planning。假如工具無法區分逾時與確定失敗、系統沒有查詢退款帳本的能力,或完成條件只寫成「模型說退款完成」,再好的計畫都碰不到真實問題。AgentOccam在 Web Agent 研究中,透過調整觀察結果與動作空間來貼近模型能力,在不新增 Agent 角色、線上回饋或搜尋策略的情況下改善表現。這不是退款案例的直接驗證,但支持一個很實際的優先順序:先改善 Agent 看見什麼、能做什麼、如何驗證,再增加規劃複雜度。
完成也要回到外部狀態。τ-bench評估客服 Agent 時,會檢查對話結束後的資料庫狀態是否符合目標,而不是只讀 Agent 的最後一句話。對自己的系統,最有價值的第一個改造通常不是一個更大的規劃器,而是一條能查驗最終狀態的完成條件。
Planning 是下一段進展的假設,Replanning 是證據推翻假設後換路,停止是完成條件已通過或繼續已不合理。三者共享同一份 Progress 判斷。
你不需要一次改造整套 Agent。找一條最近失敗或成本異常的執行軌跡,沿著每個工具呼叫寫下三句話:
如果三題都答不出來,就把它標成「無進展」候選。接著觀察下一輪:執行控制器是重複相同動作、換了一條能取得證據的路、等待正確時機,還是把問題交給有權限的人?這一條執行軌跡就能成為第一個回歸案例。
對 order 123,回歸案例不只是檢查「最後有回答」,而是固定同一個初始狀態與錯誤注入,驗證執行控制器是否做到:逾時保留為結果未知、下一步改查退款帳本、沒有重複退款、完成前檢查筆數與金額。未來換模型、Prompt 或工具版本,都重跑同一組條件。
這對設計自己的 Agent 有什麼用?它把抽象的「Agent 好像會卡住」變成可以比較的控制行為:哪一步沒有新證據、哪個狀態沒改變、哪個完成條件沒靠近,以及執行控制器最後選擇了什麼。你不需要相信展示看起來順利,可以直接檢查失敗是否真的被修掉。

打開你最近一條 Agent 執行軌跡,它最像哪一種?
留下一個字母,再加一句你的情境。接著先問那三個 Progress 問題,不必急著加更複雜的 Planning。