化:用Harness Engineering構(gòu)建穩(wěn)定之橋)
上個(gè)月幫一個(gè)團(tuán)隊(duì)把內(nèi)部的數(shù)據(jù)查詢助手從Demo接進(jìn)生產(chǎn)第一周就崩了六次。不是模型變笨了是系統(tǒng)層面根本沒(méi)準(zhǔn)備好工具調(diào)用超時(shí)、上下文塞爆、同一個(gè)問(wèn)題復(fù)現(xiàn)不了、模型偶爾抽風(fēng)輸出一個(gè)空J(rèn)SON直接把下游任務(wù)干掛了。那幾天我一直在想一個(gè)問(wèn)題——為什么Demo階段明明很順一上生產(chǎn)就到處冒煙答案其實(shí)不復(fù)雜Demo驗(yàn)證的是“模型能不能做這件事”生產(chǎn)考驗(yàn)的是“整個(gè)系統(tǒng)能不能穩(wěn)定地讓模型把這件事做完”。這中間隔著一整層工程我習(xí)慣把它叫做Harness Engineering也就是給AI Agent的智能能力裝上韁繩、護(hù)具和儀表盤的那套工程體系。這篇文章就圍繞這個(gè)名字展開(kāi)講講從Demo到生產(chǎn)到底差在哪幾步、每一步具體怎么落地。如果你是剛跑通第一個(gè)Agent原型、正要往生產(chǎn)推的工程師或者已經(jīng)在生產(chǎn)里被Agent折騰過(guò)幾輪、想系統(tǒng)化梳理一下方案這篇應(yīng)該能幫上忙。我會(huì)盡量用具體的配置、代碼和踩坑記錄來(lái)講不寫空話。1. Demo能跑和能穩(wěn)定生產(chǎn)中間隔著一整層工程1.1 一個(gè)Demo跑通只需要三條“好消息”我自己跑通第一個(gè)Agent的時(shí)候心里想的全是三個(gè)正反饋模型會(huì)調(diào)用工具了、流程走通了、輸出看起來(lái)有模有樣。這三個(gè)好消息確實(shí)能撐起一個(gè)Demo但充其量只是證明了一條理想路徑能被走通。理想路徑是什么是模型在正確的時(shí)機(jī)調(diào)用正確的工具、工具返回了干凈的數(shù)據(jù)、模型據(jù)此給出了正確的答案、用戶恰好沒(méi)有提出邊界問(wèn)題、網(wǎng)絡(luò)和接口都穩(wěn)定如絲。Demo階段的運(yùn)氣成分極大因?yàn)槟愀緵](méi)有把系統(tǒng)置于“壞環(huán)境”里考察過(guò)。到了生產(chǎn)環(huán)境模型面對(duì)的是嘈雜的輸入、不完整的工具返回、用戶不會(huì)再按你的腳本提問(wèn)。這個(gè)時(shí)候你會(huì)陸續(xù)收到一堆壞消息某個(gè)時(shí)間點(diǎn)接口變慢導(dǎo)致Agent卡死、用戶上下文太長(zhǎng)導(dǎo)致費(fèi)用飆升、模型突然不按工具契約輸出而是開(kāi)始自由發(fā)揮、重試機(jī)制把同一個(gè)寫操作重復(fù)執(zhí)行了三次。這些基本都不在Demo的考察范圍內(nèi)卻都是生產(chǎn)事故的主力來(lái)源。1.2 生產(chǎn)環(huán)境對(duì)Agent的真正考察項(xiàng)我一般用一個(gè)簡(jiǎn)單的對(duì)照表來(lái)跟團(tuán)隊(duì)解釋Demo和生產(chǎn)之間的差距。每次Review都用這張表過(guò)一遍它已經(jīng)變成我們項(xiàng)目評(píng)審的標(biāo)準(zhǔn)動(dòng)作考察維度Demo階段的通常狀態(tài)生產(chǎn)環(huán)境的要求成功路徑只驗(yàn)證理想路徑驗(yàn)證成功路徑、失敗路徑、邊界路徑輸入分布自己手工準(zhǔn)備的正例真實(shí)用戶分布包含臟數(shù)據(jù)、多輪歧義執(zhí)行穩(wěn)定性偶發(fā)成功即可演示95%以上的請(qǐng)求成功且可復(fù)現(xiàn)工具調(diào)用工具總是可用且快工具會(huì)慢、會(huì)錯(cuò)、會(huì)返回臟數(shù)據(jù)上下文管理單輪或短輪不關(guān)注Token多輪、超長(zhǎng)上下文有成本預(yù)算約束可觀測(cè)性打印模型文本即可需要追蹤完整軌跡、歸因和復(fù)盤安全護(hù)欄無(wú)需超時(shí)、預(yù)算、鑒權(quán)、兜底切換發(fā)布變更重新運(yùn)行Notebook即可需要灰度、版本管理和回滾你會(huì)發(fā)現(xiàn)生產(chǎn)環(huán)境真正考察的不是模型智商而是系統(tǒng)的工程韌性。這種韌性不會(huì)自動(dòng)出現(xiàn)只能靠明確的設(shè)計(jì)和測(cè)試去構(gòu)建這就是我把Harness Engineering當(dāng)作必修課的原因。1.3 為什么傳統(tǒng)后端工程的思維在這里部分失靈做過(guò)后端服務(wù)的人會(huì)習(xí)慣性地想Agent就是“編排層加上模型API調(diào)用”那我用常規(guī)的微服務(wù)思路來(lái)處理不就完了這個(gè)思路對(duì)了一半但有一塊核心差異很容易被忽略傳統(tǒng)后端里控制流是開(kāi)發(fā)者在代碼里寫死的而在Agent里控制流是模型在運(yùn)行時(shí)動(dòng)態(tài)生成的。這個(gè)差異帶來(lái)了兩個(gè)連鎖后果。第一你的代碼不再完全決定行為走向模型可能走出一條你沒(méi)預(yù)料到的執(zhí)行路徑。第二系統(tǒng)里最難排查的問(wèn)題從“哪里邏輯寫錯(cuò)了”變成“模型為什么在某個(gè)語(yǔ)境下做了這個(gè)決定”。后者的可復(fù)現(xiàn)性很差可能換個(gè)會(huì)話、調(diào)換一下上下文順序同樣的調(diào)用就走向了不同的分支。所以Harness Engineering的核心目標(biāo)不是“控制模型的每一個(gè)token”而是在模型自由度的周圍建立一套約束和響應(yīng)機(jī)制。就像騎馬你不可能控制馬腿的每一步肌肉運(yùn)動(dòng)但你能控制韁繩、馬鐙、馬鞍通過(guò)這套“騎具”穩(wěn)定方向、保持平衡、及時(shí)停下。工程體系的本質(zhì)就是這套圍繞模型建立的騎具。2. Harness Engineering到底是什么給AI能力裝上“韁繩與儀表盤”2.1 名字的來(lái)由和邊界Harness這個(gè)詞在工程領(lǐng)域并不陌生。早期軟件測(cè)試?yán)锞陀衪est harness指的是測(cè)試夾具把被測(cè)對(duì)象架起來(lái)、喂入輸入、抓取輸出、匯報(bào)結(jié)果的那套支撐結(jié)構(gòu)。把這個(gè)概念遷移到AI Agent上Harness Engineering就成了包裹在模型能力外面的整層工程設(shè)施。這層設(shè)施做什么我傾向于給出一個(gè)覆蓋關(guān)系它把Agent從“一個(gè)會(huì)調(diào)用工具的模型”變成“一個(gè)可以被管理、被評(píng)估、被控制、被觀測(cè)的生產(chǎn)組件”。具體拆成四件事對(duì)應(yīng)的就是下面要展開(kāi)的內(nèi)容。第一是可靠性。通過(guò)執(zhí)行循環(huán)設(shè)計(jì)、重試和降級(jí)保證長(zhǎng)鏈路任務(wù)在真實(shí)環(huán)境下盡量穩(wěn)定。第二是可評(píng)估。建立評(píng)測(cè)集和回歸機(jī)制讓每次模型或提示詞改動(dòng)都可以量化判斷好壞。第三是可控制。通過(guò)超時(shí)、預(yù)算、并發(fā)限流和人在回路讓系統(tǒng)在最壞情況下仍然有兜底動(dòng)作。第四是可觀測(cè)。把模型的每一步推理、工具調(diào)用和內(nèi)部狀態(tài)變成日志和指標(biāo)出了問(wèn)題能定位、能歸因。這四個(gè)能力不是可選增強(qiáng)而是生產(chǎn)級(jí)Agent的底線。Demo里模型發(fā)揮失常你重跑一次就行生產(chǎn)里模型發(fā)揮失常影響的是業(yè)務(wù)和用戶信任你不能靠“重跑”來(lái)交差。2.2 它解決的問(wèn)題域和框架、提示詞工程的分工有些朋友會(huì)問(wèn)這些事難道LangChain、Semantic Kernel這類框架沒(méi)做嗎框架確實(shí)提供了很多編排能力比如Agent循環(huán)、工具注冊(cè)、記憶組件用起來(lái)能省很多時(shí)間。但我的經(jīng)驗(yàn)是框架解決的是“怎么搭”Harness Engineering解決的是“怎么?!?。打個(gè)比方框架給你一輛配置齊全的車Harness是你要給它裝上的安全帶、氣囊、行車記錄儀和維修保養(yǎng)計(jì)劃。車本身不錯(cuò)但上不上市、能不能長(zhǎng)期可靠運(yùn)行取決于你裝了哪些保護(hù)設(shè)施。反過(guò)來(lái)Harness Engineering也不該去搶提示詞工程的工作。提示詞工程優(yōu)化的是“模型輸出的質(zhì)量”Harness優(yōu)化的是“系統(tǒng)對(duì)模型輸出的處理能力”。兩者有交疊但重點(diǎn)不同一個(gè)在思考層面發(fā)力一個(gè)在執(zhí)行和反饋層面發(fā)力。真正成熟的分工是提示詞讓模型盡量少犯錯(cuò)Harness讓模型即使犯錯(cuò)系統(tǒng)也能把損失控制在一定范圍內(nèi)。2.3 判定Harness做得好不好的三個(gè)信號(hào)做了幾輪生產(chǎn)改造之后我總結(jié)出三個(gè)說(shuō)明Harness做得比較到位的信號(hào)。第一個(gè)信號(hào)是失敗可以被routine地處理。新出現(xiàn)的失敗模式很快就能歸入已有的重試、降級(jí)、兜底或告警分類里而不是每次都像第一次遇到那樣手足無(wú)措。第二個(gè)信號(hào)是上線改動(dòng)不再手心出汗。提示詞、模型版本、工具實(shí)現(xiàn)都可以灰度放量用數(shù)據(jù)和評(píng)測(cè)說(shuō)話而不是靠“我覺(jué)得沒(méi)問(wèn)題”。第三個(gè)信號(hào)是事故能夠被復(fù)盤和歸因。出事后你能講清楚“哪個(gè)環(huán)節(jié)出了問(wèn)題、當(dāng)時(shí)系統(tǒng)的狀態(tài)是什么、為什么做出那個(gè)決定”而不是只能籠統(tǒng)地說(shuō)“模型抽風(fēng)了”。這三個(gè)信號(hào)同時(shí)出現(xiàn)意味著Harness Engineering基本成型了。下面從執(zhí)行循環(huán)開(kāi)始講具體怎么造橋。3. 第一道橋墩?qǐng)?zhí)行循環(huán)的可靠性加固3.1 把一次性長(zhǎng)鏈拆成可重試的短步驟Agent的執(zhí)行循環(huán)通常長(zhǎng)這樣模型接收任務(wù)規(guī)劃一系列動(dòng)作逐個(gè)調(diào)用工具根據(jù)工具結(jié)果繼續(xù)推理直到完成。問(wèn)題是這個(gè)循環(huán)里的任何一步失敗整個(gè)鏈就可能斷。我踩過(guò)最典型的一個(gè)坑是讓模型依次調(diào)用三個(gè)工具才能給出最終答案結(jié)果第二個(gè)工具返回超時(shí)整個(gè)任務(wù)直接失敗。Demo里不會(huì)遇到這種問(wèn)題因?yàn)楣ぞ叨荚诒镜?、?shù)據(jù)量小、網(wǎng)絡(luò)通暢生產(chǎn)里這是家常便飯。解決思路是給每一步一個(gè)明確的“狀態(tài)邊界”。我在設(shè)計(jì)工具調(diào)用層時(shí)要求每一步操作要么成功、要么失敗絕不允許出現(xiàn)半成功、半失敗的狀態(tài)。舉例來(lái)說(shuō)一個(gè)工具先寫數(shù)據(jù)庫(kù)再通知下游就必須把“寫數(shù)據(jù)庫(kù)”和“通知下游”拆成兩個(gè)獨(dú)立調(diào)用或者用事務(wù)保證原子性。這樣重試就安全了失敗時(shí)重放同一個(gè)步驟不會(huì)產(chǎn)生重復(fù)副作用。這一步做完執(zhí)行循環(huán)就從“一條脆弱的邏輯鏈”變成了“一串可以單獨(dú)重放的短步驟”??煽啃蕴嵘幕A(chǔ)是這個(gè)。3.2 給每個(gè)工具寫“契約”而不是寫“說(shuō)明”框架里注冊(cè)工具通常就是傳一個(gè)函數(shù)、加一段描述模型通過(guò)描述理解該不該調(diào)用這個(gè)工具。我的經(jīng)驗(yàn)是描述只能解決“模型愿不愿意調(diào)用”解決不了“調(diào)用之后系統(tǒng)怎么處理結(jié)果”。我們項(xiàng)目的做法是給每個(gè)工具維護(hù)一份契約文檔核心包括輸入?yún)?shù)的JSON Schema、輸出結(jié)果的結(jié)構(gòu)約定、錯(cuò)誤碼和錯(cuò)誤信息約定、副作用說(shuō)明、超時(shí)閾值。模型看到的說(shuō)明是把契約翻譯成自然語(yǔ)言的版本而系統(tǒng)層拿契約做解析、校驗(yàn)和報(bào)錯(cuò)映射。舉個(gè)例子有一個(gè)內(nèi)部查詢工具返回結(jié)果可能是“查詢成功數(shù)據(jù)為空”、“查詢失敗權(quán)限不足”、“查詢失敗依賴接口超時(shí)”三種情況。模型如果只看到“返回查詢結(jié)果”這句描述它根本沒(méi)有辦法區(qū)分這三種情況背后應(yīng)該怎么決策。有了契約和錯(cuò)誤映射模型才能知道“權(quán)限不足”時(shí)要跟用戶解釋而不是重試三遍。我甚至?xí)殃P(guān)鍵的契約寫進(jìn)系統(tǒng)提示詞里讓模型在決策時(shí)就能看到邊界。寫作時(shí)保持簡(jiǎn)短比如“工具查詢失敗時(shí)如果是超時(shí)錯(cuò)誤可以重試一次如果是權(quán)限錯(cuò)誤請(qǐng)直接告知用戶缺少權(quán)限。”這種約束在Demo里看不出價(jià)值在生產(chǎn)里能讓很多無(wú)效循環(huán)提前終止。3.3 模型輸出到系統(tǒng)指令之間需要翻譯器模型并不總是會(huì)嚴(yán)格按照你規(guī)定的JSON結(jié)構(gòu)輸出。尤其在你讓它自由規(guī)劃、自己決定下一步Action的時(shí)候偶爾會(huì)冒出來(lái)多一個(gè)字段、少一個(gè)逗號(hào)、把字符串寫成了數(shù)組等格式錯(cuò)誤。傳統(tǒng)做法是把這個(gè)原始輸出直接丟給下游結(jié)果下游一解析報(bào)錯(cuò)整個(gè)流程就斷了。我采用的方案是加一個(gè)解析翻譯層。模型輸出先經(jīng)過(guò)一個(gè)輕量級(jí)的解析器把它整理成標(biāo)準(zhǔn)化的指令對(duì)象。解析器要做三件事第一是格式修正比如提取被代碼塊包裹的JSON、修復(fù)明顯的語(yǔ)法問(wèn)題第二是字段映射把同義字段名統(tǒng)一到標(biāo)準(zhǔn)字段第三是置信度判斷如果解析結(jié)果與預(yù)期結(jié)構(gòu)偏差過(guò)大不強(qiáng)行使用而是觸發(fā)生成解析失敗的提示要求模型重新輸出或者直接降級(jí)為安全回復(fù)。這個(gè)翻譯層的價(jià)值不僅僅是讓流程不崩更在于它給系統(tǒng)一個(gè)“可控的失敗點(diǎn)”。失敗被集中在這里就可以針對(duì)性地retry或fallback而不是讓莫名其妙的格式錯(cuò)誤跑到業(yè)務(wù)的各個(gè)角落去爆炸。3.4 超時(shí)與重試的邊界條件關(guān)于超時(shí)我給自己定過(guò)一條非常簡(jiǎn)單的原則沒(méi)有超時(shí)的環(huán)節(jié)就是生產(chǎn)事故的預(yù)留位置。模型的推理調(diào)用要設(shè)超時(shí)工具調(diào)用要設(shè)超時(shí)整個(gè)Agent的一輪執(zhí)行也要設(shè)總超時(shí)。這幾個(gè)超時(shí)是層層收縮的類似TCP的超時(shí)和重傳。具體參數(shù)上我們會(huì)對(duì)不同工具單獨(dú)配置。比如本地?cái)?shù)據(jù)庫(kù)查詢一般2秒沒(méi)回來(lái)就很可疑我會(huì)給3秒超時(shí)、允許重試1次外部API調(diào)用會(huì)留到5秒因?yàn)榫W(wǎng)絡(luò)抖動(dòng)存在但重試要加指數(shù)退避第一次失敗等500毫秒第二次等1.5秒最多3次。這里有一個(gè)特別重要的坑重試不能對(duì)冪等之外的請(qǐng)求無(wú)腦使用。如果工具調(diào)用有副作用比如扣費(fèi)、發(fā)消息、創(chuàng)建資源重試一次就等于把同樣的副作用執(zhí)行兩次。所以我會(huì)在工具契約里顯式標(biāo)注是否冪等不冪等的操作只能靠人工介入或異步確認(rèn)去兜底絕不在Agent內(nèi)部自動(dòng)重試。這塊想清楚重試機(jī)制才真正安全。4. 第二道橋墩上下文與記憶的工程化治理4.1 Token不是游客記憶需要分層你可能會(huì)好奇上下文治理有什么好講的不就是把歷史消息拼在一起喂給模型嗎這么做在短會(huì)話里確實(shí)能跑但生產(chǎn)環(huán)境里用戶的會(huì)話可能長(zhǎng)達(dá)幾十輪中間穿插著工具調(diào)用結(jié)果、臨時(shí)文件內(nèi)容、用戶中途修改的需求。全塞進(jìn)上下文幾個(gè)問(wèn)題立刻找上來(lái)費(fèi)用暴漲、響應(yīng)變慢、模型注意力被無(wú)關(guān)信息稀釋。我的做法是把記憶做成分層結(jié)構(gòu)簡(jiǎn)單說(shuō)就是三類記憶分開(kāi)存。長(zhǎng)期記憶存用戶的基本偏好和不變的事實(shí)比如賬號(hào)類型、常用語(yǔ)言、業(yè)務(wù)線的固定配置工作記憶存當(dāng)前任務(wù)相關(guān)的臨時(shí)信息比如正在填寫的表單字段、本次查詢的中間結(jié)果會(huì)話記憶存對(duì)話的歷史消息只保留用于銜接語(yǔ)境的關(guān)鍵內(nèi)容而不是把每句話都堆進(jìn)上下文。分層的意義在于你可以為每一層設(shè)置不同的保留時(shí)長(zhǎng)和Token預(yù)算。長(zhǎng)期記憶每次請(qǐng)求都注入但內(nèi)容很少工作記憶在任務(wù)完成后清理會(huì)話記憶按輪數(shù)或Token上限截?cái)?。這樣既保住了必要的語(yǔ)境信息又不至于讓上下文變成一筆糊涂賬。4.2 上下文壓縮的三個(gè)實(shí)用策略在Token預(yù)算有限的情況下我常用三種壓縮策略它們可以組合使用。第一種是摘要替換。當(dāng)歷史對(duì)話超過(guò)一定長(zhǎng)度時(shí)用一個(gè)摘要節(jié)點(diǎn)替代最早的那些輪次。摘要可以在后臺(tái)異步生成生成完畢后再注入后續(xù)請(qǐng)求。需要注意摘要本身不要寫太詳細(xì)能回答“用戶之前問(wèn)過(guò)什么、結(jié)論是什么、還有什么遺留事項(xiàng)”就夠了寫太細(xì)等于沒(méi)壓縮。第二種是截止窗口。有些歷史信息對(duì)當(dāng)前問(wèn)題已經(jīng)完全沒(méi)有影響比如用戶上一單的配送地址已經(jīng)改掉了。這類信息要主動(dòng)識(shí)別并從上下文中清除而不是“帶著以防萬(wàn)一”。我見(jiàn)過(guò)很多案例是模型因?yàn)樯舷挛睦锏呐f信息而答錯(cuò)信息污染造成的錯(cuò)誤比信息缺失更隱蔽。第三種是檢索增強(qiáng)把完整信息放到向量庫(kù)里只在需要時(shí)才檢索相關(guān)片段放回上下文。這個(gè)方法適合知識(shí)庫(kù)類場(chǎng)景但要控制好檢索結(jié)果的裁剪和去重。壓縮不是無(wú)限砍核心原則是把“上下文”當(dāng)作一種需要管理的資源而不是隨手可以無(wú)限追加的緩沖。4.3 一次因上下文污染引發(fā)的故障排查記錄這里分享一個(gè)具體排查案例。某公司內(nèi)部工單Agent上線后部分用戶的反饋是明明在上一步確認(rèn)了自己的賬號(hào)類型是企業(yè)版下一步模型又開(kāi)始按個(gè)人版的規(guī)則回答。我和團(tuán)隊(duì)花了半天最后定位到原因一個(gè)用戶歷史切換過(guò)賬號(hào)類型舊賬號(hào)類型的信息還躺在會(huì)話記錄里沒(méi)被清理。鏈路是這樣的第一輪用戶說(shuō)“我切換成企業(yè)版了”系統(tǒng)處理完上下文里同時(shí)存在“切換前是個(gè)人版”和“切換后是企業(yè)版”兩條信息。后續(xù)幾輪里模型通過(guò)注意力機(jī)制抓取信息時(shí)偶爾會(huì)命中舊信息導(dǎo)致判斷漂移。修復(fù)方案很簡(jiǎn)單在賬號(hào)切換事件發(fā)生時(shí)主動(dòng)改寫上下文節(jié)點(diǎn)刪除掉與賬號(hào)類型相關(guān)的舊記錄并在摘要節(jié)點(diǎn)里注明“已切換到企業(yè)版”。這個(gè)案例給我一個(gè)啟發(fā)上下文治理不只是Token層面的省錢手段更是模型認(rèn)知一致性的保障。你不主動(dòng)管理上下文里的事實(shí)性信息模型就會(huì)在矛盾證據(jù)里隨機(jī)搖擺而這種搖擺是最難人工追查的。5. 第三道橋墩評(píng)測(cè)體系與回歸護(hù)欄5.1 手工體驗(yàn)測(cè)試的局限性我經(jīng)常跟團(tuán)隊(duì)說(shuō)如果你評(píng)估Agent的改進(jìn)效果靠“自己試了十幾個(gè)問(wèn)題感覺(jué)變好了”那這個(gè)項(xiàng)目還沒(méi)有達(dá)到可以上線改動(dòng)的水平。手工測(cè)試有致命弱點(diǎn)覆蓋量太小、結(jié)果不可復(fù)現(xiàn)、評(píng)估標(biāo)準(zhǔn)不一致。我自己就犯過(guò)這樣的錯(cuò)。改了一版系統(tǒng)提示詞手工測(cè)試了幾個(gè)典型案例覺(jué)得輸出更精煉了心里很滿意。結(jié)果上線后發(fā)現(xiàn)調(diào)用工具的頻率下降了一些需要查數(shù)據(jù)的請(qǐng)求被模型憑“記憶”硬答了。手工測(cè)試時(shí)我沒(méi)注意到這個(gè)偏向因?yàn)槟菐讉€(gè)問(wèn)題恰好不需要工具。這充分說(shuō)明無(wú)評(píng)測(cè)集的改動(dòng)就是在憑感覺(jué)賭博。后來(lái)我們立了一條規(guī)矩任何影響模型行為的改動(dòng)提示詞、工具定義、上下文策略、模型版本都必須過(guò)評(píng)測(cè)集得先出數(shù)字再談上線。5.2 評(píng)測(cè)集應(yīng)該怎么建評(píng)測(cè)集建設(shè)是個(gè)臟活但很值得做。我們起步時(shí)選了三種來(lái)源搭它。第一種是真實(shí)會(huì)話采樣。從生產(chǎn)環(huán)境的日志里按一定比例抽出歷史請(qǐng)求包括成功和失敗的經(jīng)典案例。這些數(shù)據(jù)最真實(shí)能避免你構(gòu)建出和實(shí)際需求脫節(jié)的“理想數(shù)據(jù)”。注意脫敏處理。第二種是人工構(gòu)造的邊界用例。針對(duì)你已知的風(fēng)險(xiǎn)點(diǎn)手工寫案例比如歧義問(wèn)題、多意圖嵌套、工具異常時(shí)的應(yīng)對(duì)請(qǐng)求這些樣例專門用來(lái)測(cè)模型的“抵抗力”。第三種是合成變體。拿真實(shí)案例做模板改動(dòng)里面的實(shí)體、數(shù)字、措辭來(lái)生成更多變體增加覆蓋范圍這種方法成本低特別適合初期擴(kuò)充規(guī)模。評(píng)測(cè)的維度不要只盯著“答案對(duì)不對(duì)”。我常用五維評(píng)估任務(wù)完成度看核心目標(biāo)有沒(méi)有達(dá)成工具選擇正確率看該調(diào)用的工具是否調(diào)了、不該調(diào)的是否忍住輸出結(jié)構(gòu)合規(guī)率看格式和字段是否符合契約浪費(fèi)程度看是否走了不必要的冗余步驟安全表現(xiàn)看是否說(shuō)了越權(quán)或離譜的話。每個(gè)維度都要有明確定義和打分標(biāo)準(zhǔn)盡量讓兩個(gè)評(píng)估者打分的結(jié)果基本一致。5.3 如何把評(píng)測(cè)接進(jìn)發(fā)布流程評(píng)測(cè)建好之后接下來(lái)是把評(píng)測(cè)從“跑一次看結(jié)果”變成“發(fā)布流程的關(guān)卡”。我用的是三級(jí)門檻機(jī)制?;A(chǔ)門檻是自動(dòng)化跑一遍核心評(píng)測(cè)集要求任務(wù)完成度不低于某個(gè)閾值比如90%。第二個(gè)門檻是差異對(duì)比新版本和線上版本各跑一遍相同評(píng)測(cè)集比較各維度優(yōu)劣。模型行為是多變的允許有些指標(biāo)略降尤其是那些能換來(lái)響應(yīng)速度或成本大幅改善的提升比都可以接受但要人來(lái)看、要記錄下原因。第三個(gè)門檻是線上灰度的小流量驗(yàn)證用真實(shí)流量在看板指標(biāo)上跑一段時(shí)間再放量。這套機(jī)制跑通之后團(tuán)隊(duì)的信心會(huì)明顯不一樣。改動(dòng)上線不再依賴“某開(kāi)發(fā)哥覺(jué)得好”而是有一套可追溯的評(píng)估鏈條。這個(gè)習(xí)慣本身也是從Demo思維轉(zhuǎn)向生產(chǎn)思維的重要標(biāo)志。6. 第四道橋墩成本、并發(fā)與人在回路6.1 Token預(yù)算與并發(fā)控制生產(chǎn)環(huán)境里成本不是事后統(tǒng)計(jì)的而是事前要鎖死的。我一般會(huì)給每個(gè)會(huì)話和每個(gè)用戶分別設(shè)置Token預(yù)算會(huì)話級(jí)預(yù)算是控制單次任務(wù)不失控比如一個(gè)復(fù)雜任務(wù)最多消耗30萬(wàn)Token超過(guò)就強(qiáng)制收斂或終止用戶級(jí)預(yù)算是防止某個(gè)高頻用戶在整體成本上造成沖擊。模型API的調(diào)用也需要并發(fā)控制。Demo里單線程調(diào)用并發(fā)問(wèn)題不會(huì)出現(xiàn)生產(chǎn)里有多個(gè)用戶同時(shí)使用如果一個(gè)用戶的任務(wù)內(nèi)部包含20個(gè)串行步驟那么10個(gè)并發(fā)用戶就會(huì)在中間環(huán)節(jié)堆積大量待處理請(qǐng)求。不加并發(fā)限制可能一瞬間打爆下游接口的負(fù)載。我常用的做法是給Agent接入通用信號(hào)量機(jī)制限制同時(shí)進(jìn)行的模型調(diào)用數(shù)量加上基于令牌桶的請(qǐng)求速率限制。限流策略不會(huì)讓單個(gè)請(qǐng)求變快但它能讓整體服務(wù)穩(wěn)定不雪崩。這個(gè)往往不是第一次上線就做而是出了接口占用率告警后才補(bǔ)建議一開(kāi)始就規(guī)劃好。6.2 人在回路與緊急剎車并不是所有任務(wù)都能完全自動(dòng)化。對(duì)于高風(fēng)險(xiǎn)操作比如刪除數(shù)據(jù)、批量發(fā)消息、修改核心配置我堅(jiān)持引入人在回路Agent可以生成建議但執(zhí)行前必須經(jīng)過(guò)人工確認(rèn)。實(shí)現(xiàn)上就是在執(zhí)行鏈路上加一個(gè)“暫停”節(jié)點(diǎn)將待審批的Action轉(zhuǎn)成審核任務(wù)等待人工返回后才繼續(xù)。另一種兜底是“緊急剎車”開(kāi)關(guān)也就是全局熔斷。當(dāng)某類錯(cuò)誤連續(xù)出現(xiàn)或請(qǐng)求成功率跌到閾值之下系統(tǒng)自動(dòng)暫停受影響鏈路的執(zhí)行轉(zhuǎn)入降級(jí)模式或直接返回人為兜底提示。這個(gè)開(kāi)關(guān)平時(shí)不應(yīng)該被觸發(fā)但一旦出現(xiàn)異常它能保住系統(tǒng)和數(shù)據(jù)不至于被帶崩。6.3 可觀測(cè)性與版本管理生產(chǎn)運(yùn)維里你至少需要三類數(shù)據(jù)來(lái)回答“剛才發(fā)生了什么”。第一是軌跡日志記錄每一步模型輸入輸出、工具調(diào)用參數(shù)和結(jié)果、耗時(shí)與Token消耗第二是聚合指標(biāo)包括請(qǐng)求成功率、平均響應(yīng)時(shí)長(zhǎng)、單會(huì)話Token消耗、工具調(diào)用失敗率第三是事故事件也就是那些觸發(fā)了重試、降級(jí)、熔斷或人工審核的關(guān)鍵節(jié)點(diǎn)。這些信息光記錄還不行還要能高效檢索。排查時(shí)候我最常做的事就是輸入一個(gè)會(huì)話ID按時(shí)間線回放Agent到底做了哪些決策。沒(méi)有軌跡日志這件事幾乎不可能完成只能靠復(fù)現(xiàn)和猜。版本管理同樣重要。一個(gè)Agent版本不只包含模型版本還包括提示詞、工具契約、上下文策略和評(píng)測(cè)結(jié)果的組合。我們上線時(shí)會(huì)對(duì)這一整套打一個(gè)版本標(biāo)簽這樣線上出了問(wèn)題能精準(zhǔn)回滾到某個(gè)穩(wěn)定版本而不是逐個(gè)配置文件去找。7. 一個(gè)案例數(shù)據(jù)查詢Agent從Demo到生產(chǎn)的完整改造7.1 原版Demo的問(wèn)題清單為了把這些方法論串起來(lái)我拆一個(gè)實(shí)際幫團(tuán)隊(duì)改造的例子是一個(gè)內(nèi)部數(shù)據(jù)查詢助手。最初版本Demo做得挺漂亮用戶用自然語(yǔ)言提問(wèn)Agent判斷需要查哪張寬表、調(diào)用查詢接口、給出數(shù)據(jù)摘要。團(tuán)隊(duì)覺(jué)得可以加真實(shí)用戶了找我做了一次上線前體檢開(kāi)出來(lái)的問(wèn)題清單是這樣的工具調(diào)用沒(méi)有總超時(shí)某個(gè)聚合查詢慢的時(shí)候整個(gè)會(huì)話會(huì)卡到用戶放棄工具描述寫得太簡(jiǎn)略模型經(jīng)常分不清“按日匯總”和“按周匯總”該調(diào)用哪個(gè)參數(shù)上下文全量保留用戶多問(wèn)十幾個(gè)問(wèn)題后Token消耗直接翻倍沒(méi)有任何評(píng)測(cè)集團(tuán)隊(duì)說(shuō)“效果不錯(cuò)”的依據(jù)是手動(dòng)測(cè)試了二十個(gè)問(wèn)句查詢失敗時(shí)模型只會(huì)原樣報(bào)錯(cuò)誤碼用戶根本看不懂。問(wèn)題不少但每一條都在Harness的覆蓋范圍內(nèi)改起來(lái)有章法。7.2 改造步驟與效果改造分四步推進(jìn)。第一步加固執(zhí)行層。給查詢工具加上3秒超時(shí)超時(shí)后返回標(biāo)準(zhǔn)錯(cuò)誤系統(tǒng)把它映射為“查詢超時(shí)請(qǐng)稍后再試”的回復(fù)模板模型側(cè)重試邏輯調(diào)整為最多一次加了退避。同時(shí)把查詢接口按冪等性標(biāo)注清楚只對(duì)冪等查詢開(kāi)啟自動(dòng)重試。第二步重寫工具契約。查詢工具的輸入?yún)?shù)改成結(jié)構(gòu)化Schema并明確區(qū)分“時(shí)間粒度”“維度字段”“過(guò)濾條件”三個(gè)獨(dú)立參數(shù)最關(guān)鍵是給模型提供錯(cuò)誤碼到用戶話術(shù)的映射表。權(quán)限不足、數(shù)據(jù)為空、接口超時(shí)三種情況的回復(fù)策略在提示詞里寫明防止模型在不該重試的場(chǎng)景下反復(fù)請(qǐng)求。第三步做評(píng)測(cè)集和回歸。從歷史查詢?nèi)罩纠锍榱?0條真實(shí)問(wèn)題手工構(gòu)造了20條邊界問(wèn)題包括“查詢條件互相矛盾”“用戶一次性問(wèn)了三個(gè)指標(biāo)”“表格不存在”等。跑完評(píng)測(cè)后發(fā)現(xiàn)工具選擇準(zhǔn)確率從改造前的60%左右提升到85%以上浪費(fèi)Token的平均值下降了約一半。第四步上線灰度。先在內(nèi)部群邀請(qǐng)20個(gè)重度用戶試用一周看軌跡日志里是否有新的失敗模式之后擴(kuò)大到20%流量最終全量。全程開(kāi)著超時(shí)告警和評(píng)測(cè)回歸任何一次改動(dòng)都先過(guò)一遍評(píng)測(cè)集再放量。7.3 改造過(guò)程中最容易忽略的兩個(gè)細(xì)節(jié)這個(gè)項(xiàng)目里有兩個(gè)細(xì)節(jié)我印象很深。第一個(gè)工具返回的“數(shù)據(jù)為空”和“查詢結(jié)果沒(méi)有命中任何記錄”在模型眼里是兩件事寫契約時(shí)必須顯式區(qū)分否則模型會(huì)開(kāi)始強(qiáng)行編造“沒(méi)有數(shù)據(jù)時(shí)存在的趨勢(shì)”。第二個(gè)提示詞里明確要求模型“當(dāng)查詢失敗時(shí)用清晰的話術(shù)告訴用戶而不是展示原始錯(cuò)誤代碼”。這個(gè)約束看著很簡(jiǎn)單但如果沒(méi)有顯式寫明模型默認(rèn)會(huì)傾向于把原始報(bào)錯(cuò)信息原封不動(dòng)拋給用戶。評(píng)測(cè)集里加了兩條“接口超時(shí)”的用例就是為了盯住這個(gè)行為。這些細(xì)節(jié)不是理論推出來(lái)的都是改造過(guò)程中逐步暴露、逐步補(bǔ)上的也是Harness Engineering要有評(píng)測(cè)集兜底的原因。8. 我在幾次生產(chǎn)事故之后學(xué)到的事經(jīng)歷這些之后我對(duì)AI Agent生產(chǎn)化有了幾個(gè)比較踏實(shí)的認(rèn)知。第一個(gè)認(rèn)知是穩(wěn)定性不是加幾個(gè)防御性代碼就能解決的它來(lái)自一整套成體系的設(shè)計(jì)。超時(shí)、重試、契約、評(píng)測(cè)、預(yù)算、可觀測(cè)這些環(huán)節(jié)少一塊短期內(nèi)可能沒(méi)感覺(jué)長(zhǎng)期一定會(huì)在某個(gè)深夜變成告警電話。第二個(gè)認(rèn)知是模型的能力會(huì)持續(xù)變強(qiáng)但Harness這部分不會(huì)自動(dòng)變好。模型升級(jí)了你的評(píng)測(cè)集和工具契約需要跟著動(dòng)場(chǎng)景變了你的預(yù)算策略和上下文策略也要重新審視。工程體系的維護(hù)和模型的迭代是并行推進(jìn)的缺一不可。最后再分享一個(gè)個(gè)人體會(huì)不要把Agent當(dāng)成一個(gè)黑盒去“誠(chéng)心祈禱”一定要把它當(dāng)成一個(gè)你隨時(shí)可以拆開(kāi)、可以控制、可以反問(wèn)的系統(tǒng)來(lái)設(shè)計(jì)。多想想“這里如果失敗會(huì)怎樣”“這一步用戶會(huì)怎么看”“這個(gè)決策為什么這樣做”你就是在做Harness Engineering了。這些東西并不性感但正是它們把一個(gè)“驚艷的演示”變成了一個(gè)“每天都能穩(wěn)定交付價(jià)值的產(chǎn)品”。如果你正準(zhǔn)備把Agent從Demo推向生產(chǎn)我建議你從最小的一環(huán)開(kāi)始先給自己的工具調(diào)用加上超時(shí)然后把第一次失敗的過(guò)程記進(jìn)日志。從這一個(gè)小小的動(dòng)作開(kāi)始你已經(jīng)在修橋了。