管理到失敗恢復的關鍵設計)
做長任務 Agent 的工程人應該都經歷過這種深夜瞬間凌晨三點日志里躺著一行timeout after 30000ms任務卡在 70% 的位置前幾個小時的 Token 全部白燒你還得爬起來手工清理狀態(tài)、回滾數(shù)據(jù)、重新觸發(fā)。那一刻你會產生一個很現(xiàn)實的疑問我們費這么大勁到底是讓 AI 幫我們省時間還是讓我們陪它熬夜過去兩年我做了不少 Agent 原型。單輪問答型的最開心兩三百行代碼模型一調用、答案出來、任務結束效果肉眼可見。但當 Agent 從“回答一個問題”變成“完成一項工作”——比如連續(xù)跑一個月的市場分析、自動整理幾百個文件、無人值守地調度外部系統(tǒng)——工程問題的性質就徹底變了。這不是把 Prompt 寫長一點能解決的。從單次回答走向長任務執(zhí)行真正發(fā)生變化的是Agent 不再是一個無狀態(tài)的函數(shù)而是一個需要持續(xù)運行、重復讀寫狀態(tài)、隨時應對失敗、被監(jiān)控和限制的長期進程。它從一個“會說話的模型”變成了一個“必須被托管的工作負載”。于是在這個轉變背后問題就浮出來了工程工作到底發(fā)生在哪里我的結論很明確工程重心不在模型這一側而在圍繞任務構建的整個執(zhí)行框架里——狀態(tài)管理、編排控制、失敗恢復、成本護欄、可觀測性。下面我就基于自己做過長任務 Agent 的真實項目把這幾個核心位置分別拆開講清楚每一處到底在做什么以及為什么這些工作沒有辦法用“模型智能”替代。1. 單次回答的思維慣性為什么扛不住長任務執(zhí)行1.1 無狀態(tài)回答與有狀態(tài)進程之間的鴻溝當我們調用大模型聊天接口時本質上在做一件非常簡單的事把一段文本發(fā)給模型模型基于上下文生成一段新文本返回。整個過程是無狀態(tài)的——輸入、輸出、結束。即使是多輪對話也不過是每次把歷史拼接進去模型自己并不維護真正的“記憶”。長任務執(zhí)行則完全不同。假設一個 Agent 被要求“每天早晨抓取行業(yè)新聞生成分析摘要發(fā)送到項目群并歸檔到知識庫”這個任務要連續(xù)運行 30 天。這時候真正重要的問題變成了今天幾點運行跑完沒有上次生成了什么摘要和昨天的內容重復了嗎抓取接口突然掛了是跳過今天還是持續(xù)重試消息發(fā)送成功但歸檔寫失敗算完成還是部分完成用戶中途改了目標是重啟任務還是斷點續(xù)跑這些問題沒有一個是模型“聰明”一點就能自己解決的它們幾乎全部依賴工程層面對任務狀態(tài)的建模。我把這個差距概括為“函數(shù)式思維”與“進程式思維”的區(qū)別。單次回答是函數(shù)輸入 X返回 Y。長任務是進程啟動、運行、暫停、恢復、終止中間還要持久化大量中間產物。1.2 長任務 Agent 的狀態(tài)到底包含什么實際落地時至少要維護這幾類狀態(tài)狀態(tài)類別典型字段說明任務目標狀態(tài)objective、current_phase、status當前做到哪一步目標有沒有變化執(zhí)行歷史狀態(tài)events、step_results、checkpoints每一步做了什么、結果如何依賴資源狀態(tài)credentials、config、外部系統(tǒng)連接信息運行環(huán)境是否就緒預算與配額狀態(tài)token_budget、cost、remaining_retry防失控的核心數(shù)據(jù)人工協(xié)同狀態(tài)waiting_for_human、decision_log哪些節(jié)點在等人審批用結構化存儲來維護這些狀態(tài)而不是全部塞進對話歷史里讓模型去“記住”。模型再聰明狀態(tài)也必須滿足三個硬性要求可查詢、可恢復、可審計。對話歷史天然不具備這些能力。你很難從一個聊天記錄里回答“上一步到底用了哪個工具參數(shù)”但你能從一張結構化事件表里兩秒查出來。1.3 工程視角的轉變從提示設計到執(zhí)行設計早幾年聊 Agent 工程大多數(shù)人默認核心是 Prompt。在單輪場景下Prompt 確實能決定 90% 的效果。但長任務場景跑下來你會發(fā)現(xiàn)“提示語”的作用在快速衰減——因為失敗的環(huán)節(jié)往往不是“模型理解不了指令”而是“任務跑到中段狀態(tài)臟了”“外部系統(tǒng)返回了完全意外的數(shù)據(jù)”“超時重試把業(yè)務做重復了”。我做過的幾個長任務項目基本都經歷了三個階段。第一階段是興奮期覺得只要描述清楚目標Agent 就能自己搞定一切于是把目標塞進 Prompt直接while true循環(huán)調用。第二階段是翻車期任務跑兩天后各種問題接踵而至上下文爆炸、死循環(huán)、重復執(zhí)行、任務中斷后無法恢復、賬單嚇人所有人開始瘋狂打補丁。第三階段才是工程期老老實實把任務當成一個分布式系統(tǒng)來設計狀態(tài)落庫、步驟冪等、失敗分級、預算截斷、全程可觀測之后穩(wěn)定性才真正上來。這個歷程太典型了。所以先給一個結論放在這里**長任務 Agent 的工程工作不在提示詞里而在任務運行時的工程容器里。**接下來的幾個章節(jié)就是對這個容器核心模塊的逐層拆解。2. 任務不是對話把目標拆解成可落庫的狀態(tài)圖2.1 拆解層級目標、階段、步驟長任務管控的第一步是把“一個模糊的大目標”拆成計算機能管理的最小單元。我常采用四層結構Objective目標一句話定義最終成果例如“完成 Q3 競品分析報告”。Milestone階段大目標的分隔點例如“收集數(shù)據(jù)”“分析數(shù)據(jù)”“生成報告”。Task任務具體工作項例如“抓取 5 個競品官網的更新動態(tài)”。Step步驟一次原子操作例如“調用瀏覽器工具抓取 xx 網頁并解析正文”。這里有個實操經驗拆得越細可控性越強但編排成本也越高。比較合適的粒度是“一個 Step 對應一次外部動作或一次模型決策”比如一次搜索、一次讀取、一次寫入、一次需要判斷的節(jié)點。這樣既能保證恢復粒度又不會讓狀態(tài)表爆炸。拆解之后并不是所有任務都是線性執(zhí)行的。很多長任務天然包含分支、等待、循環(huán)。所以底層建議用狀態(tài)機或任務圖來建模。每個 Step 可以有前置條件、執(zhí)行動作、后置校驗前置條件不滿足就阻塞等待。但我也要潑一盆冷水**千萬不要一上來就搞流程引擎。**在任務還只有十幾個 Step 時用數(shù)據(jù)庫狀態(tài)表加循環(huán)調度就足夠了甚至可以是最樸素的while switch。等真正需要處理并發(fā)和復雜依賴時再上圖形化編排引擎。否則你會有一種“為了裁一棵樹買了整個家具工廠”的荒謬感。2.2 狀態(tài)存儲與檢查點跑一半掛了不能從頭再來任務一旦開始運行最重要的工程動作是“隨時落狀態(tài)”。每完成一個 Step就把這個 Step 的輸入、輸出摘要、Token 消耗、開始結束時間寫進持久化存儲。模型調用是昂貴的而落庫是廉價的不要省這筆錢。我習慣用這樣一組表來承載任務狀態(tài)task_instance表task_idobjectivestatuscurrent_phaseinput_snapshot任務啟動時的完整輸入參數(shù)JSON 快照created_atupdated_atlast_heartbeattask_event表event_idtask_idstep_idevent_typedatacreated_atstep_result表idtask_idstep_namestatusinput_summaryoutput_summarytoken_usagemodellatency_msstarted_atfinished_attask_event尤其重要。它是一條只增不減的事件流每一次決策、每一次工具調用、每一次失敗都追加為一條事件。為什么要用事件流而不是只維護一份“最新狀態(tài)”第一事件流天然可回放排查問題時能看到完整決策路徑第二事件流支持冪等重建即使狀態(tài)表損壞也能從事件記錄里恢復第三做審計和成本分析時只需要掃這一張表。檢查點checkpoint則是為了恢復。在任務的生命周期里每完成一個安全節(jié)點就寫入檢查點。所謂安全節(jié)點通常是“所有前置操作已完成且結果已確認”的位置。進程重啟后調度器讀取最近檢查點把目標、當前階段、近期事件摘要重新組裝進 Prompt讓 Agent 接著跑而不是重頭再來。2.3 冪等設計長任務最常見的翻車現(xiàn)場長任務工程中重復執(zhí)行是頭號事故來源而且越簡單的場景越容易翻車。舉一個我踩過的例子某個文檔處理任務流程是“讀取文件 → 解析內容 → 調用模型總結 → 寫入輸出 → 發(fā)通知”。某次模型總結步驟超時了程序判定失敗并重試整個任務。重啟后從第一步重新執(zhí)行結果文件被寫入了兩份下游同事收到了兩次重復通知。單次回答場景里根本不會有這種問題——回答失敗就重新問一次模型沒有副作用。但長任務里每一步都可能對外部系統(tǒng)產生真實影響重放操作就是真實的生產事故。解決思路其實不復雜為每個外部寫操作生成一個冪等鍵。比如“數(shù)據(jù)導入”任務中每條導入記錄都帶上source_batch_id record_no作為唯一鍵寫入時數(shù)據(jù)庫按唯一鍵去重。批量工具調用、發(fā)消息、生成文件、提交工單全部做同樣的處理。另一個常用做法是把“命令是否已執(zhí)行”記錄在步驟狀態(tài)里重試時先查狀態(tài)如果該步驟已完成就直接跳過、進入下一步。實際中還需要給外部 API 調用編號每次模型說要調用工具先分配一個invocation_id執(zhí)行結果和invocation_id綁定重試同一決策時帶上相同 ID外部系統(tǒng)就能識別重復。這不是新發(fā)明就是把分布式系統(tǒng)里的“冪等消費”概念搬進 Agent 任務的每一個副作用操作上。3. 編排的核心戰(zhàn)場兩次模型調用之間發(fā)生了什么3.1 Agent 循環(huán)的完整拆分很多人理解的 Agent 循環(huán)是三行偽代碼讓模型思考、讓模型調用工具、把結果還給模型。真正工程化后的循環(huán)要復雜得多我把它拆成六個連續(xù)階段讀取狀態(tài)從任務存儲中取出當前階段、目標、前置結果。組裝上下文按預算裁剪相關歷史、檢索必要信息、拼接當前指令。模型決策模型產出下一步動作可能是調用某個工具、指定參數(shù)或給出中間結論。動作執(zhí)行工具層執(zhí)行外部操作可能是 HTTP 請求、文件讀寫、數(shù)據(jù)庫查詢、發(fā)送消息。結果驗證用確定性規(guī)則或獨立校驗器評估動作結果是否符合預期。狀態(tài)回寫將動作結果、驗證結論、Token 消耗追加到事件流推進狀態(tài)機。在這六步里最容易被忽略也最容易出事的是第 5 步“結果驗證”。大量 Agent 實現(xiàn)是“模型說調用就調用工具返回什么直接塞回 Prompt”完全不做結果層面的判斷。于是會出現(xiàn)這種情況搜索接口返回了 500 錯誤頁模型卻把錯誤內容當成正常搜索結果繼續(xù)分析發(fā)送郵件接口返回“成功”但實際發(fā)到了測試郵箱表格寫入說完成實際只有表頭。我的工程要求很簡單每一個工具動作都配一個驗證模塊能驗證就寫確定性斷言。比如“響應 status 必須是 200 且 body 包含 title 字段”“寫庫后必須能 SELECT 回來”。模型可以判斷語義但工程上一定要有規(guī)則兜底。3.2 上下文管理長任務的慢性病這是長任務 Agent 區(qū)別于單次回答最折磨人的地方。任務跑到第 20 輪如果每輪都把全部歷史塞回模型Prompt 會迅速膨脹。我第一次做長任務時跑到第 15 輪就發(fā)現(xiàn)模型開始“忘記”用戶最初的目標經常答非所問。排查時一查 Token 用量發(fā)現(xiàn)每輪上下文已經超過 5 萬 Token。根因根本不是模型不行而是工程上沒有做上下文治理。目前常用的手段有以下幾種滾動摘要早期步驟的原始結果每隔幾輪被模型壓縮成一個摘要后續(xù)只保留摘要摘要過長再壓縮成摘要的摘要。結構化外部化工具調用的完整輸出存進數(shù)據(jù)庫Prompt 里只放“該步驟已完成結果見附件 ID x”這類引用信息需要細節(jié)時再用檢索工具去取。裁剪與召回對歷史事件按重要度打分保留高價值信息低價值信息裁剪后存外部記憶需要時通過語義搜索召回。上下文預算每輪進入模型前計算 Token 預算比如單輪限制 16K歷史太長就先做摘要再進 Prompt。核心原則是**長期記憶是數(shù)據(jù)庫的職責不是 Prompt 的職責。**模型只需要拿到“眼前這一步需要的最小信息集”。這也是長任務 Agent 和大模型單輪對話在工程上最本質的差異之一。3.3 人工確認節(jié)點與等待語義不是所有動作都應該讓 Agent 自己說了算。在長任務里凡是“成本高、影響大、不可逆”的動作都應該插入人工確認節(jié)點。比如對外發(fā)送通知、提交訂單、刪除數(shù)據(jù)、發(fā)布內容。如果沒有審批機制Agent 一旦決策失誤后果會被放大成真實事故。工程實現(xiàn)上我一般讓狀態(tài)機支持waiting_for_human這個狀態(tài)。當 Agent 走到審批節(jié)點時不是繼續(xù)瞎猜而是把待確認內容、影響范圍、下一步選項推送給用戶可以通過 IM、郵件或控制臺任務卡展示然后任務掛起、存儲狀態(tài)、開啟超時計時。用戶在控制臺點擊“批準 / 拒絕 / 修改參數(shù)”任務恢復。等待語義必須顯式設計否則很容易出現(xiàn)“任務看似活著但卡住了”的現(xiàn)象。我給每個waiting_for_human節(jié)點也設置超時。比如策略是超過 6 小時未確認則再次推送超過 24 小時未確認則自動掛起并通知管理員。這樣人工環(huán)節(jié)本身也不會成為靜默堵點。這套等待恢復機制的技術含量不算高但它直接決定了 Agent 能否被放心地投入真實業(yè)務流程。沒有人工確認節(jié)點的長任務 Agent本質上是一個沒有剎車的自動駕駛性能和風險成正比。4. 失敗分類與重試設計長任務工程里最殘酷的一課4.1 失敗的層次不是所有失敗都該重試長任務跑久了失敗是必然的問題只在于系統(tǒng)怎么應對失敗。如果對所有失敗一視同仁統(tǒng)一走“重試”那最直接的后果是有些重試毫無意義有些重試把問題放大。我把運行中遇到的失敗分成四類失敗類型典型例子處理策略瞬時錯誤網絡超時、限流、服務 5xx指數(shù)退避重試上限約 3-5 次確定性錯誤參數(shù)不合法、權限不足、文件不存在不重試讓模型修正參數(shù)或改變策略業(yè)務校驗失敗工具執(zhí)行成功但結果不符合預期規(guī)則返回校驗信息模型換方案限次數(shù)不可收斂模型反復嘗試同樣的失敗動作強制暫停轉入人工這個分類看起來簡單實際意義很大。瞬時錯誤重試是正確的因為外部服務抖一下會自己恢復確定性錯誤重試一百次也是同樣結果不如把錯誤信息回傳給模型讓模型重新思考動作參數(shù)業(yè)務校驗失敗不能簡單重試要讓模型理解“這次動作雖然執(zhí)行成功但結果不滿足驗收條件”。我還會給每個 Step 加一個retry_policy字段不同步驟掛不同的策略而不是走全局同一套。比如“調用外部接口”默認指數(shù)退避重試 3 次“寫入數(shù)據(jù)庫”默認失敗即停、需要人工處理“發(fā)送通知”默認失敗后轉入補償流程。策略掛在步驟上恢復邏輯才有針對性。4.2 重試的放大效應從單點抖動到任務雪崩這里想單獨講一個高頻翻車場景重試疊加導致的雪崩。假設一個 Agent 任務是批量調用某個第三方平臺的開放接口每個批次要處理 2000 條數(shù)據(jù)。某次對方接口開始限流如果重試策略是無腦重試會發(fā)生什么第一次調用失敗等 0.5 秒重試失敗等 1 秒所有 Worker 同步重試瞬間把第三方接口打到更嚴重的限流形成惡性循環(huán)。其結果不僅是任務失敗還可能因為觸發(fā)對方封禁策略導致整個賬號被限制。這類問題的解法在傳統(tǒng)后端領域已經很成熟直接平移過來就好退避抖動 熔斷 并發(fā)限制。我在任務調度層加了一個熔斷開關當某個外部服務的連續(xù)失敗率達到閾值比如 30%就把對這個服務的調用暫時降級或暫停讓任務先處理其他分支等冷卻窗口過了再恢復。加了熔斷之后第三方抖動造成的連帶傷害肉眼可見地減少了。關鍵轉變在于Agent 的任務框架不能把“模型調用”和“外部工具調用”混為一談。模型調用失敗可以用重試解決但外部工具調用失敗要考慮業(yè)務語義。拿捏不住這一點所謂的智能 Agent 會在最簡單的問題上暴露最原始的架構缺陷。4.3 部分完成與補償任務不是非黑即白長任務里最難處理的不是“完全失敗”而是“部分完成”。比如一個任務的目標是“把 10 份文件從 A 系統(tǒng)同步到 B 系統(tǒng)”跑到第 7 份時 A 系統(tǒng)接口掛了。這時候整任務標記為failed不公平前 7 份白干了標記為success更不對還有 3 份沒完成。我建議的做法是讓任務狀態(tài)機支持“部分完成 斷點續(xù)跑”。任務本身維持running或升級為suspended狀態(tài)但明確記錄已完成步驟列表、失敗步驟列表、剩余步驟列表。重啟恢復后調度器從剩余步驟開始而不是重新執(zhí)行所有步驟。這就是檢查點機制真正的價值。另外還要考慮補償compensation。有些操作一旦部分執(zhí)行必須做回滾或對沖。比如批量提交審批的任務提交到一半失敗這時候如果直接續(xù)跑可能造成重復提交正確方式是先查詢未審批單據(jù)補提交缺失的單據(jù)并清除重復記錄。補償邏輯最好在任務編排階段就定義好而不是等事故發(fā)生了再來打補丁。4.4 防死循環(huán)別讓 Agent 進入“螺旋加班”狀態(tài)長任務自動循環(huán)跑著跑著出現(xiàn)死循環(huán)是真實存在的。我自己就遇過Agent 被要求整理一批 PDF其中一份文件解析失敗。模型試圖重試解析失敗換一種解析方法還是失敗換個標題再看一次還是失敗。整個任務卡在同一個文件上循環(huán)了將近 30 輪消耗大量 Token毫無進展。為什么會出現(xiàn)這種情況因為模型在開放場景下天然傾向于“繼續(xù)嘗試”而沒有一個“我應該停下來求助”的機制。這個傾向在單次問答里無所謂在長任務里就是燒錢黑洞。工程上的防死循環(huán)主要有三條。一是全局循環(huán)上限比如每個階段最多執(zhí)行 N 輪模型決策超過就強制暫停。二是失敗模式識別連續(xù) M 次收到同一類錯誤自動標記“此處需要人工判斷”。三是給模型顯式的退出信號在系統(tǒng)提示詞中聲明“如果同一目標嘗試多次仍失敗請生成 NEED_HELP 決策而不是繼續(xù)嘗試?!边@個設計本質上是在給“自由意志”裝剎車。沒有剎車的 Agent 不是效率工具是風險工具。5. 護欄越界即事故成本、權限與完成度驗證5.1 成本預算Token 不是自來水是真金白銀做單次回答 Agent 的人通常對 Token 成本不敏感一次問答幾毛錢無所謂。但長任務 Agent 的成本模型完全不一樣任務持續(xù)運行、頻繁循環(huán)幾十輪調用是常態(tài)。如果任務里還包含文本處理、PDF 解析、批量搜索每天的 Token 消耗可能是單次回答的幾十倍甚至上百倍。我有一次跑一個“批量總結競品文檔”的任務沒有做預算限制結果一個晚上跑了 128 輪模型調用消耗超過 120 萬 Token。賬單出來的時候我整個人是清醒的智能的代價是真的貴。工程上必須做三重預算控制任務級預算給每個 Task 設置最大 Token 數(shù)和最大金額超限自動暫停。階段級預算每個 Milestone 分配額度防止單階段耗盡全局可用資源。實時監(jiān)控每次模型調用后累計消耗超過閾值觸發(fā)告警超過硬頂強制凍結任務。預算告警要接人工通知。比如消耗超過 50% 時 IM 通知超過 80% 時再次通知超過 100% 自動掛起。不要讓一個無人值守任務悄悄把預算燒完。5.2 最小權限與高風險動作審批長任務的執(zhí)行環(huán)境比單次回答更需要權限管控。原因很簡單單次回答沒有外部副作用但長任務會調用真實工具、真實接口、真實寫操作。如果你給 Agent 配了一個“管理員”級別的賬號它一旦被惡意注入的指令誤導后果就是整個系統(tǒng)范圍內的事故。我的經驗法則是**給 Agent 進程分配最小的專用憑證只開放任務必需的 API 權限所有刪除、覆蓋、發(fā)送、支付、發(fā)布類動作默認走人工審批節(jié)點絕不賦予 Agent 自動執(zhí)行權限。**工具調用使用允許名單模式Agent 只能調用名單內的工具遇到未授權工具直接返回“無權限”而不是繼續(xù)嘗試。有人會說這樣 Agent 就不“自主”了。我的回答是自主是工程給的邊界內的自主不是無限自由。真實的自動化系統(tǒng)從來都是“被約束的自動化”不約束的 Agent 只能待在 Demo 里。5.3 完成度驗證Agent 說做完了不等于真的做完了長任務“跑完”并不等于“做好”。模型的自我評估天然帶有樂觀傾向它傾向于認為自己已經完成了用戶目標。工程上必須對完成度做獨立驗證。我在任務結尾會加一個“完成校驗階段”做三件事讓 Agent 輸出執(zhí)行報告完成了哪些步驟、每步結果的依據(jù)是什么、哪些地方和原目標有偏差。通過自動化規(guī)則核查關鍵產出比如“報告文件存在且非空”“所有源文件已歸檔”“目標系統(tǒng)記錄數(shù)已核對”。人工抽查或獨立評審對關鍵任務把執(zhí)行報告和核心產物發(fā)給一個獨立評審者可以是人也可以是另一個模型實例評審通過后才允許把任務標記為success。這套“做完 驗完 完成”的語義看起來保守但在真實業(yè)務里非常有用。它讓任務從“跑完流程”升級為“交付結果”用戶對 Agent 的信任也是這么一點點建立起來的。6. 長任務的可觀測性Debug 從“猜謎”變成“回放”6.1 事件流打底每輪決策都值得留痕長任務 Debug 和單次回答 Debug 完全兩碼事。單次回答出問題直接看模型輸出就完了。長任務出問題你需要回答的是這個 Agent 為什么在昨天下午三點做了一個奇怪的操作它當時看到了什么上下文哪個步驟觸發(fā)了它做這個決策要回答這些問題必須讓執(zhí)行過程可回放。前面說的task_event表就是基礎每個模型調用記錄當時組裝后的完整 Prompt 摘要、模型、輸入輸出 Token、耗時每次工具調用記錄工具名、參數(shù)、輸出摘要、返回狀態(tài)每個錯誤記錄錯誤類型、錯誤信息、重試次數(shù)。所有事件按時間順序落庫。注意一個實操細節(jié)不要把完整 Prompt 都存進每個事件會很占空間。我通常存“Prompt 摘要 關鍵上下文片段 完整調用 ID”調用 ID 指向獨立日志存儲。這樣既保證可回放又不至于把數(shù)據(jù)庫撐爆。6.2 任務時間線與回放模式有了事件流就可以給每個任務生成一條時間線從啟動、規(guī)劃、每一步決策、工具調用、失敗重試、人工等待到最終完成或終止。界面按時間展示每條事件包含時間、類型、關鍵摘要?;胤拍J绞俏易鲩L任務最依賴的 Debug 手段。所謂回放就是按時間順序把事件重新走一遍重現(xiàn) Agent 的決策路徑。遇到“任務結果完全不符合預期”的情況第一件事就是打開回放看它在哪一步開始偏離目標是哪條上下文讓它做出了錯誤判斷。答案比盲改 Prompt 快得多??梢怨蚕硪粋€經驗數(shù)據(jù)我修長任務問題的耗時分布大約 40% 在“定位哪一步出了問題”30% 在“理解當時為什么會這么決策”20% 在“制定修復方案”10% 在“實施修復”。如果沒有事件流和回放前兩項會無限膨脹Debug 基本靠猜。6.3 心跳與靜默告警長任務的“活人監(jiān)護”長任務系統(tǒng)最危險的一個狀態(tài)是“靜默死亡”進程還在線程還在但循環(huán)不再推進也沒有任何報錯。這個狀態(tài)比崩潰更可怕。崩潰會立刻觸發(fā)告警靜默死亡不會。防止靜默死亡的辦法是給任務加心跳。每次狀態(tài)變更都更新last_heartbeat字段調度器或定時巡檢定期掃描如果某個running狀態(tài)的任務心跳超過閾值比如 10 分鐘沒有變化就判定“可能卡住”觸發(fā)告警并把任務掛起。實際中我還加過“看護進程”如果任務在一個階段內沒有任何事件產出看護進程會主動詢問模型“當前還在處理嗎”如果模型連續(xù)兩次未正確響應就強制重啟該階段或轉入人工。有人擔心這樣會誤傷正在慢速運行的任務。會所以心跳閾值要結合任務特點設置耗時長的外部等待可以明確標記為“等待外部系統(tǒng)”不算靜默。這里的原則是寧可偶爾誤告警也不要讓異常靜默吞掉生產事故。6.4 復盤跑完任務后把日志變成經驗最后想提一個工作習慣每個長任務跑完一版后花時間做一次“任務復盤”。我會讓系統(tǒng)自動生成執(zhí)行摘要總耗時、總 Token 消耗、失敗最多的階段、人工介入次數(shù)、成本分布。然后人工查看這些數(shù)據(jù)找出最值得優(yōu)化的環(huán)節(jié)??赡苁悄硞€工具調用頻繁失敗可能是某類 Prompt 總引導模型走彎路也可能是上下文裁剪策略過于激進導致模型丟失關鍵信息。這一步看似不是核心功能但實際上對長任務 Agent 的持續(xù)優(yōu)化至關重要。沒有復盤你就是反復踩同一個坑有復盤每跑一周任務系統(tǒng)就變聰明一點。工程上的長期主義往往就是從這些不起眼的例行流程里長出來的。做長任務 Agent 這一年多我最大的體會是當 Agent 從“單次回答”走向“長任務執(zhí)行”工程上真正發(fā)生工作的位置幾乎全都在模型外部——狀態(tài)怎么存、失敗怎么處理、成本怎么限制、行為怎么審計、結果怎么驗證。模型的智能負責做決策工程框架負責讓決策安全落地。這兩者之間不存在替代關系Prompt 寫得再好也替代不了冪等鍵、檢查點和預算熔斷。所以如果你正打算開始做長任務 Agent我的建議很直白先別急著調 Prompt。先把任務狀態(tài)表設計好、把失敗分類定義清楚、把可觀測性底子打牢然后再去追求 Agent 的自由度??蚣芊€(wěn)了Agent 才能真正跑得遠。