用架構(gòu)設(shè)計(jì)實(shí)戰(zhàn):從模塊拆解到知識(shí)庫(kù)Agent落地)
1. 從一張畫不明白的架構(gòu)圖說起去年年初我們團(tuán)隊(duì)接了一個(gè)AI應(yīng)用項(xiàng)目產(chǎn)品經(jīng)理給的需求只有一句話“做一個(gè)能幫客戶查合同條款的智能助手”。當(dāng)時(shí)人人都在談AI應(yīng)用架構(gòu)設(shè)計(jì)我們也沒多想直接拉了幾個(gè)人開始做后端同學(xué)用Python寫了個(gè)服務(wù)前端同事搭了個(gè)聊天界面算法同學(xué)那邊微調(diào)了一個(gè)開源大模型數(shù)據(jù)庫(kù)里頭存了一份法規(guī)文檔的切塊。兩周后我們把東西串起來結(jié)果連自己人都看不懂系統(tǒng)是怎么流轉(zhuǎn)的問題來了要先進(jìn)哪個(gè)服務(wù)向量庫(kù)里的數(shù)據(jù)是哪里來的為什么模型偶爾答非所問卻查不到日志我畫了三版架構(gòu)圖每一版都被人挑戰(zhàn)“你這個(gè)框和線到底代表什么”。那段時(shí)間我意識(shí)到一個(gè)很現(xiàn)實(shí)的問題大部分AI應(yīng)用不缺代碼缺的是能把系統(tǒng)講清楚的架構(gòu)設(shè)計(jì)。很多團(tuán)隊(duì)立項(xiàng)時(shí)只盯著“接入哪個(gè)大模型”卻忽略了應(yīng)用本身的完整生命周期——從用戶請(qǐng)求進(jìn)來到意圖識(shí)別、上下文組裝、知識(shí)檢索、模型推理、結(jié)果校驗(yàn)、工具調(diào)用再到最終回復(fù)這中間每一條鏈路都要被顯式地畫出來、定下來。如果你說不清一條請(qǐng)求在系統(tǒng)里經(jīng)歷了什么排查問題就只能是碰運(yùn)氣優(yōu)化性能就是拍腦袋。這篇文章不是學(xué)院派的理論講義而是我基于真實(shí)項(xiàng)目的經(jīng)驗(yàn)整理——從AI應(yīng)用架構(gòu)設(shè)計(jì)的核心模塊拆解開始講清楚每一層為什么存在、怎么選型、怎么落地再聊到架構(gòu)圖要怎么畫才不會(huì)淪為“應(yīng)付匯報(bào)的裝飾品”最后給出一個(gè)可直接參考的知識(shí)庫(kù)問答Agent設(shè)計(jì)案例以及我們?cè)趯?shí)際部署中踩過的坑。適合正在設(shè)計(jì)AI應(yīng)用方案的后端工程師、AI應(yīng)用開發(fā)者、產(chǎn)品和技術(shù)負(fù)責(zé)人也適合剛?cè)腴TAI應(yīng)用開發(fā)、想建立整體視角的同學(xué)。2. AI應(yīng)用架構(gòu)設(shè)計(jì)的核心模塊拆解2.1 先想清楚這是“功能”還是“系統(tǒng)”很多人架構(gòu)設(shè)計(jì)做不好根因是沒分清做的是功能還是系統(tǒng)。功能是“能對(duì)話、能回答”系統(tǒng)是“在什么輸入條件下、經(jīng)過哪些環(huán)節(jié)、在多大負(fù)載下、以什么質(zhì)量穩(wěn)定地輸出結(jié)果”。AI應(yīng)用架構(gòu)設(shè)計(jì)的起點(diǎn)不是選一個(gè)模型而是把整個(gè)系統(tǒng)分成六個(gè)互相獨(dú)立又能協(xié)同的模塊我沿用的分層方式是接入層、理解與編排層、模型層、記憶與上下文層、知識(shí)增強(qiáng)層、執(zhí)行與工具層。接入層負(fù)責(zé)對(duì)外通信統(tǒng)一處理HTTP請(qǐng)求、WebSocket長(zhǎng)連接、消息隊(duì)列以及后端的鑒權(quán)、限流、計(jì)量。理解與編排層是大腦承擔(dān)意圖識(shí)別、任務(wù)規(guī)劃、工作流調(diào)度決定當(dāng)前請(qǐng)求應(yīng)該走快速回答還是多步推理。模型層包括大語(yǔ)言模型本身和可能用到的多模態(tài)模型、向量模型、重排模型。記憶與上下文層管理短期對(duì)話狀態(tài)、長(zhǎng)期用戶偏好、全局事實(shí)性知識(shí)。知識(shí)增強(qiáng)層是RAG落地的主戰(zhàn)場(chǎng)涵蓋文檔解析、切片、向量化、索引、召回、重排。執(zhí)行與工具層讓Agent真正“動(dòng)手”包括內(nèi)置函數(shù)、外部API、代碼解釋器、數(shù)據(jù)庫(kù)查詢器等。這六層不是每個(gè)系統(tǒng)都必須齊備功能簡(jiǎn)單的問答機(jī)器人可能只有接入層、模型層和基礎(chǔ)上下文但你在設(shè)計(jì)架構(gòu)時(shí)至少要走過一遍這六個(gè)問題域再?zèng)Q定砍掉哪些。這個(gè)“先完整拆解、再按需裁剪”的過程能避免最典型的設(shè)計(jì)失誤——一上來就直撲模型層等到需要加記憶、接知識(shí)庫(kù)、調(diào)工具時(shí)發(fā)現(xiàn)原來的膠水代碼根本撐不住。2.2 編排層是AI應(yīng)用架構(gòu)里最容易被低估的部分我見過太多團(tuán)隊(duì)把“編排”等同于“調(diào)用模型”這是架構(gòu)設(shè)計(jì)里最大的誤區(qū)。早期的AI應(yīng)用確實(shí)往往就是一個(gè)HTTP接口包一層提示詞但進(jìn)入Agent時(shí)代以后編排層的復(fù)雜度已經(jīng)超過很多傳統(tǒng)后端系統(tǒng)。一個(gè)真實(shí)的Agent請(qǐng)求可能包含意圖分類、必要的多輪澄清、檢索觸發(fā)條件判斷、工具調(diào)用規(guī)劃、工具結(jié)果解析、臨時(shí)狀態(tài)保存、多人協(xié)調(diào)等。編排層的設(shè)計(jì)目標(biāo)是把“模型的不確定性”和“業(yè)務(wù)邏輯的確定性”隔離開。業(yè)務(wù)規(guī)則比如“客戶等級(jí)為VIP時(shí)必須優(yōu)先走人工復(fù)核”“金額超過閾值必須調(diào)用風(fēng)控接口”這些應(yīng)該落在代碼里做硬編碼規(guī)則而“用戶想表達(dá)什么、應(yīng)該調(diào)用哪個(gè)工具、需要從哪份文檔里找答案”這些語(yǔ)義判斷才交給模型去推理。如果反過來把確定性的東西全塞進(jìn)提示詞讓模型用概率去保證系統(tǒng)就會(huì)表現(xiàn)得飄忽不定。在模塊劃分上編排層里我習(xí)慣再拆成三個(gè)子組件意圖路由負(fù)責(zé)把用戶輸入分類到不同的處理流程任務(wù)分解器把復(fù)雜任務(wù)拆成多步驟清單狀態(tài)控制器維護(hù)當(dāng)前任務(wù)執(zhí)行到哪一步下一步依賴哪些數(shù)據(jù)。三個(gè)人可以平行開發(fā)的組件合起來就是一個(gè)可控的Agent工作流。架構(gòu)圖畫到這里才開始有了“可解釋性”的雛形。2.3 模型層的選型不是越大越好模型層設(shè)計(jì)要回答的問題很直接用哪個(gè)模型、部署在哪里、一次推理的成本是多少。大多數(shù)業(yè)務(wù)場(chǎng)景下我們需要的不是一個(gè)無(wú)所不能的通用大模型而是一個(gè)能在特定任務(wù)上穩(wěn)定輸出、成本可控的模型組合。實(shí)操中我傾向于按任務(wù)難度分層選型簡(jiǎn)單意圖識(shí)別、文本分類、格式抽取用輕量模型或直接調(diào)用速度快的小尺寸模型復(fù)雜推理、長(zhǎng)文本生成、高難度代碼生成才動(dòng)用旗艦級(jí)模型。還有一類任務(wù)適合用多個(gè)模型協(xié)作比如先讓一個(gè)小模型做路由判斷請(qǐng)求該進(jìn)快速通道還是深度通道再把深度通道的請(qǐng)求交給大模型。這套設(shè)計(jì)在架構(gòu)上并不復(fù)雜但對(duì)成本和延遲的改善非常直接。模型部署位置的選擇同樣關(guān)鍵。純?cè)贫薃PI方案的優(yōu)勢(shì)是維護(hù)成本為零、模型更新及時(shí)短板在于數(shù)據(jù)私密性受限、單次調(diào)用延遲偏高私有化部署能解決隱私和長(zhǎng)尾成本問題但需要GPU資源、運(yùn)維能力和模型版本管理能力混合方案則把敏感數(shù)據(jù)處理放在私有化模型非敏感通用任務(wù)走云端。我給過一個(gè)客戶的參考建議如果每日請(qǐng)求量低于一萬(wàn)次直接用云端API的性價(jià)比最高過了這個(gè)量級(jí)再認(rèn)真核算私有化部署的邊際成本。3. 圖解AI應(yīng)用架構(gòu)圖到底應(yīng)該怎么畫3.1 四種必備視圖對(duì)應(yīng)不同溝通場(chǎng)景很多項(xiàng)目里的架構(gòu)圖只有一張“大雜燴”把服務(wù)器、數(shù)據(jù)庫(kù)、模型API、業(yè)務(wù)流程全塞在一個(gè)方框里誰(shuí)看都費(fèi)勁。真正可用的AI應(yīng)用架構(gòu)設(shè)計(jì)圖解至少應(yīng)該包括四種視圖每種視圖服務(wù)不同的讀者和決策場(chǎng)景。第一種是系統(tǒng)上下文圖這是給產(chǎn)品經(jīng)理、業(yè)務(wù)方、老板看的。整張圖只需要一個(gè)核心系統(tǒng)方塊周邊畫上用戶角色、外部依賴和數(shù)據(jù)源目標(biāo)是讓非技術(shù)人員一眼看懂“這個(gè)AI應(yīng)用處于什么位置和誰(shuí)打交道”。我在項(xiàng)目啟動(dòng)會(huì)上通常只展示這一張圖用來對(duì)齊范圍避免一開始就陷入技術(shù)細(xì)節(jié)。第二種是容器圖給后端團(tuán)隊(duì)成員看。容器在這里指可獨(dú)立部署的服務(wù)或進(jìn)程比如Web網(wǎng)關(guān)、Agent編排服務(wù)、向量數(shù)據(jù)庫(kù)、模型推理服務(wù)。容器圖要表達(dá)的是服務(wù)之間的調(diào)用關(guān)系和協(xié)議比如通過HTTP還是gRPC、同步還是異步這張圖畫清楚了系統(tǒng)拆分和部署邊界也就清楚了。第三種是組件圖給核心開發(fā)人員看。在容器圖的基礎(chǔ)上深入到每個(gè)容器內(nèi)部的模塊劃分比如編排服務(wù)里的意圖路由模塊、工具調(diào)度模塊、狀態(tài)管理模塊是如何協(xié)作的。組件圖是我們?cè)谧鲈O(shè)計(jì)評(píng)審、代碼走查時(shí)的主要參考資料。第四種是部署圖給運(yùn)維和SRE團(tuán)隊(duì)看。要標(biāo)明每個(gè)容器的物理/云上部署形態(tài)、副本數(shù)量、GPU資源信息、網(wǎng)絡(luò)策略等。部署圖需要在架構(gòu)設(shè)計(jì)早期就動(dòng)筆很多AI項(xiàng)目上線延遲正是因?yàn)椴渴鸺?xì)節(jié)到開發(fā)尾聲才被想起。3.2 圖解的關(guān)鍵約定讓框和線都有一致語(yǔ)義架構(gòu)圖畫多了我總結(jié)出幾條約定能顯著減少“圖看不懂”的尷尬。方框只畫實(shí)體比如服務(wù)、數(shù)據(jù)庫(kù)、外部系統(tǒng)圓角矩形只畫邏輯模塊比如組件、子功能箭頭表示控制流或調(diào)用流實(shí)線代表同步調(diào)用虛線代表異步消息。不要在圖上用不同顏色表達(dá)含義除非圖例里寫明了顏色規(guī)則否則看圖的人只能靠猜。數(shù)據(jù)流的方向盡量統(tǒng)一我習(xí)慣從左到右展開用戶入口在左側(cè)外部依賴在右側(cè)核心系統(tǒng)占據(jù)中間主視覺。如果一張圖里數(shù)據(jù)流出現(xiàn)回頭、交叉、繞圈往往是系統(tǒng)設(shè)計(jì)本身存在循環(huán)依賴這在架構(gòu)層面就需要警惕。有一次我們畫編排服務(wù)組件圖發(fā)現(xiàn)“調(diào)用工具→工具回調(diào)編排服務(wù)→編排服務(wù)再調(diào)用另一個(gè)工具”形成了跨服務(wù)循環(huán)實(shí)際排查后發(fā)現(xiàn)確實(shí)存在同步阻塞風(fēng)險(xiǎn)。還要強(qiáng)制給每個(gè)關(guān)鍵連接標(biāo)注協(xié)議和數(shù)據(jù)類型比如“HTTP/JSON”“gRPC/ProtoBuf”或“Kafka/事件”。標(biāo)注的價(jià)值在于暴露隱式假設(shè)AI系統(tǒng)里特別常見的問題是“模型輸出后直接通過HTTP轉(zhuǎn)發(fā)給下游”沒有明確數(shù)據(jù)格式約定最后下游解析報(bào)錯(cuò)時(shí)誰(shuí)都不知道問題出在哪。3.3 架構(gòu)圖用什么工具畫才能保持“活”靜態(tài)畫圖工具畫的架構(gòu)圖最致命的問題是“畫完即過期”。兩周后代碼改了架構(gòu)圖還停留在舊版本沒有人愿意維護(hù)它最后這張圖徹底變成擺設(shè)。對(duì)于AI應(yīng)用這種迭代速度極快的系統(tǒng)我的建議是把架構(gòu)圖“代碼化”用文本生成圖的方式管理。PlantUML、Graphviz這類工具都支持用文本描述方框和箭頭改動(dòng)架構(gòu)時(shí)改幾個(gè)字符就能重新生成能放進(jìn)Git倉(cāng)庫(kù)里做版本管理。文本化的另一個(gè)好處是可以做架構(gòu)評(píng)審的差異對(duì)比我經(jīng)常在代碼評(píng)審時(shí)順帶跑一下架構(gòu)描述文件的diff能直觀看到這次改動(dòng)影響了哪些調(diào)用關(guān)系。還要注意架構(gòu)圖里可以簡(jiǎn)要標(biāo)注技術(shù)選型但不要在圖上堆砌過多細(xì)節(jié)比如不要寫具體的超參、不要寫環(huán)境變量名。架構(gòu)圖的信息層次應(yīng)該比詳細(xì)設(shè)計(jì)文檔高一層否則圖會(huì)變成一篇看不懂的文檔。做到這里圖解方法論算是通了但還要配合一套協(xié)作規(guī)范至少約定好誰(shuí)負(fù)責(zé)更新、什么變更必須更新圖、評(píng)審時(shí)看圖還是看代碼。沒有規(guī)范約束任何圖示方案都活不過一個(gè)月。4. 從零到一設(shè)計(jì)一個(gè)知識(shí)庫(kù)問答Agent4.1 需求側(cè)把邊界定清楚為了讓前面的模塊拆解和圖解方法落地我完整走一個(gè)案例設(shè)計(jì)一個(gè)面向企業(yè)內(nèi)部員工的知識(shí)庫(kù)問答Agent數(shù)據(jù)源有幾十份產(chǎn)品文檔、制度文檔和故障處理手冊(cè)用戶通過Web聊天窗口提問期望獲得帶出處的答案。按之前的六層拆解需求側(cè)的重點(diǎn)不是“能回答”而是三個(gè)邊界條件。回答必須給出文檔出處這意味著知識(shí)增強(qiáng)層是剛需召回結(jié)果里必須保留來源信息和置信度。文檔更新后系統(tǒng)要能感知變化需要有文檔版本追蹤和索引刷新機(jī)制。部分問題的答案不能被限定在文檔里需要結(jié)合實(shí)時(shí)數(shù)據(jù)比如庫(kù)存數(shù)量、服務(wù)器狀態(tài)因?yàn)锳gent必須能調(diào)用工具例如查詢內(nèi)部API。這三個(gè)需求直接決定架構(gòu)里哪些模塊必須存在、哪些可以砍掉也決定了我們最終的部署形態(tài)是私有化還是混合方案。我們還定義了非功能需求單次問答端到端延遲不超過三秒日活用戶不超過五百人并發(fā)峰值為五十個(gè)會(huì)話特殊客戶數(shù)據(jù)必須留在內(nèi)部網(wǎng)絡(luò)。這幾個(gè)數(shù)字決定了Embedding模型和LLM在本地還是云端運(yùn)行決定了向量數(shù)據(jù)庫(kù)選型甚至決定了回答流式還是非流式輸出。4.2 分層實(shí)現(xiàn)的關(guān)鍵決策與配置樣例接入層我們選擇了一個(gè)輕量網(wǎng)關(guān)服務(wù)統(tǒng)一處理WebSocket會(huì)話、用戶鑒權(quán)和限流請(qǐng)求進(jìn)入后由網(wǎng)關(guān)轉(zhuǎn)發(fā)到Agent編排服務(wù)。為什么沒用HTTP短連接因?yàn)閱柎饒?chǎng)景天然適合多輪對(duì)話WebSocket能省去每次請(qǐng)求都建立連接的開銷也能更自然地上推流式回復(fù)。編排層我們用一套規(guī)則加模型混合的路由先通過一個(gè)極快的意圖分類判斷如果問題命中“查文檔資料”這個(gè)意圖就走RAG流程如果命中“查系統(tǒng)狀態(tài)”就進(jìn)入工具調(diào)用流程如果兩者都命中就先檢索文檔再調(diào)用工具補(bǔ)全實(shí)時(shí)數(shù)據(jù)。這套路由用幾十條標(biāo)注數(shù)據(jù)和一個(gè)較小的分類模型就能做不需要什么復(fù)雜的推薦算法。這里一個(gè)心得是路由意圖的集合一定要控制在合理范圍內(nèi)別超過十五個(gè)否則分類準(zhǔn)確率下降后續(xù)維護(hù)和擴(kuò)展都會(huì)很吃力。模型層最終選擇了雙模型組合問答主模型部署了一款中等參數(shù)規(guī)模的模型偏重指令遵循和中文理解量化后在本地單卡上跑Embedding模型用了專門的向量模型索引維度一千多。重排模型選擇了一個(gè)輕量級(jí)的排序模型對(duì)召回的前五十條做精排再取前幾條進(jìn)上下文。這套組合比“一個(gè)大模型干所有事”的方式在延遲上優(yōu)化了約一半成本更是只用了大概三分之一。知識(shí)增強(qiáng)層是工作量最大的部分。文檔先按結(jié)構(gòu)拆成段落再按長(zhǎng)度做二次切分保證每片語(yǔ)義相對(duì)完整切片后生成Embedding并寫入向量庫(kù)。我們最初直接用長(zhǎng)度固定切分效果很差大量相關(guān)命中被割斷。后來改成“按標(biāo)題層級(jí)切塊、塊內(nèi)再分片”的策略實(shí)測(cè)召回率提升明顯。重排之后還需要做一個(gè)“出處格式化”把命中的原文片段和文檔名、章節(jié)路徑帶回給編排層。工具層我們接了兩個(gè)內(nèi)部API一個(gè)用于查詢庫(kù)存數(shù)量一個(gè)用于查詢服務(wù)狀態(tài)通過函數(shù)調(diào)用約定暴露給模型。這里一個(gè)比較容易踩的坑是工具返回的數(shù)據(jù)結(jié)構(gòu)要穩(wěn)定一旦變動(dòng)必須同步更新給模型看的工具說明否則模型會(huì)按舊結(jié)構(gòu)解析經(jīng)常解析出奇怪的字段。后來我們加了一個(gè)簡(jiǎn)單的json schema校驗(yàn)器在工具返回的第一環(huán)做結(jié)構(gòu)性檢查問題率降了很多。4.3 配置參數(shù)一份可以直接抄的啟動(dòng)清單項(xiàng)目落地后我把關(guān)鍵配置參數(shù)整理成了表格式清單按模塊劃分方便團(tuán)隊(duì)對(duì)照部署。模塊配置項(xiàng)參考值說明接入層會(huì)話超時(shí)10分鐘無(wú)操作斷開配合心跳機(jī)制避免資源空占接入層限流閾值每用戶每分鐘20次請(qǐng)求防止對(duì)話機(jī)器人被高頻刷單編排層意圖分類閾值置信度低于0.7轉(zhuǎn)入兜底話術(shù)避免低置信度誤路由到錯(cuò)誤流程編排層最大工具調(diào)用數(shù)單輪最多3次防止模型陷入工具循環(huán)模型層主模型量化4bit量化部署兼顧回答質(zhì)量和單卡推理速度模型層溫度參數(shù)0.3知識(shí)問答類任務(wù)建議低溫知識(shí)增強(qiáng)層切片長(zhǎng)度按語(yǔ)義塊約300~500字長(zhǎng)文檔按標(biāo)題遞歸切分知識(shí)增強(qiáng)層召回?cái)?shù)量初召回50條精排后取5條給上下文足夠候選但不超窗口上下文層歷史窗口最近10輪摘要長(zhǎng)會(huì)話用摘要代替全量歷史溫度參數(shù)的取舍值得多說一句。知識(shí)問答場(chǎng)景你希望模型盡量忠實(shí)于檢索到的內(nèi)容而不是自由發(fā)揮文采所以溫度設(shè)低一些比較穩(wěn)。我在實(shí)驗(yàn)里把溫度從0.3升到0.8其他條件不變連續(xù)跑了三組測(cè)試集結(jié)果在“忠實(shí)度”這項(xiàng)指標(biāo)上下降了十幾個(gè)百分點(diǎn)代價(jià)非常直觀。5. 落地實(shí)證高頻故障與排查實(shí)錄5.1 RAG不生效問題是相關(guān)文檔根本沒被召回上線后我們遇到的最典型問題是明明知識(shí)庫(kù)里有一篇文檔寫得很清楚用戶提問時(shí)模型就是答不上來。一開始懷疑是生成環(huán)節(jié)的問題調(diào)提示詞、換模型都沒用后來檢查重排結(jié)果發(fā)現(xiàn)檢索環(huán)節(jié)的召回列表里根本沒有那篇文檔。排查路徑是這樣的先確認(rèn)文檔是否成功入庫(kù)向量庫(kù)里能查到對(duì)應(yīng)記錄再檢查輸入查詢向量化是否正常手工打印用戶問題的向量相似度分布最后查出問題出在文檔切分上那份文檔的關(guān)鍵內(nèi)容在一個(gè)超長(zhǎng)的表格里按標(biāo)題切塊后被整體當(dāng)成一個(gè)塊而該塊的向量表示被表格中的大量數(shù)字稀釋了。解決辦法是增加一個(gè)表格識(shí)別步驟把大表格拆成按行/按頁(yè)的小塊再單獨(dú)建立索引。從這個(gè)案例里我總結(jié)出一條規(guī)律RAG鏈路不對(duì)優(yōu)先查“文檔到底怎么被切的”永遠(yuǎn)比盲目調(diào)模型參數(shù)更有效。這類問題也可以用更系統(tǒng)的排查清單來梳理檢查入庫(kù)文檔解析是否完整特別警惕PDF提取丟字檢查切片是否破壞語(yǔ)義塊檢查Embedding模型和查詢向量是否同一版本檢查重排是否把正確結(jié)果排到了后面最后檢查拼接好的上下文是否被截?cái)?。按照順序一點(diǎn)一點(diǎn)排除能節(jié)省大量試錯(cuò)時(shí)間。5.2 上下文管理不當(dāng)導(dǎo)致的多輪對(duì)話漂移另一個(gè)高頻故障是對(duì)話輪次稍長(zhǎng)模型就“跑偏”。用戶第一輪問“打印機(jī)故障如何處理”第二輪說“我是指三樓那臺(tái)”模型完全聽不明白這個(gè)指代。問題看起來是模型能力不夠?qū)嶋H上是我們上下文層設(shè)計(jì)太簡(jiǎn)單——直接把全部歷史消息原樣塞給模型沒有做指代消解和摘要提煉。我們后來在上下文層里增加了一個(gè)動(dòng)態(tài)摘要器當(dāng)歷史超過十輪就把更早的內(nèi)容壓縮成一則語(yǔ)義摘要保留核心實(shí)體和用戶意圖同時(shí)保留近三輪完整消息用于指代識(shí)別?!叭龢悄桥_(tái)”這類指代信息必須保留在最近消息里不能過早被摘要掉。改造后十輪以上多輪對(duì)話的滿意度有明顯提升。上下文層的設(shè)計(jì)三個(gè)要點(diǎn)都是踩坑換來的歷史不是越長(zhǎng)越好窗口過長(zhǎng)會(huì)稀釋注意力消息需要區(qū)分層級(jí)系統(tǒng)指令、工具返回結(jié)果、歷史用戶消息在拼接時(shí)要有明確的優(yōu)先級(jí)敏感信息要做脫敏或權(quán)限過濾不能讓模型在回答中泄露其他用戶的數(shù)據(jù)。5.3 穩(wěn)定的代價(jià)像對(duì)待交易系統(tǒng)一樣對(duì)待Agent我們把Agent服務(wù)想象成一個(gè)交易系統(tǒng)來設(shè)計(jì)穩(wěn)定性。任何一步都可能失敗所以要構(gòu)建完善的錯(cuò)誤處理機(jī)制。工具調(diào)用設(shè)置了嚴(yán)格的超時(shí)和重試策略默認(rèn)超時(shí)五秒、最多重試兩次模型輸出做格式校驗(yàn)必須符合預(yù)期的JSON結(jié)構(gòu)否則觸發(fā)一次修復(fù)提示再交給模型整個(gè)編排過程的關(guān)鍵節(jié)點(diǎn)都記錄traceID請(qǐng)求一進(jìn)來就生成一個(gè)唯一的追蹤標(biāo)識(shí)下游日志全部帶上它。排查問題時(shí)的第一個(gè)動(dòng)作永遠(yuǎn)是“按traceID拉全鏈路日志”而不是盯著模型輸出猜。這個(gè)習(xí)慣幫我們省了無(wú)數(shù)時(shí)間。日志要區(qū)分結(jié)構(gòu)化事件和內(nèi)容快照事件日志用于聚合統(tǒng)計(jì)內(nèi)容快照用于困難樣本復(fù)盤。成本方面我們給每個(gè)請(qǐng)求記錄Token消耗和模型調(diào)用的費(fèi)用估算監(jiān)控異常消耗。有一次線上發(fā)現(xiàn)某個(gè)用戶的單次會(huì)話消耗突增拉了日志后發(fā)現(xiàn)是Agent陷入工具循環(huán)連續(xù)調(diào)用了十幾次查詢接口。在編排規(guī)則里加上“單輪最多調(diào)用工具三次”的硬限制后這種異?;鞠Я?。為了讓系統(tǒng)可控我們還會(huì)定期抽取線上失敗的對(duì)話樣本人工復(fù)盤后加入回歸測(cè)試集。這個(gè)動(dòng)作比什么評(píng)估框架都實(shí)用因?yàn)槊恳淮蜶eview都能直接轉(zhuǎn)化為下一輪迭代的用例。6. 從單Agent到多Agent協(xié)作的架構(gòu)演進(jìn)6.1 三種協(xié)作模式按需選擇而非追新Agent類應(yīng)用的下一站通常是多Agent協(xié)作多個(gè)具備不同專長(zhǎng)的Agent組合起來處理更復(fù)雜的任務(wù)。但架構(gòu)上的“多Agent”不是為了炫技而是為了解決單一Agent“什么都會(huì)一點(diǎn)、什么都做不精”的問題。實(shí)際工程里最常見的三種協(xié)作模式。第一種是編排者模式一個(gè)主Agent負(fù)責(zé)接收用戶請(qǐng)求并拆解任務(wù)把子任務(wù)分發(fā)給不同的專家Agent再統(tǒng)一匯總結(jié)果。這個(gè)模式控制性強(qiáng)、流程透明適合流程相對(duì)固定的場(chǎng)景比如工單處理。第二種是辯論模式多個(gè)Agent扮演不同角色比如產(chǎn)品、技術(shù)、風(fēng)控針對(duì)同一個(gè)問題提出方案并互相挑戰(zhàn)最終由一個(gè)裁決Agent或投票機(jī)制給出結(jié)論。這個(gè)模式適合決策類任務(wù)但成本很高需要注意控制Agent數(shù)量和討論輪數(shù)以防止邏輯循環(huán)。第三種是流水線模式把任務(wù)拆解成固定順序的步驟每個(gè)步驟由一個(gè)專門的Agent完成前一個(gè)Agent的輸出作為后一個(gè)的輸入比如一篇文章從資料檢索、初稿撰寫、合規(guī)審查到潤(rùn)色發(fā)布的流水線。選哪種模式主要看任務(wù)的可拆解性和對(duì)流程可控性的要求。我在項(xiàng)目里的一條原則是能用一個(gè)Agent解決的任務(wù)不要為了架構(gòu)上的“多”去拆成多個(gè)只有明確出現(xiàn)了能力沖突或獨(dú)立質(zhì)量瓶頸時(shí)才值得引入多Agent協(xié)作。6.2 協(xié)作接口比Agent內(nèi)部的模型更重要多Agent架構(gòu)最容易翻車的地方不是Agent的模型能力而是Agent之間的通信協(xié)議。每個(gè)Agent本質(zhì)上是獨(dú)立的服務(wù)相互之間要傳遞結(jié)構(gòu)化任務(wù)、內(nèi)容片段、狀態(tài)信息。如果直接在代碼里硬編碼互相調(diào)用一旦一個(gè)Agent的接口變了整個(gè)協(xié)作鏈就癱瘓。我們給每個(gè)Agent定義了一套統(tǒng)一的任務(wù)協(xié)議包含任務(wù)類型、輸入?yún)?shù)、上下文引用、期望輸出格式、質(zhì)量要求和回調(diào)地址。這樣無(wú)論是哪個(gè)Agent發(fā)起的協(xié)作請(qǐng)求格式都是一致的。這套協(xié)議同時(shí)也是多Agent協(xié)作架構(gòu)圖的重要支撐——圖解上不再畫“A調(diào)B、B調(diào)C”這種蛛網(wǎng)式線條而是改為“所有Agent通過協(xié)議總線交換信息”的簡(jiǎn)潔結(jié)構(gòu)圖面清晰很多排查問題也簡(jiǎn)單很多。只要遵循協(xié)作協(xié)議新增Agent不會(huì)破壞既有鏈路替換某個(gè)Agent的內(nèi)部實(shí)現(xiàn)也不影響整體架構(gòu)。6.3 演進(jìn)過程中始終保持架構(gòu)上的“不變項(xiàng)”無(wú)論單Agent還是多Agent有幾件事在架構(gòu)演進(jìn)中盡量保持不變。第一接入層對(duì)外暴露的接口形態(tài)保持穩(wěn)定用戶的會(huì)話體系和后端Agent內(nèi)部結(jié)構(gòu)解耦這樣即使整個(gè)Agent編排方式推翻重做用戶端無(wú)感知。第二知識(shí)增強(qiáng)層的數(shù)據(jù)通道保持單一入口所有文檔寫入都經(jīng)過同一條解析入庫(kù)管道不會(huì)因?yàn)闃I(yè)務(wù)復(fù)雜化就出現(xiàn)多個(gè)互不相通的知識(shí)源。第三可觀測(cè)性基礎(chǔ)設(shè)施從一開始就搭建好traceID貫穿所有Agent這是多Agent系統(tǒng)里唯一能定位問題的抓手等到出問題再來補(bǔ)往往已經(jīng)晚了。我的習(xí)慣是每次架構(gòu)評(píng)審時(shí)先看這三個(gè)不變項(xiàng)有沒有被破壞。如果沒破壞內(nèi)部再怎么演進(jìn)都算安全一旦破壞了再好看的架構(gòu)圖也掩蓋不了未來要爆的雷。最后說一點(diǎn)個(gè)人體會(huì)。我在實(shí)際項(xiàng)目中越來越覺得AI應(yīng)用架構(gòu)設(shè)計(jì)和傳統(tǒng)軟件架構(gòu)沒有本質(zhì)區(qū)別核心都是管理復(fù)雜度。模型只是整個(gè)系統(tǒng)里的一個(gè)組件它能力再?gòu)?qiáng)也替代不了清晰的邊界劃分、穩(wěn)定的數(shù)據(jù)通道和扎實(shí)的工程規(guī)范。每次團(tuán)隊(duì)里有人興奮地拿來一個(gè)新的Agent框架說“這個(gè)能幫我們解決所有問題”我都會(huì)建議先把它的調(diào)用鏈圖畫出來走一遍我們自己的六層拆解再?zèng)Q定要不要引入。這個(gè)習(xí)慣幫我們避開了很多無(wú)效的“架構(gòu)追新”。希望這份從設(shè)計(jì)方法、圖解規(guī)范到落地排查的經(jīng)驗(yàn)?zāi)茏屇阍谙乱话鍭I應(yīng)用架構(gòu)設(shè)計(jì)時(shí)少走幾步彎路。