當 AI Agent 在部署前都運作良好,直上線一切就崩潰了
在 Reddit 看到很實用的實戰文章,翻譯給大家:
過去兩年我在七個不同的系統上部署過 AI Agents,最大的體悟是——最難的部分其實不是 AI 本身,而是讓長時間執行的非同步流程不變成一場災難的基礎架構。
我們都經歷過:本地端測試一切正常,結果一上線,有位使用者啟動了一個要跑 45 秒的流程,中途連線斷掉。然後呢?流程變成孤兒程序、狀態全丟、使用者覺得你的 App 壞了。這就是所謂的「非同步問題」:你不能只是簡單地 await 一串 API 呼叫就祈禱它順利完成。現實世界裡,API 會逾時、會被限流、網路會斷。
大多數教學都展示同步程式:使用者發訊息、Agent 思考、回覆,三秒搞定。
但真實上線環境?Agent 啟動一個 45 秒的流程,要呼叫三個外部 API、等 Sonnet-4 生成內容、再處理結果、再打兩個 API。使用者在第 12 秒連線中斷。那怎麼辦?
大家都會撞上的「工作佇列(Job Queue)」問題
在生產環境裡真正發生的情況是這樣的:
Agent 決定要呼叫五個工具。你為了速度全部 async 發出去。
Tool 1 兩秒完成,Tool 3 30 秒逾時,Tool 5 被限流失敗,Tool 2 和 Tool 4 雖然成功但回傳的資料互相衝突。
如果你這一切都在同一個 request 裡執行,那恭喜,使用者只會看到錯誤訊息,完全不知道哪些步驟其實已經成功。
因為一個失敗,你就失去了前三個成功的狀態。
Job Queue 的解法是把請求和執行分離。
使用者送出任務後,你立即回傳一個 Job ID,後續的工作交給背景工作者處理。
若某步驟失敗,只需重試該部分,不用重跑整個流程。
我現在大多使用 Redis 搭配 Bull。每個 Agent 任務都是一個具唯一 ID 的 job。
背景 worker 會非同步處理它。若某個 worker 掛掉,任務會自動轉交給其他 worker。
使用者隨時可以查詢狀態。
狀態持久化是「必須的」
Agent 啟動一個多步驟流程,前三個 API 呼叫都成功,第四個因限流被拒。你設定 30 秒後重試。
但請問:前三步的結果你存哪裡?
如果狀態放在記憶體裡,當程序重啟就全沒了。
你不是得重跑(浪費錢又更容易限流),就是整個流程直接掛掉。
我現在的作法是每個步驟都寫進資料庫。
Agent 開始任務 → 寫入 DB;步驟完成 → 寫入 DB;步驟失敗 → 寫入 DB。
這樣我隨時知道發生了什麼、接下來該重試哪一步。
當出錯時,我能精準地重跑需要的部分。
Idempotency(冪等性)能救你一命
真實環境中使用者會重複點擊、會重新整理頁面、你的 retry 邏輯也可能觸發兩次。
若沒處理好,就可能執行相同操作多次。
經典錯誤:Agent 建立訂單 → 下單 → 刷卡 → 被限流 → 重試 → 使用者被扣兩次款。
在分散式系統裡這種事超常發生。
我會用 Queue 的 message ID 當「去重鍵(dedup key)」。
在執行任何具破壞性的操作前,先檢查該 message ID 是否已執行過。若是,就跳過。
這個模式(至少一次送達 + 最多一次執行)能防止災難。
大多框架對狀態管理沒太多意見——他們通常把 context 放在記憶體裡就結案。
但當你需要水平擴展、或程序半途崩潰,就全炸了。
我現在實際在跑的架構
每個 Agent 任務都丟進 Redis queue,附上唯一 job ID。
背景 worker(通常 3~5 個實例)輪詢 queue。
每個執行步驟都把狀態寫進 Postgres。
所有工具呼叫都用 job ID 做冪等性檢查。
失敗任務會指數退避(exponential backoff)重試最多 5 次,再進 Dead Letter Queue。
使用者會立即拿到 Job ID,可隨時查狀態。
若保持連線,透過 WebSocket 即時更新;斷線也沒關係,工作仍會繼續。
這套架構開發起來貴很多,但讓我不用在半夜 3 點被叫起來處理重複扣款或遺失的任務。
問題
有沒有人找到更好的方式處理長時間執行的 Agent 工作流,而不用從零開始重建半套 Temporal?
作者:MingTech