級(jí)知識(shí)助手的落地路線與工程實(shí)踐)
這兩年最常被問(wèn)到的一個(gè)問(wèn)題就是企業(yè)內(nèi)部的知識(shí)助手到底該怎么落地。很多團(tuán)隊(duì)的路徑出奇地一致先上一套 RAG 把文檔問(wèn)答跑通然后跑著跑著發(fā)現(xiàn)“只能答不能做”再往上加 Agent 能力讓系統(tǒng)能調(diào)用工具、能主動(dòng)檢索多輪信息、能完成跨系統(tǒng)操作。這條路幾乎成了企業(yè)知識(shí)助手開(kāi)發(fā)的默認(rèn)路線也確實(shí)是踩坑最少的一條路。這篇文章就圍繞“從 RAG 到 Agent”這條演進(jìn)線索講清楚一個(gè)完整的企業(yè)知識(shí)助手是怎么一步步搭起來(lái)的。我會(huì)拆解 RAG 的原理與瓶頸、Agent 化改造的關(guān)鍵設(shè)計(jì)并給出完整的工程實(shí)現(xiàn)和踩坑記錄。適合正在做知識(shí)問(wèn)答類應(yīng)用的研發(fā)同學(xué)也適合準(zhǔn)備把 LLM 接入企業(yè)業(yè)務(wù)但還在觀望的團(tuán)隊(duì)參考。1. 為什么企業(yè)知識(shí)助手的選擇是“先 RAG后 Agent”1.1 RAG 到底解決的是什么問(wèn)題先說(shuō)清楚 RAG 是什么。RAG 的全稱是 Retrieval-Augmented Generation檢索增強(qiáng)生成。它的核心思路很直白大模型不是萬(wàn)能的尤其在企業(yè)內(nèi)部知識(shí)面前它既不知道你們的產(chǎn)品文檔寫(xiě)了什么也不知道你們內(nèi)部流程走的是哪套審批邏輯。所以與其指望模型記住這些不如先把知識(shí)存在外部每次問(wèn)答前先檢索出相關(guān)內(nèi)容再把“問(wèn)題 檢索到的資料”一起丟給模型生成答案。這句話聽(tīng)起來(lái)簡(jiǎn)單但它是整個(gè)企業(yè)知識(shí)助手的邏輯起點(diǎn)。做 RAG 的本質(zhì)不是寫(xiě)個(gè)檢索接口而是重新定義“知識(shí)怎么存放、怎么被找到、怎么被使用”這三件事。企業(yè)內(nèi)部的知識(shí)形態(tài)高度混合有 Word 文檔、PDF、PPT、網(wǎng)頁(yè)、表格、甚至聊天記錄里的經(jīng)驗(yàn)碎片。RAG 的價(jià)值在于把這些異構(gòu)內(nèi)容統(tǒng)一成同一種形態(tài)——文本向量——然后用語(yǔ)義相似度來(lái)召回。用戶問(wèn)“報(bào)銷流程怎么走”不需要文檔里出現(xiàn)“報(bào)銷”兩個(gè)字只要語(yǔ)義相關(guān)向量檢索也能找得到。這也是 RAG 比微調(diào)更適合企業(yè)知識(shí)場(chǎng)景的根本原因。微調(diào)意味著把知識(shí)壓進(jìn)模型參數(shù)里每次知識(shí)更新都要重新訓(xùn)練成本高、周期長(zhǎng)、還容易讓模型“記串了”。RAG 則把知識(shí)留在外部更新知識(shí)就是更新索引模型本身不動(dòng)幻覺(jué)風(fēng)險(xiǎn)也相對(duì)可控。對(duì)于知識(shí)頻繁變動(dòng)的企業(yè)場(chǎng)景RAG 幾乎是唯一在成本和效果之間取得平衡的方案。1.2 為什么最終要走向 AgentRAG 能解決“從文檔中找答案”但解決不了“復(fù)雜任務(wù)需要多步處理”的問(wèn)題。舉幾個(gè)真實(shí)場(chǎng)景你就能感受到差距。第一個(gè)場(chǎng)景用戶問(wèn)“幫我對(duì)比一下 A 產(chǎn)品和 B 產(chǎn)品在安全認(rèn)證方面的差異”這不是一次檢索能搞定的需要先定位 A 產(chǎn)品的認(rèn)證文檔再找 B 產(chǎn)品的資質(zhì)材料可能還要查一個(gè)第三方的認(rèn)證標(biāo)準(zhǔn)最后匯總對(duì)比。第二個(gè)場(chǎng)景用戶問(wèn)“下周要提交給客戶的方案幫我拉一下最近三個(gè)項(xiàng)目的技術(shù)細(xì)節(jié)”這已經(jīng)不只是問(wèn)答了這是要跨文檔、跨系統(tǒng)、帶條件的任務(wù)。第三個(gè)場(chǎng)景更典型用戶說(shuō)“查一下這個(gè)故障碼在運(yùn)維手冊(cè)里的處理方法然后按格式生成一張工單”這里面有檢索動(dòng)作、有格式變換、還可能涉及調(diào)用工單系統(tǒng)接口。這些需求暴露了 RAG 的硬瓶頸RAG 是無(wú)狀態(tài)的“檢索-生成”單輪通道沒(méi)有規(guī)劃能力沒(méi)有工具調(diào)用能力也沒(méi)有多步推理能力。而 Agent 恰恰補(bǔ)上的是這三樣。Agent 的本質(zhì)是讓大模型不再只是“回答者”而是“決策者”和“執(zhí)行者”。它自己做任務(wù)拆解決定先檢索什么、再干什么甚至在需要時(shí)調(diào)用外部工具完成動(dòng)作。所以企業(yè)知識(shí)助手的完整形態(tài)往往不是純 RAG 也不是純 Agent而是從 RAG 這個(gè)“閱讀理解能力”出發(fā)疊加 Agent 的“任務(wù)執(zhí)行能力”。2. RAG 的五大瓶頸這是升級(jí) Agent 的直接理由2.1 檢索層的先天缺陷固定 Top-K 與語(yǔ)義盲區(qū)所有 RAG 系統(tǒng)第一個(gè)碰到的痛點(diǎn)就是“檢索結(jié)果不穩(wěn)定”。你設(shè)了 Top-K5可能用戶問(wèn)的問(wèn)題只需要 3 段資料就夠了多出來(lái)的 2 段反而干擾了模型回答換個(gè)問(wèn)題5 段又不夠真正關(guān)鍵的文檔排在第 6 位模型根本沒(méi)看到。這就是固定 Top-K 的結(jié)構(gòu)性缺陷。另一個(gè)更隱蔽的問(wèn)題是純向量檢索的語(yǔ)義盲區(qū)。向量檢索擅長(zhǎng)找“意思相近”的內(nèi)容但在處理精確匹配時(shí)非常弱。比如用戶輸入一個(gè)產(chǎn)品型號(hào)“SG-2000”向量檢索很可能把“SG-2000 Pro”“SG-2000 Mini”都當(dāng)成相似內(nèi)容拉出來(lái)而文檔里所有提到“SG-2000”的段落全部命中后真正包含技術(shù)參數(shù)的章節(jié)反而因?yàn)槲谋咎?、向量距離不夠近而被漏掉。還有代碼片段、IP 地址、工單號(hào)、合同編號(hào)這類高精度信息用向量檢索完全是不擅長(zhǎng)的。這也是后來(lái)要引入混合檢索、關(guān)鍵詞倒排索引甚至 Agent 檢索規(guī)劃的原因所在。2.2 編排層的僵硬單輪問(wèn)答撐不起復(fù)雜任務(wù)RAG 的標(biāo)準(zhǔn)鏈路是“一問(wèn)一檢一答”這個(gè)鏈路在簡(jiǎn)單問(wèn)答上沒(méi)問(wèn)題但撐不起復(fù)雜任務(wù)。典型現(xiàn)象是用戶的問(wèn)題涉及多個(gè)知識(shí)域比如“這個(gè)設(shè)備的保養(yǎng)周期是多少如果超期未保養(yǎng)會(huì)影響質(zhì)保嗎”前半個(gè)問(wèn)題屬于運(yùn)維手冊(cè)后半個(gè)問(wèn)題可能藏在商務(wù)合同條款里。普通 RAG 會(huì)把兩個(gè)子問(wèn)題混在一次檢索里結(jié)果召回的文檔兩邊都沒(méi)完全覆蓋。這種問(wèn)題的本質(zhì)是 RAG 缺少“查詢規(guī)劃”的能力它不知道把問(wèn)題拆成子問(wèn)題、分路檢索再匯總。有些團(tuán)隊(duì)試圖靠一個(gè)復(fù)雜 Prompt 讓模型先生成檢索詞、再檢索、再回答這個(gè)方向的盡頭就是 Agent因?yàn)橐坏┻M(jìn)入“根據(jù)查詢結(jié)果決定下一步查什么”的循環(huán)你實(shí)際上已經(jīng)是在寫(xiě) Agent 的 ReAct 邏輯了。2.3 知識(shí)表示層面的沖突RAG 與 KG 的分工很多團(tuán)隊(duì)會(huì)問(wèn)一個(gè)問(wèn)題RAG 知識(shí)庫(kù)和知識(shí)圖譜KG到底有什么區(qū)別什么時(shí)候該用哪個(gè)我的判斷是這樣的RAG 適合非結(jié)構(gòu)化文本的語(yǔ)義召回KG 適合實(shí)體關(guān)系和結(jié)構(gòu)化事實(shí)的精確查詢。前者擅長(zhǎng)“找內(nèi)容”后者擅長(zhǎng)“找關(guān)系”。舉個(gè)例子員工問(wèn)“A 項(xiàng)目的負(fù)責(zé)人是誰(shuí)他之前負(fù)責(zé)過(guò)哪些項(xiàng)目”如果只靠 RAG系統(tǒng)檢索到的是提到這個(gè)人的若干段落需要模型自己從中把實(shí)體關(guān)系抽出來(lái)準(zhǔn)確率看運(yùn)氣。如果知識(shí)庫(kù)里同時(shí)有一張圖譜節(jié)點(diǎn)是人、項(xiàng)目、角色邊是“負(fù)責(zé)”“參與”“匯報(bào)給”這類關(guān)系這個(gè)問(wèn)題就可以直接走圖譜查詢拿到確定答案。所以成熟的企業(yè)知識(shí)助手往往底層是 RAG KG 兩條檢索通道由 Agent 判斷問(wèn)題更適合走哪條路或者兩條都走、再做結(jié)果融合。這也是從 RAG 向 Agent 升級(jí)時(shí)一個(gè)非常重要的結(jié)構(gòu)性變化。2.4 缺失記憶與個(gè)性化企業(yè)知識(shí)助手的隱性問(wèn)題RAG 的另一個(gè)硬傷是沒(méi)有記憶。用戶問(wèn)“剛才那份合同里約定的付款條件是什么”系統(tǒng)無(wú)法正確理解“剛才”指的是哪一份合同。用戶連續(xù)問(wèn)了三個(gè)關(guān)于安全審計(jì)的問(wèn)題系統(tǒng)也不會(huì)把上下文串聯(lián)起來(lái)形成一份連續(xù)的分析。這在個(gè)人使用場(chǎng)景里只是體驗(yàn)問(wèn)題但在企業(yè)場(chǎng)景里是效率問(wèn)題。員工希望知識(shí)助手記住自己在看哪個(gè)項(xiàng)目、關(guān)注哪個(gè)客戶、上次查過(guò)什么這樣后續(xù)問(wèn)題不用重復(fù)交代背景。Agent 框架天然具備解決這個(gè)問(wèn)題的結(jié)構(gòu)——記憶機(jī)制。對(duì)話記憶保存短期上下文向量記憶保存長(zhǎng)期偏好實(shí)體記憶保存用戶關(guān)注的對(duì)象。一個(gè)帶記憶的 Agent才能做到真正貼合使用者。第 3 章我會(huì)詳細(xì)展開(kāi)這塊設(shè)計(jì)。2.5 企業(yè)級(jí)安全與權(quán)限這是最容易被低估的坑RAG 早期落地時(shí)大家只顧著“答得準(zhǔn)不準(zhǔn)”忽略了一個(gè)致命問(wèn)題企業(yè)內(nèi)部知識(shí)是有權(quán)限邊界的。銷售不該看到研發(fā)內(nèi)部的缺陷報(bào)告外包人員不該接觸核心財(cái)務(wù)數(shù)據(jù)但純 RAG 把所有人的提問(wèn)都映射到了同一個(gè)知識(shí)庫(kù)上本質(zhì)上是一次信息越權(quán)通道。要堵住這個(gè)洞至少要做三層隔離檢索前校驗(yàn)提問(wèn)者身份與權(quán)限范圍檢索時(shí)按權(quán)限過(guò)濾知識(shí)庫(kù)或文檔集生成后對(duì)答案做脫敏檢查。這三層邏輯在 RAG 架構(gòu)里做起來(lái)非常別扭因?yàn)橹R(shí)庫(kù)和檢索鏈路是靜態(tài)的。但在 Agent 架構(gòu)下就順理成章了因?yàn)?Agent 本身就帶工具調(diào)用鏈路把“檢索”封裝成一個(gè)受控工具在工具內(nèi)部做權(quán)限判斷在規(guī)劃層控制工具使用范圍安全策略從“全局一把鎖”變成了“每個(gè)動(dòng)作一把鎖”。3. Agent 化改造的核心機(jī)制與架構(gòu)設(shè)計(jì)3.1 ReAct 循環(huán)Agent 的“想一步做一步”Agent 最核心的機(jī)制是 ReAct也就是 Reason Act 的循環(huán)。大模型在每一輪先分析當(dāng)前狀態(tài)、決定下一步動(dòng)作執(zhí)行動(dòng)作后觀察結(jié)果再根據(jù)結(jié)果繼續(xù)推理。這個(gè)循環(huán)可以類比成一個(gè)人查資料的過(guò)程先想“這個(gè)問(wèn)題需要查什么”然后去翻文件看到文件里提到了另一個(gè)部門又去問(wèn)那個(gè)部門的負(fù)責(zé)人最后把信息整合成答案。在工程實(shí)現(xiàn)上ReAct 循環(huán)通常由三部分組成大模型充當(dāng)推理中樞工具集提供執(zhí)行能力循環(huán)控制器負(fù)責(zé)調(diào)度。大模型輸出的是“行動(dòng)指令”比如調(diào)用 search_knowledge_base(查詢?cè)~) 或者 calculator(表達(dá)式)控制器接收指令后調(diào)用對(duì)應(yīng)的工具函數(shù)拿到真實(shí)結(jié)果后把它作為觀察信息回傳給大模型模型再?zèng)Q定是繼續(xù)行動(dòng)還是輸出最終答案。這個(gè)過(guò)程循環(huán)往復(fù)直到模型認(rèn)為信息足夠、輸出答案或者到達(dá)預(yù)設(shè)的最大迭代次數(shù)。理解 ReAct 是理解 Agent 的分水嶺。很多人以為 Agent 就是一個(gè)會(huì)調(diào) API 的聊天機(jī)器人其實(shí) Agent 的真正能力來(lái)自“規(guī)劃—執(zhí)行—觀察—再規(guī)劃”的循環(huán)每多走一輪系統(tǒng)對(duì)任務(wù)的理解就深一層。3.2 一個(gè)企業(yè)知識(shí)助手的整體架構(gòu)設(shè)計(jì)我在這里給出一個(gè)已經(jīng)在實(shí)際項(xiàng)目中穩(wěn)定跑通的架構(gòu)你可以直接作為參考。整體上分為四層接入層、Agent 編排層、工具層、知識(shí)層。接入層負(fù)責(zé)統(tǒng)一接收來(lái)自 Web 端、企業(yè)微信、釘釘或聊天界面的用戶請(qǐng)求做身份認(rèn)證與權(quán)限上下文組裝。Agent 編排層是核心大腦包含任務(wù)規(guī)劃、ReAct 循環(huán)、記憶管理三個(gè)模塊。工具層是一組可被模型調(diào)用的函數(shù)集合典型工具有知識(shí)庫(kù)檢索工具、KG 查詢工具、SQL 查詢工具、工單創(chuàng)建工具、日程工具。知識(shí)層則是底層的數(shù)據(jù)資產(chǎn)包括文檔向量庫(kù)、結(jié)構(gòu)化數(shù)據(jù)庫(kù)、知識(shí)圖譜和外部 API。這套架構(gòu)的關(guān)鍵在于知識(shí)庫(kù)不再是唯一的知識(shí)來(lái)源而是作為 Agent 的一個(gè)工具存在。模型決定“是否需要檢索、檢索什么”而不是每次問(wèn)答都強(qiáng)制檢索。這樣一來(lái)簡(jiǎn)單問(wèn)題直接用模型常識(shí)回答需要查證的問(wèn)題才走檢索工具復(fù)雜任務(wù)則自動(dòng)規(guī)劃多條行動(dòng)路徑。整個(gè)系統(tǒng)的靈活性和準(zhǔn)確性都上了一個(gè)臺(tái)階。3.3 技術(shù)選型對(duì)比LangChain、Dify 與 CrewAI 怎么選做 Agent 化改造時(shí)團(tuán)隊(duì)繞不開(kāi)框架選型的問(wèn)題。這三者的定位其實(shí)完全不同LangChain 是開(kāi)發(fā)庫(kù)Dify 是應(yīng)用平臺(tái)CrewAI 是多 Agent 編排框架。選型的關(guān)鍵是看你的團(tuán)隊(duì)在哪個(gè)層級(jí)做事情。如果你們是研發(fā)團(tuán)隊(duì)需要對(duì)流程深度定制比如自定義工具調(diào)用邏輯、精細(xì)控制 Prompt 和記憶策略選 LangChain 或者直接裸寫(xiě) LLM API 會(huì)更靈活。LangChain 的 Agent 模塊提供了 ReAct Agent、工具加載、記憶抽象但不同版本 API 變動(dòng)頻繁必須做好版本鎖定。如果團(tuán)隊(duì)更偏向業(yè)務(wù)側(cè)想快速搭一個(gè)帶 UI 的知識(shí)助手、不需要深入代碼定制Dify 這類低代碼平臺(tái)見(jiàn)效最快內(nèi)置了知識(shí)庫(kù)管理、Agent 編排和應(yīng)用發(fā)布功能。CrewAI 則適合需要多個(gè)角色協(xié)作的場(chǎng)景比如一個(gè)導(dǎo)師 Agent 加一個(gè)研究員 Agent 再加一個(gè)質(zhì)檢 Agent 協(xié)同完成復(fù)雜任務(wù)它把角色定義、任務(wù)分配、協(xié)作流程都抽象成了配置項(xiàng)。我的建議是第一個(gè)項(xiàng)目不要貪多先選一個(gè)框架跑通全鏈路。選 LangChain 要有長(zhǎng)期維護(hù)代碼的準(zhǔn)備選 Dify 要接受它的定制邊界。等到業(yè)務(wù)復(fù)雜度真正上來(lái)了再評(píng)估是否需要引入多 Agent 框架。3.4 工具定義與記憶機(jī)制Agent 的關(guān)鍵設(shè)計(jì)Agent 系統(tǒng)中的工具定義直接影響模型調(diào)用工具的準(zhǔn)確率。好的工具定義要做到三點(diǎn)名稱簡(jiǎn)短明確、描述交代清楚使用場(chǎng)景和參數(shù)含義、參數(shù)設(shè)計(jì)粒度適中。我在實(shí)踐里會(huì)把描述寫(xiě)成“什么時(shí)候用”的句式比如“當(dāng)需要查詢內(nèi)部知識(shí)庫(kù)中的非結(jié)構(gòu)化文檔時(shí)使用如產(chǎn)品手冊(cè)、運(yùn)維指南、制度文件。輸入為自然語(yǔ)言查詢?cè)~或關(guān)鍵詞?!蹦P驮谝?guī)劃時(shí)看到這樣的描述能準(zhǔn)確判斷是否該調(diào)這個(gè)工具錯(cuò)誤調(diào)用的概率長(zhǎng)時(shí)間運(yùn)行下來(lái)明顯更低。記憶機(jī)制上我強(qiáng)烈建議做三級(jí)分層。第一級(jí)是短期記憶把最近 5 到 10 輪的對(duì)話內(nèi)容放進(jìn)上下文保證多輪問(wèn)題中“剛才”這類詞能被正確解析。第二級(jí)是任務(wù)記憶把當(dāng)前任務(wù)中間結(jié)果暫存下來(lái)比如剛檢索到的文檔片段防止后續(xù)步驟重復(fù)檢索。第三級(jí)是長(zhǎng)期記憶從歷史交互中提取用戶關(guān)心的主題、常用查詢模式、偏好表達(dá)以向量形式存入知識(shí)庫(kù)在后續(xù)對(duì)話開(kāi)始時(shí)把相關(guān)舊記憶加載進(jìn)來(lái)。有這三層記憶托底助手的體驗(yàn)才能從“每次都像第一次見(jiàn)面”變成“和你合作過(guò)的老同事”。4. 開(kāi)發(fā)實(shí)戰(zhàn)從零實(shí)現(xiàn)企業(yè)知識(shí)助手4.1 環(huán)境準(zhǔn)備與項(xiàng)目結(jié)構(gòu)開(kāi)始寫(xiě)代碼前先把環(huán)境準(zhǔn)備好。我這里用的是 Python 3.10 LangChain 0.1.x OpenAI 兼容 API Chroma 向量庫(kù)這套組合足夠輕量適合第一版跑通。項(xiàng)目結(jié)構(gòu)我建議按下面這樣組織knowledge-assistant/ ├── agent/ │ ├── __init__.py │ ├── orchestrator.py # Agent 編排主邏輯 │ ├── tools/ │ │ ├── kb_search.py # 知識(shí)庫(kù)檢索工具 │ │ ├── kg_query.py # 圖譜查詢工具 │ │ └── sql_executor.py # 數(shù)據(jù)庫(kù)查詢工具 │ └── memory/ │ ├── short_term.py # 短期對(duì)話記憶 │ └── long_term.py # 長(zhǎng)期向量記憶 ├── rag/ │ ├── loader.py # 文檔加載器 │ ├── splitter.py # 文本切分器 │ ├── embedder.py # 向量化封裝 │ └── retriever.py # 混合檢索器 ├── data/knowledge/ # 原始知識(shí)文檔 ├── config.yaml # 模型與索引配置 └── main.py # 入口程序這樣的分層明確了 RAG 和 Agent 的邊界rag 目錄是檢索基礎(chǔ)設(shè)施agent 目錄是決策編排邏輯。后續(xù)你從單 Agent 擴(kuò)展為多 Agent只需要在 agent 目錄下加新角色模塊不用動(dòng)底層檢索代碼。4.2 知識(shí)庫(kù)建設(shè)文檔解析與文本切分知識(shí)庫(kù)建設(shè)的質(zhì)量決定了 RAG 的上限。首先要做的是文檔解析不同類型文檔使用不同解析器。PDF 用 PyMuPDF 提取文本層掃描件先過(guò) OCR 再提取Word 和 Markdown 直接解析文本。這里要特別注意表格的解析表格在純文本提取后結(jié)構(gòu)會(huì)丟失我的做法是把表格轉(zhuǎn)成 Markdown 表格格式保留結(jié)構(gòu)化信息這樣模型能理解行列關(guān)系。然后是文本切分。切分的核心原則是“保持語(yǔ)義完整性”常用的策略是按標(biāo)題層級(jí)切分先識(shí)別文檔的結(jié)構(gòu)把每個(gè)二級(jí)標(biāo)題下的內(nèi)容作為一個(gè)大塊再按文本長(zhǎng)度二次切分。切分參數(shù)要根據(jù)你的 Embedding 模型來(lái)定。以 text-embedding-3-small 為例它的最大輸入 token 數(shù)為 8191我一般把 chunk 設(shè)為 800 到 1200 個(gè) token重疊 100 到 150 個(gè) token。重疊的作用是防止一句話恰好被切在分界線上導(dǎo)致語(yǔ)義斷裂。切分完之后生成向量索引并存入向量庫(kù)。這里有一個(gè)容易被忽略的點(diǎn)知識(shí)文檔更新后要增量寫(xiě)入不要每次全量重建。我建議在庫(kù)里記錄每個(gè) chunk 的來(lái)源文檔和版本號(hào)重跑某篇文檔時(shí)先刪除該文檔舊版本的全部向量再寫(xiě)入新版本避免新老內(nèi)容混在一起導(dǎo)致檢索結(jié)果混亂。4.3 混合檢索解決純向量召回不準(zhǔn)的問(wèn)題我在 2.1 節(jié)提到過(guò)純向量檢索的盲區(qū)解決這個(gè)問(wèn)題的標(biāo)準(zhǔn)方案是混合檢索也就是“向量召回 關(guān)鍵詞召回 重排序”。關(guān)鍵詞部分用 BM25 這種經(jīng)典算法它擅長(zhǎng)精確匹配產(chǎn)品型號(hào)、編號(hào)這類高頻密信息向量部分負(fù)責(zé)語(yǔ)義召回最后用重排序模型把兩路結(jié)果融合排序去掉重復(fù)和低相關(guān)條目。下面這個(gè)代碼片段是一個(gè)可用的混合檢索實(shí)現(xiàn)用的是 LangChain 的 EnsembleRetrieverfrom langchain.retrievers import EnsembleRetriever from langchain_community.retrievers import BM25Retriever from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings # 向量檢索器 embeddings OpenAIEmbeddings(modeltext-embedding-3-small) vectorstore Chroma( collection_nameenterprise_kb, embedding_functionembeddings, persist_directory./chroma_db ) vector_retriever vectorstore.as_retriever(search_kwargs{k: 10}) # BM25 關(guān)鍵詞檢索器 bm25_retriever BM25Retriever.from_documents(docs) bm25_retriever.k 10 # 融合檢索向量和關(guān)鍵詞各取 10 條按權(quán)重合并 ensemble_retriever EnsembleRetriever( retrievers[bm25_retriever, vector_retriever], weights[0.3, 0.7] ) docs ensemble_retriever.invoke(SG-2000 的認(rèn)證信息有哪些)融合之后我還會(huì)用重排序模型對(duì)結(jié)果做一次精排。推薦使用 bge-reranker 這類開(kāi)源模型它對(duì)“查詢-文檔”對(duì)打分能把最相關(guān)的內(nèi)容頂?shù)阶钋懊?。RAG 鏈路中檢索結(jié)果前三位決定了答案質(zhì)量的 80%重排序絕對(duì)值得投入。4.4 實(shí)現(xiàn) RAG 基線問(wèn)答鏈路在升級(jí) Agent 之前先把 RAG 基線做出來(lái)方便后續(xù)做效果對(duì)比。RAG 的核心鏈路是“檢索增強(qiáng)的問(wèn)答鏈”。用 LangChain 的 create_retrieval_chain 可以快速搭起來(lái)但我更推薦自定義鏈路因?yàn)槠髽I(yè)場(chǎng)景往往需要在檢索之后、生成之前做一些后處理。下面是一個(gè)簡(jiǎn)潔可用的自定義 RAG 鏈路from langchain_openai import ChatOpenAI from langchain.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough, RunnableLambda prompt ChatPromptTemplate.from_messages([ (system, 你是一名企業(yè)知識(shí)助手。請(qǐng)僅根據(jù)以下參考資料回答問(wèn)題。 如果資料中沒(méi)有相關(guān)內(nèi)容請(qǐng)直接回答“根據(jù)現(xiàn)有知識(shí)庫(kù)無(wú)法回答該問(wèn)題”。 參考資料 {context}), (human, 問(wèn)題{question}) ]) def format_docs(docs): return \n\n.join([d.page_content for d in docs]) rag_chain ( { context: ensemble_retriever | RunnableLambda(format_docs), question: RunnablePassthrough(), } | prompt | ChatOpenAI(modelgpt-4o-mini, temperature0.3) ) result rag_chain.invoke(SG-2000 的認(rèn)證信息有哪些) print(result.content)這里 temperature 我設(shè)置得比較低知識(shí)問(wèn)答場(chǎng)景里不希望模型自由發(fā)揮0.3 是一個(gè)平衡點(diǎn)。System Prompt 里的“回答不出就直說(shuō)”這句約束也很有必要能有效減少幻覺(jué)。4.5 升級(jí) Agent工具調(diào)用與任務(wù)編排RAG 鏈路跑通后開(kāi)始做 Agent 化。第一步是把知識(shí)檢索封裝成工具。在 LangChain 里工具的本質(zhì)是一個(gè)帶文檔字符串的函數(shù)模型通過(guò)讀函數(shù)名和文檔字符串來(lái)決定是否調(diào)用、怎么調(diào)用。這是知識(shí)庫(kù)檢索工具的定義from langchain_core.tools import tool tool def search_knowledge_base(query: str, top_k: int 5) - str: 當(dāng)需要查詢企業(yè)內(nèi)部知識(shí)庫(kù)時(shí)使用。 知識(shí)庫(kù)涵蓋產(chǎn)品手冊(cè)、運(yùn)維指南、制度文件、項(xiàng)目文檔等非結(jié)構(gòu)化資料。 輸入應(yīng)為自然語(yǔ)言描述的信息需求。 docs ensemble_retriever.invoke(query)[:top_k] return \n\n.join( f[來(lái)源: {d.metadata.get(source, 未知)}]\n{d.page_content} for d in docs )注意返回內(nèi)容里我加了來(lái)源信息這個(gè)做法非常有用。模型在生成答案時(shí)能夠引用來(lái)源文檔用戶在查看答案時(shí)也能溯源企業(yè)場(chǎng)景里“可追溯”是剛需。工具準(zhǔn)備好后用 create_tool_calling_agent 把這個(gè)工具注入 Agentfrom langchain.agents import create_tool_calling_agent, AgentExecutor from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate agent_prompt ChatPromptTemplate.from_messages([ (system, 你是一個(gè)企業(yè)知識(shí)助手。你可以調(diào)用知識(shí)庫(kù)工具獲取信息 也可以根據(jù)需要使用計(jì)算和其他已注冊(cè)工具。請(qǐng)一步步完成任務(wù)并在最終回答中注明信息來(lái)源。), (placeholder, {chat_history}), (human, {input}), (placeholder, {agent_scratchpad}), ]) agent create_tool_calling_agent( llmChatOpenAI(modelgpt-4o, temperature0.2), tools[search_knowledge_base], promptagent_prompt ) agent_executor AgentExecutor( agentagent, tools[search_knowledge_base], verboseTrue, max_iterations5, return_intermediate_stepsTrue )max_iterations 設(shè)置成 5 是為了防止 Agent 在某個(gè)查詢里無(wú)限循環(huán)。return_intermediate_steps 打開(kāi)后可以拿到 Agent 的完整思考鏈這個(gè)信息在調(diào)試階段非常寶貴。真正讓 Agent 比 RAG 強(qiáng)的場(chǎng)景是復(fù)雜任務(wù)。比如“請(qǐng)幫我查一下 SG-2000 的維護(hù)手冊(cè)中關(guān)于潤(rùn)滑保養(yǎng)的部分并總結(jié)成一段可以直接發(fā)給客戶的說(shuō)明”。Agent 會(huì)先調(diào)用知識(shí)庫(kù)工具檢索“SG-2000 維護(hù)手冊(cè) 潤(rùn)滑保養(yǎng)”拿到內(nèi)容后根據(jù)“直接發(fā)給客戶”這個(gè)要求重寫(xiě)語(yǔ)氣與措辭。這種“檢索改寫(xiě)面向場(chǎng)景調(diào)整”的組合是 RAG 鏈路很難做到的任務(wù)級(jí)能力。4.6 權(quán)限與安全的工程落地Agent 化之后安全策略要同步升級(jí)。我在實(shí)際項(xiàng)目中使用了三層防護(hù)每一層都簡(jiǎn)單但有效。第一層是工具級(jí)別的權(quán)限控制。所有檢索類工具的輸入?yún)?shù)帶上 user_context在工具內(nèi)部判斷該用戶是否有權(quán)訪問(wèn)目標(biāo)知識(shí)集。實(shí)現(xiàn)方式是給知識(shí)文檔打上權(quán)限標(biāo)簽檢索時(shí)過(guò)濾掉無(wú)權(quán)訪問(wèn)的標(biāo)簽。第二層是數(shù)據(jù)脫敏。檢索結(jié)果送入模型之前用正則和敏感詞庫(kù)過(guò)濾手機(jī)號(hào)、身份證號(hào)等個(gè)人信息防止模型在回答中意外輸出敏感字段。第三層是輸出審計(jì)。Agent 的每輪思考與最終回答寫(xiě)入日志API 層面設(shè)置內(nèi)容安全審核策略也就是“可以不給答案但絕不能給錯(cuò)答案、給越權(quán)答案”。注意企業(yè)知識(shí)助手上線前一定要做一次覆蓋“人員離職權(quán)限回收”“跨部門文檔訪問(wèn)”“工具調(diào)用頻率控制”的完整安全評(píng)審。技術(shù)上的安全問(wèn)題都好解決組織層面的權(quán)限定義才是復(fù)雜來(lái)源建議在早期就與業(yè)務(wù)方對(duì)齊權(quán)限模型。5. 常見(jiàn)問(wèn)題與排查技巧實(shí)錄5.1 檢索質(zhì)量差召回內(nèi)容不相關(guān)或關(guān)鍵信息缺失排查檢索問(wèn)題我有一套固定的診斷順序。第一步看召回結(jié)果本身把檢索器返回的前幾條內(nèi)容和問(wèn)題擺在一起看如果問(wèn)題相關(guān)但內(nèi)容不相關(guān)問(wèn)題出在向量化或切分上如果內(nèi)容相關(guān)但答案不準(zhǔn)問(wèn)題出在生成環(huán)節(jié)如果連內(nèi)容都不相關(guān)問(wèn)題基本出在查詢理解上。查詢理解是 RAG 項(xiàng)目里最容易被低估的環(huán)節(jié)。用戶口語(yǔ)化的提問(wèn)方式和文檔中的術(shù)語(yǔ)表達(dá)差異很大直接拿用戶原話去檢索經(jīng)常找不到東西。解決辦法有幾個(gè)用同義詞擴(kuò)展改寫(xiě)查詢?cè)~把口語(yǔ)轉(zhuǎn)換成文檔術(shù)語(yǔ)根據(jù)歷史檢索日志做查詢分析找出高頻檢索失敗的模式或者更簡(jiǎn)單直接在 Agent 規(guī)劃環(huán)節(jié)增加一個(gè)“查詢優(yōu)化”動(dòng)作讓模型先改寫(xiě)檢索詞再執(zhí)行檢索。5.2 切分參數(shù)怎么調(diào)chunk 大小和重疊的正確思路很多團(tuán)隊(duì)問(wèn) chunk_size 到底設(shè)多少合適。這個(gè)參數(shù)沒(méi)有標(biāo)準(zhǔn)答案取決于知識(shí)文檔的類型和 Embedding 模型能力。我的經(jīng)驗(yàn)判斷文檔邏輯塊比較獨(dú)立、每塊信息密度高用小塊400 到 600 token文檔敘述性強(qiáng)、需要上下文連續(xù)用大塊1000 到 1500 token。重疊長(zhǎng)度一般設(shè)置為 chunk 的 10% 到 15%。判斷切分效果好壞有一個(gè)快速辦法隨機(jī)抽一批用戶問(wèn)題一個(gè)個(gè)去檢索器里查看召回的前幾條內(nèi)容是否覆蓋了答案的所有必要信息。覆蓋率達(dá)不到 80% 以上就先別急著調(diào) Prompt問(wèn)題大概率在檢索端也就是切分和索引上。RAG 領(lǐng)域有句老話垃圾進(jìn)去垃圾出來(lái)召回的內(nèi)容不完整模型再聰明也編不出正確答案。5.3 知識(shí)庫(kù)能存圖片嗎多模態(tài)問(wèn)題的邊界這個(gè)問(wèn)題被問(wèn)到的頻率非常高。答案是可以但不能像存文本一樣簡(jiǎn)單。向量數(shù)據(jù)庫(kù)本質(zhì)上存的是向量和文本元數(shù)據(jù)圖片本身不直接進(jìn)庫(kù)??尚械淖龇ㄓ腥龡l路。第一把圖片轉(zhuǎn)成文本描述再入庫(kù)適合流程圖、架構(gòu)圖這類需要語(yǔ)義理解的圖用視覺(jué)語(yǔ)言模型生成描述文本。第二走多模態(tài) Embedding把圖片和文本映射到同一個(gè)向量空間檢索時(shí)圖文可以互相召回不過(guò)這類模型在企業(yè)內(nèi)網(wǎng)部署還有不少限制。第三圖片作為附件引用向量庫(kù)里存圖片路徑和上下文描述回答時(shí)輸出圖片鏈接。需要說(shuō)明的是如果圖片里包含表格或文字信息先做 OCR 提取文本比直接圖片入庫(kù)更實(shí)用。比如掃描版 PDF 中的報(bào)表OCR 結(jié)果進(jìn)入文本索引原始圖片作為閱讀附件檢索命中率會(huì)高得多。5.4 Agent 工具調(diào)用失靈的排查思路Agent 類問(wèn)題最常見(jiàn)的表現(xiàn)是模型該調(diào)工具時(shí)不調(diào)或者調(diào)用了錯(cuò)誤的工具參數(shù)。遇到這類問(wèn)題不要急著改 Prompt先檢查工具定義本身。工具名稱是否清晰表達(dá)了功能描述里是否說(shuō)明了“什么時(shí)候用”而不只是“是什么”參數(shù)名和描述是否讓模型容易理解工具多了之后模型的選擇難度也升高建議每個(gè) Agent 掛載的工具數(shù)量控制在 5 個(gè)以內(nèi)業(yè)務(wù)擴(kuò)大后拆分成多個(gè)專業(yè) Agent 比不斷增加單個(gè) Agent 的工具數(shù)更可靠。另外日志是你最好的調(diào)試工具。我強(qiáng)烈建議把 AgentExecutor 的 verbose 打開(kāi)把每輪思考、動(dòng)作、觀察完整記錄下來(lái)。問(wèn)題發(fā)生后順著 ReAct 軌跡一步步看就能定位是模型規(guī)劃錯(cuò)了還是工具返回了空結(jié)果還是返回結(jié)果太長(zhǎng)超出了上下文窗口。大多數(shù) Agent 問(wèn)題三分鐘看日志就能定位個(gè)八九成。6. 踩坑心得團(tuán)隊(duì)落地知識(shí)助手的幾點(diǎn)忠告6.1 先定評(píng)估標(biāo)準(zhǔn)再開(kāi)始做優(yōu)化這是我特別想強(qiáng)調(diào)的一點(diǎn)。很多團(tuán)隊(duì)一上來(lái)就調(diào) Prompt、換模型、調(diào)切分參數(shù)搞了半個(gè)月效果也不知道變好還是變差。正確做法是先建立一套評(píng)估集選取 100 到 300 條覆蓋核心場(chǎng)景的真實(shí)問(wèn)題每條標(biāo)注期望答案和檢索參考文檔。每次改動(dòng)后在評(píng)估集上跑一遍計(jì)算召回率、答案準(zhǔn)確率和無(wú)答案率。沒(méi)有評(píng)估集的優(yōu)化都是自我感覺(jué)良好有了評(píng)估集每一次改動(dòng)是變好還是變差立刻見(jiàn)分曉。評(píng)估集的來(lái)源最好是真實(shí)用戶問(wèn)題。第一版可以先從業(yè)務(wù)部門收集問(wèn)題后續(xù)上線后持續(xù)從日志里抽一批新的、經(jīng)過(guò)用戶反饋確認(rèn)的問(wèn)題加入評(píng)估集。三個(gè)月后你的評(píng)估集會(huì)成為判斷系統(tǒng)健康度的最重要資產(chǎn)。6.2 從單 Agent 到多 Agent 要克制很多人做完第一個(gè)單 Agent 知識(shí)助手之后馬上就想上多 Agent讓一個(gè)“管理員 Agent”去調(diào)度多個(gè)專業(yè) Agent。我的經(jīng)驗(yàn)是先用最少一個(gè) Agent 的架構(gòu)跑通業(yè)務(wù)閉環(huán)只有當(dāng)出現(xiàn)以下三種情況再考慮拆分——工具數(shù)量太多導(dǎo)致模型選擇困難不同任務(wù)類型需要差異很大的 Prompt 和記憶策略多個(gè)任務(wù)環(huán)節(jié)需要并行處理或者輪流質(zhì)檢。拆分時(shí)也要注意多 Agent 之間的通信、上下文共享、沖突仲裁都是新問(wèn)題復(fù)雜度是線性往上漲的。先小步快跑別為了架構(gòu)的“高級(jí)感”而提前引入復(fù)雜度。我個(gè)人的體會(huì)是企業(yè)知識(shí)助手這個(gè)項(xiàng)目最大的難點(diǎn)從來(lái)不是模型多聰明而是知識(shí)工程做得多細(xì)致、工程鏈路做得多扎實(shí)。RAG 解決的是知識(shí)怎么到達(dá)模型的問(wèn)題Agent 解決的是任務(wù)怎么完成的問(wèn)題兩者是遞進(jìn)關(guān)系。把檢索質(zhì)量做扎實(shí)了Agent 才有可靠的工具可用把 Agent 規(guī)劃做好了RAG 才有智能的調(diào)度者。建議你按照本文的順序先搭 RAG 基線建立評(píng)估集再逐步加 Agent 能力每一步都用真實(shí)問(wèn)題驗(yàn)證效果穩(wěn)扎穩(wěn)打地往前推進(jìn)。