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