指南)
做 Agent 評估最容易犯的錯誤是把“換模型”當(dāng)成“換 API 地址”。這次從 sonnet 切到 deepseek v4 flash我真正花時間的不是修改接入代碼而是把評估集、評估指標和跑批流程重新對齊了一遍。這篇文章適合正在做 Agent 選型、模型切換、質(zhì)量評估的開發(fā)者和算法同學(xué)。最值得關(guān)注的不是某個模型更強而是怎么在統(tǒng)一口徑下判斷它到底能不能進入生產(chǎn)環(huán)境。一個 Agent 項目里模型替換牽扯的東西比普通模型評測要多得多。你要保證工具調(diào)用能被解析、多輪任務(wù)能走完、結(jié)構(gòu)化輸出能落到下游代碼里、延遲和成本還在預(yù)算內(nèi)。下面按我實際操作的順序拆開講。1. 給 Agent 做模型切換評估先拆清楚“評估什么”1.1 Agent 評估和普通模型評測不是一回事普通模型評測通常是給一個輸入讓模型直接輸出答案然后用準確率、BLEU、Rouge 這些指標打分。到了 Agent 場景這套方法就不夠用了。Agent 不是只回答一次。它要先理解任務(wù)再決定調(diào)用哪些工具工具返回之后還要繼續(xù)分析可能再調(diào)用下一輪最后才給出結(jié)果。整個鏈路里任一步出錯任務(wù)就失敗。哪怕模型“說話”很流暢只要工具調(diào)用參數(shù)寫錯或者兩步之間邏輯接不上最后的結(jié)果依然不可用。所以給 Agent 做模型切換評估核心不是測“誰的回答更像人”而是測“誰能在同一套工具和提示詞下面穩(wěn)定地把任務(wù)跑完”。這個差異很關(guān)鍵。之前我好幾次看到有人直接拿通用評測集的題目去測 Agent測出來分數(shù)差不多但一旦接上真實工具差異馬上拉開。1.2 從 sonnet 切到 deepseek v4 flash對比的指標要有側(cè)重點在這次的切換中我建了一張指標表一開始就定了對比維度。不然跑完一輪數(shù)據(jù)很多但你根本不知道應(yīng)該看什么。指標怎么判斷為什么關(guān)鍵任務(wù)完成率每條任務(wù)是否走到預(yù)期結(jié)束狀態(tài)最直接的 Agent 能力體現(xiàn)工具調(diào)用成功率模型返回的工具名和參數(shù)能否被正確解析執(zhí)行Agent 和普通問答的核心區(qū)別結(jié)構(gòu)化輸出合格率輸出 JSON、字段、類型是否能直接消費決定下游代碼要不要加大量兜底延遲單條任務(wù)從發(fā)起到結(jié)束的時間影響用戶體驗和隊列占用token 成本一條任務(wù)平均消耗的輸入/輸出 token決定切換后預(yù)算是否可控異常率超時、死循環(huán)、重復(fù)調(diào)用、截斷等生產(chǎn)可用性的底線這些指標不能只看平均數(shù)還要看分布。尤其是工具調(diào)用成功率和異常率如果一批任務(wù)里反復(fù)出現(xiàn)同一種異常就要先排查不能被整體平均分掩蓋。我還會加一個“后處理修正率”作為參考模型第一次輸出不合法需要程序修正后才能繼續(xù)執(zhí)行的占比。這個指標高說明當(dāng)前模型并不真正適配你的 Agent 結(jié)構(gòu)只是被代碼兜住了。2. 評估集和評估腳本沒有統(tǒng)一入口就是白測2.1 評估集要從真實業(yè)務(wù)里長出來第一個建議是不要自己去編一堆“有挑戰(zhàn)性”的任務(wù)。容易編偏。更可靠的做法是從線上日志里抽真實用戶問題先做脫敏再按業(yè)務(wù)類型分類。比如我們這個項目里有幾類普通信息查詢需要調(diào)用內(nèi)部工具查詢數(shù)據(jù)需要連續(xù)調(diào)用多個工具完成鏈路用戶輸入模糊需要主動澄清輸入明顯有誤需要拒絕或校驗每類至少準備 5 到 10 條總共 50 到 100 條比較合適。不要一上來就準備 1000 條。Agent 評估的標注成本比普通模型高很多。每條任務(wù)都要寫“預(yù)期動作”和“預(yù)期結(jié)果”還要人工核對模型走的過程。50 到 100 條已經(jīng)能看出大部分方向性問題。如果評估集不方便從日志截取可以先從團隊成員日常維護的測試用例里挑。但一定要盡量貼近線上真實輸入。否則結(jié)果只能說明模型在“你給的任務(wù)”上表現(xiàn)好不能說明它在業(yè)務(wù)里表現(xiàn)好。如果你的 Agent 主要依賴 RAG也可以參考 ragas 這類開源評估工具的思路先評估檢索質(zhì)量。但完整 Agent 的評估不能停留在檢索必須落到任務(wù)執(zhí)行鏈路。2.2 統(tǒng)一輸入輸出兩個模型必須跑同一套通道切換評估最忌諱的就是模型 A 用一套 prompt模型 B 用另一套。這樣拿到結(jié)果根本沒有可比性。我在這次評估里不管底層接的是 sonnet 還是 deepseek v4 flash都走同一個 Agent Runner 入口。系統(tǒng)提示詞、工具描述、任務(wù)輸入、超時策略都保持一致。唯一變的只是模型配置。輸出也要統(tǒng)一成一種記錄格式把每個任務(wù)的關(guān)鍵信息全部落下來{ task_id: T001, model: deepseek-v4-flash, prompt_version: v2.3, tool_calls: [ {name: query_sales, arguments: {date: 2025-06-01}} ], final_answer: 當(dāng)日銷售額為 ..., input_tokens: 1280, output_tokens: 610, latency_ms: 3820, error: null }這樣后面無論是算平均指標還是定位某條失敗任務(wù)都能直接查原始記錄。2.3 用一套輕量 harness 跑批而不是每次手點Agent 評估的關(guān)鍵是“可重復(fù)”。所以我建議把跑批腳本沉淀成一個小工具而不是每次手點。早期沒有統(tǒng)一腳本時問題特別多不同人跑出來的結(jié)果不是同一批 prompt、輸出沒有存原始日志、失敗之后重試規(guī)則不一致。后來我寫了一個很輕量的評估 runner邏輯不復(fù)雜def run_agent_eval(tasks, model_config, max_rounds5): records [] for task in tasks: record run_single_task(task, model_config, max_rounds) records.append(record) save(record) return records核心不是代碼復(fù)雜度而是以下幾點失敗任務(wù)不能跳過要記錄 error 信息每條任務(wù)限制最大輪數(shù)防止死循環(huán)結(jié)果寫入本地文件或數(shù)據(jù)庫方便后續(xù)分組統(tǒng)計跑批前記錄評估集 hash 和 prompt 版本保證可回溯注意跑批前先確認評估集 hash 和 prompt 版本都固定了否則結(jié)果不可比。跑批時我不建議一開始就開高并發(fā)。先用單線程跑一遍確認輸出和日志都正常再考慮并發(fā)。并發(fā)一開日志順序會很亂后面排查會很痛苦。3. 單任務(wù)先跑通再跑批量從 sonnet 切到 deepseek v4 flash 的最小驗證路徑3.1 先拿單任務(wù)驗證連通性切換模型前不要直接跑 100 條。先從一條最簡單的任務(wù)開始比如調(diào)用一個返回固定信息的工具。這一步的目的是把“接口能不能通”這個基礎(chǔ)問題確認掉。常見注意點model 名稱要準確。不同 API 網(wǎng)關(guān)對模型標識的要求不一樣接入 deepseek v4 flash 時要以你拿到的配置為準。鑒權(quán) header 不要寫死到業(yè)務(wù)代碼里最好通過環(huán)境變量或配置中心下發(fā)。超時參數(shù)要合理。Agent 任務(wù)多輪調(diào)用單次請求超時和整條任務(wù)超時要分開設(shè)置。如果連單條任務(wù)都一直報錯不要懷疑模型能力先看報錯信息里的狀態(tài)碼和原始響應(yīng)體。很多問題其實只是參數(shù)名沒對上。我一般會用一條“當(dāng)前時間查詢”或“固定結(jié)果查詢”來驗證。它不涉及復(fù)雜鏈路能最快暴露接口層問題。3.2 用 30 條小樣本做冒煙測試連通之后我會先跑 30 條左右的小樣本而不是立刻全量跑批。小樣本的目的不是得出最終結(jié)論而是快速判斷方向。跑完后不要只看通過率。要一條一條翻原始輸出。我一般會重點看三類失敗工具調(diào)用返回了但參數(shù)解析失敗模型一路用自然語言解釋但沒有真正執(zhí)行工具任務(wù)進入循環(huán)反復(fù)調(diào)用同一個工具拿不到結(jié)果這三類問題如果在小樣本階段出現(xiàn)超過幾次就不是偶發(fā)應(yīng)該先處理 prompt、工具描述或者模型參數(shù)而不是繼續(xù)跑全量。小樣本冒煙只用來判斷方向不要拿它當(dāng)最終結(jié)論。3.3 全量跑批生成本次切換評估報告小樣本身邊看邊改改到?jīng)]有明顯方向性問題后再固定評估集和 prompt 版本跑全量。全量跑批時要注意兩個模型最好在同一個時間段內(nèi)跑避免線上工具返回結(jié)果變化影響對比跑批時把 temperature 調(diào)成同一個值建議從 0 或低溫度開始記錄開始時間、結(jié)束時間、評估集 hash、prompt 版本跑完直接生成一個對比報告把每個任務(wù)兩個模型的結(jié)果放在一起看生成對比報告時我會先看“兩個模型都不對”和“只有一個模型對”的任務(wù)。前者可能是任務(wù)本身標注有問題后者才是模型差異的體現(xiàn)。如果兩個模型在同一批任務(wù)上錯得都一樣先檢查任務(wù)本身的預(yù)期結(jié)果是不是寫錯了。4. 從結(jié)果數(shù)據(jù)判斷“能不能切”完成率、成本、延遲怎么取舍4.1 先看工具調(diào)用和結(jié)構(gòu)化輸出Agent 場景里模型返回的如果是一段漂亮的自然語言但沒有可執(zhí)行的結(jié)構(gòu)化動作這個結(jié)果對系統(tǒng)來說幾乎沒用。所以我評估時會單獨算兩個比例工具調(diào)用解析率結(jié)構(gòu)化輸出合格率工具調(diào)用解析可以用一個很樸素的函數(shù)來校驗def is_valid_tool_call(raw): if not isinstance(raw, dict): return False if not isinstance(raw.get(name), str): return False args raw.get(arguments) if not isinstance(args, dict): return False return True只要程序沒能解析出合法的 tool_call就會計入失敗。如果 deepseek v4 flash 在這個指標上明顯低于 sonnet別急著下結(jié)論。先看它是在哪一類任務(wù)上失分。有時是工具描述寫得不夠清楚有時是參數(shù) schema 太復(fù)雜。換一個更清晰的描述結(jié)果可能就明顯改善。4.2 成本不是只算單次請求很多模型切換評估把成本算得太簡單只看一次請求的 token 價格。到了 Agent 場景這個算法很容易失真。Agent 任務(wù)通常要多個回合。一個簡單查詢可能只要 2 輪復(fù)雜任務(wù)可能要到 5 到 8 輪。實際成本應(yīng)該是單任務(wù)成本 每輪輸入 token 之和 × 輸入單價 每輪輸出 token 之和 × 輸出單價評估時我會在記錄里保存每個任務(wù)的總 token 和總輪次最后分別求平均。對比表格可以這樣列模型任務(wù)完成率平均輪次平均輸入 token平均輸出 token平均單任務(wù)延遲估算成本sonnet本次實測值本次實測值本次實測值本次實測值本次實測值按實際單價算deepseek v4 flash本次實測值本次實測值本次實測值本次實測值本次實測值按實際單價算不要直接抄我這張表里的結(jié)論因為模型價格和評估任務(wù)差異太大但可以按這個結(jié)構(gòu)去統(tǒng)計。除了平均成本還要關(guān)注異常成本。比如某個任務(wù)因為模型死循環(huán)連續(xù)調(diào)了 20 次工具token 消耗可能是一個正常任務(wù)的 5 倍以上。這種異常任務(wù)會直接影響月末賬單。4.3 給“可以切換”定一個自己的閾值評估完成后真正難的是拍板。我的習(xí)慣是先定底線再看分數(shù)任務(wù)完成率不能比原模型低超過 3 到 5 個百分點工具調(diào)用解析失敗率不能超過 1% 到 2%單任務(wù) P95 延遲不能超過線上可接受上限成本即使上升也要在預(yù)算范圍內(nèi)異常率越低越好一旦有循環(huán)或者超時必須能兜底這些閾值是參考。不同業(yè)務(wù)差異很大客服場景更看重延遲后臺自動化任務(wù)更看重成本和穩(wěn)定性。定閾值有個好處不會因為某個模型在某條任務(wù)上表現(xiàn)特別好就忽略整體風(fēng)險。如果一個模型完成率只低 1 個點但異常率明顯更低我會更傾向選擇它。因為生產(chǎn)環(huán)境里穩(wěn)定兜底比偶發(fā)的“超水平發(fā)揮”更值錢。5. 常見坑與排查鏈路輸出解析、超時、上下文、并發(fā)5.1 模型回復(fù)了但 Agent 沒有執(zhí)行這是切換模型后最常見的現(xiàn)象。表面上看兩個模型都“回答”了。但 Agent 執(zhí)行起來一個正常執(zhí)行另一個根本沒走到工具調(diào)用。問題往往出在工具調(diào)用的返回結(jié)構(gòu)上。不同模型 API 的返回字段可能有差異有的把工具調(diào)用放在頂層字段有的嵌套在其他結(jié)構(gòu)里。排查順序建議先看原始返回體確認 tool_calls 是否存在再看自己解析邏輯用的字段名和返回體結(jié)構(gòu)是否一致再看工具描述是否有特殊字符或 schema 與模型不兼容最后看執(zhí)行器日志確認工具調(diào)用有沒有真正觸發(fā)不要一開始就改系統(tǒng)提示詞。很多“解析失敗”不是模型不會而是代碼只兼容了原來模型的返回結(jié)構(gòu)。5.2 同一條任務(wù)多次結(jié)果不一致這個問題很容易讓人誤判成“新模型不穩(wěn)定”。需要先確認一個參數(shù)temperature。如果兩個模型默認值不一樣結(jié)果差異會很大。評估時最好把 temperature 固定成同一個值想做嚴格對比時可以先設(shè) 0。如果溫度已經(jīng)固定多次結(jié)果仍然不穩(wěn)定那就要看任務(wù)本身。比如用戶輸入本身有歧義或者工具返回內(nèi)容不完整。這種情況下兩條不同結(jié)果可能都有一定合理性不能簡單說誰對誰錯。評估記錄里最好把模型原始回復(fù)都保留。這樣出現(xiàn)不一致時可以對比具體是哪一步開始分叉。5.3 上下文太長被截斷關(guān)鍵信息后段丟失Agent 多輪任務(wù)很容易把上下文撐大。尤其是一些工具返回內(nèi)容很多的場景比如查詢大列表、讀取長文檔、拉取報表數(shù)據(jù)。模型上下文有上限。一旦超過可能有幾種表現(xiàn)直接報錯、截斷前文、只保留最后的對話但是丟失早期工具結(jié)果、輸出質(zhì)量突然下降。排查時先看請求里實際發(fā)送的 token 數(shù)。很多日志系統(tǒng)只記錄了用戶輸入長度沒有記錄工具返回拼接后的長度。Agent 場景里工具返回往往是上下文膨脹的主因。處理思路一般有幾種對大的工具返回做摘要而不是全量塞進上下文清理無用的歷史輪次只保留關(guān)鍵結(jié)果擴大模型上下文窗口但要注意成本會上升把長內(nèi)容落到外部存儲只傳引用信息給模型這類問題在 sonnet 上可能不明顯換成 deepseek v4 flash 后突然變多不一定是模型理解能力變差很可能是兩個模型對超長上下文的處理策略不同。5.4 批量跑批出現(xiàn)超時、限流、OOM全量跑批時最容易踩的是資源問題。先看單請求耗時。如果單請求已經(jīng)要 10 秒并發(fā)開到 10資源消耗就會急劇上升。Agent 一個任務(wù)可能調(diào)用多個工具也就是多次請求所以真正要關(guān)注的是“單任務(wù)耗時”而不是“單次請求耗時”。遇到限流或 5xx先做退避重試不要繼續(xù)加并發(fā)。遇到限流先退避重試不要繼續(xù)加并發(fā)。如果本地跑批內(nèi)存占用高常見原因是把每個任務(wù)的完整日志都堆在內(nèi)存里再統(tǒng)一寫入。更好的做法是每跑完一條任務(wù)就立即寫入文件或數(shù)據(jù)庫只保留最近幾條在內(nèi)存里。超時還需要區(qū)分“單次模型請求超時”和“整條任務(wù)超時”。我一般會給單次請求設(shè)置一個較長的超時給整條任務(wù)設(shè)置最大輪數(shù)和總時長上限避免一個失敗任務(wù)掛住整個隊列。如果任務(wù)日志里出現(xiàn)了類似agent execution terminated due to error的結(jié)束原因先看是不是最大輪數(shù)觸頂再繼續(xù)追具體在哪一步報錯。6. 切到生產(chǎn)環(huán)境的幾步灰度、監(jiān)控、回滾6.1 灰度先讓一小部分流量替大家踩坑評估結(jié)果再好看也不能直接全量切。更穩(wěn)妥的做法是先把新模型掛在灰度開關(guān)后面。比如只對內(nèi)部測試賬號開放或者只放 5% 的流量。灰度期間不要同時改其他東西。如果同一時間既換了模型又改了工具描述又改了流程腳本后面出了問題根本說不清是誰引起的?;叶绕陂g不要同時改其他東西?;叶确秶梢月糯?% → 20% → 50% → 100%。每一步都觀察一段時間不要只跑半小時就放大。如果項目有平臺層配置建議把模型名、temperature、max_rounds 這些都做成可動態(tài)配置的項。這樣灰度時只需要改配置不需要重新發(fā)布代碼。6.2 監(jiān)控Agent 層和生產(chǎn)層指標要分開看常規(guī) API 監(jiān)控只能看到請求狀態(tài)碼和延遲看不到 Agent 是否真的把任務(wù)完成了。所以最好在建監(jiān)控時加幾類 Agent 層指標整體完成率平均輪次工具調(diào)用失敗率異常結(jié)束原因分布超時、循環(huán)、解析失敗、用戶取消等每類任務(wù)的完成率變化日志里一定要帶 model 標識。沒有模型標識線上對比就無從談起。同一個任務(wù) ID 的全過程日志也要能串聯(lián)起來方便從用戶請求追到每一步工具調(diào)用。6.3 回滾先把服務(wù)恢復(fù)再追原因最后一個建議是回滾動作要足夠快。我見過不少團隊在灰度發(fā)現(xiàn)問題時第一反應(yīng)是打開日志分析原因結(jié)果用戶持續(xù)受影響。更合理的順序是先切回舊模型等服務(wù)恢復(fù)再回頭從日志和評估數(shù)據(jù)里找問題?;貪L開關(guān)最好提前放到配置中心避免臨時改代碼發(fā)布。切回舊模型后再把新舊兩個模型這段時間的日志拉到一起對比確認是不是新模型導(dǎo)致的問題。如果確認不是可以再進入下一輪灰度。切模型不是換一行配置更像是給 Agent 做一次體檢。真正要盯的不是單條回答有多好而是任務(wù)鏈路能不能穩(wěn)定走完。先積累評估集和跑批工具以后換任何模型都能少踩一半坑。