文檔打造知識庫Agent主線:從切塊到混合檢索全拆解)
手頭只有一份66頁的工業(yè)庫卻把它做成了一條完整的知識庫Agent主線。這件事做完以后我反而把知識庫Agent這件事想明白了——它能不能跑起來跟文檔數(shù)量多少沒有決定關(guān)系而是看你能不能把每一個(gè)知識塊都處理到位。這里說的工業(yè)庫不是某種數(shù)據(jù)庫產(chǎn)品而是工業(yè)現(xiàn)場最常見的文檔集合設(shè)備參數(shù)手冊、標(biāo)準(zhǔn)操作規(guī)程、報(bào)警響應(yīng)預(yù)案、安全注意事項(xiàng)雜七雜八湊一起就66頁。系統(tǒng)最終能穩(wěn)定回答設(shè)備參數(shù)查詢、異常處置步驟、標(biāo)準(zhǔn)依據(jù)核對這些高頻問題每個(gè)答案還能給出文檔頁碼出處。這篇文章就把這條主線的完整拆解過程寫出來給想用小體量知識庫起步做Agent的人一個(gè)參照。1. 項(xiàng)目解剖66頁工業(yè)庫為何能長成Agent主線1.1 這66頁工業(yè)庫到底是什么我先說清楚這份66頁的底料長什么樣因?yàn)樗途W(wǎng)上常見的“通用知識庫”差別很大。它不是一個(gè)單一的PDF文件而是好幾類文檔拼起來的一是核心設(shè)備的參數(shù)表和技術(shù)手冊選頁里面全是型號、額定電壓、功率、壓力范圍這類數(shù)值二是一套標(biāo)準(zhǔn)操作流程也就是工業(yè)現(xiàn)場常說的SOP規(guī)定某個(gè)操作按什么順序做、每步注意什么三是報(bào)警值和異?,F(xiàn)象對照表比如哪個(gè)報(bào)警代碼對應(yīng)什么故障、該怎么處置四是安全注意事項(xiàng)和應(yīng)急響應(yīng)預(yù)案。這些內(nèi)容在主題上高度強(qiáng)相關(guān)都在回答同一個(gè)車間里操作人員會遇到的日常問題但格式完全不統(tǒng)一有橫版表格、有帶層級編號的條款、有流程圖截圖。工業(yè)庫的特點(diǎn)就是“數(shù)字化程度低但專業(yè)要求極高”大量縮寫、中英混排、數(shù)值范圍、版本號而且知識更新的節(jié)奏說變就變——設(shè)備一改型、標(biāo)準(zhǔn)一改版舊文檔就得下線。更關(guān)鍵的是答錯(cuò)代價(jià)不同。通用知識庫答錯(cuò)一句也就是用戶覺得不準(zhǔn)工業(yè)知識庫要是答錯(cuò)一個(gè)報(bào)警閾值操作工照著回答去處理設(shè)備后果可能是設(shè)備損壞甚至安全事故。所以這個(gè)項(xiàng)目從一開始就定了底線每個(gè)回答必須有出處沒有出處的回答寧可不說。這也決定了后面所有技術(shù)選型都圍繞“可溯源、可驗(yàn)證、可更新”來展開。1.2 為什么用知識庫Agent而不是“讓大模型背下全本”有人會問66頁內(nèi)容這么少直接把全文塞給大模型讓它回答不就行了我分別解釋一下為什么三條路都沒走。第一條路是微調(diào)。讓大模型把這66頁背下來聽起來很誘人但工業(yè)文檔的高頻操作是“改版”今天參數(shù)表更新一頁明天SOP修訂一條每次改動都重新微調(diào)一輪時(shí)間和算力成本都不可接受。而且微調(diào)后的模型是黑盒回答沒有出處運(yùn)維人員根本不敢拿來做操作依據(jù)。66頁的數(shù)據(jù)量對于微調(diào)來說也遠(yuǎn)遠(yuǎn)不夠很容易學(xué)歪。第二條路是長上下文直讀。把66頁文本全部塞進(jìn)上下文窗口模型確實(shí)能看到但有兩個(gè)問題一是長篇文檔中的具體數(shù)值會被上下文稀釋提問“3號空壓機(jī)排氣壓力上限是多少”模型很可能把4號設(shè)備的數(shù)據(jù)混進(jìn)來二是沒有檢索定位能力每次回答都要重新處理全文延遲高也無法指出“依據(jù)在第34頁”。第三條路就是知識庫Agent也就是我這篇文章說的主線。它本質(zhì)上是一個(gè)“檢索增強(qiáng)生成”的框架但比普通的單次RAG多了一層Agent能力。普通RAG是“用戶問一句、檢索一次、生成一次”工業(yè)場景下的真實(shí)提問往往一句話里藏著好幾個(gè)子問題。比如“空壓機(jī)排氣溫度高報(bào)警到底怎么處置”這個(gè)問題實(shí)際上需要三步先確認(rèn)空壓機(jī)型號對應(yīng)的正常溫度范圍和報(bào)警閾值再查對應(yīng)型號的處置步驟最后補(bǔ)充安全注意事項(xiàng)。單次檢索很可能只命中其中一段剩下的靠模型瞎猜。知識庫Agent做的事情就是把“一次提問、多次檢索、按需匯總”變成一套可控流程讓問題拆解、檢索調(diào)用、答案驗(yàn)證每個(gè)環(huán)節(jié)都透明可見。2. 工業(yè)文檔的知識化加工從66頁到可檢索的知識塊2.1 文檔清洗有三件事必須親自做知識庫Agent的地基是文檔本身。66頁文檔不多但這恰恰是優(yōu)勢——我有精力把每一頁都人工過一遍。清洗階段有三件事偷懶不得。第一件事是解析與轉(zhuǎn)文本。PDF用pdfplumber或PyMuPDF轉(zhuǎn)成文本橫版表格直接用文本解析很容易錯(cuò)亂需要專門的表格抽取工具。我那份文檔里有一頁是設(shè)備參數(shù)總表直接用通用解析器抽出來列和行全錯(cuò)位單位也丟了最后是用表格識別工具加人工校對才恢復(fù)原樣。工業(yè)文檔里的數(shù)字和計(jì)量單位是生命線這里出錯(cuò)后面檢索做得再好都是白搭。第二件事是清理噪音。頁眉頁腳、目錄頁碼、水印、殘留換行、制表符這些都會污染切塊結(jié)果。尤其是OCR出來的文檔錯(cuò)別字要逐頁抽查我曾經(jīng)遇到過“MPa”被識別成“M Pa”一個(gè)空格之差檢索時(shí)關(guān)鍵詞完全匹配不上。這種錯(cuò)誤靠模型自動修是修不干凈的必須人工盯一遍關(guān)鍵數(shù)值和單位。第三件事是結(jié)構(gòu)還原。工業(yè)文檔普遍有清晰的標(biāo)題層級和編號體系比如“3.2.1 濾芯更換步驟”。要把這些層級關(guān)系提取出來構(gòu)建成“文件—章節(jié)—小節(jié)—段落”的樹狀結(jié)構(gòu)。這一步有兩層價(jià)值一是后面檢索時(shí)可以按章節(jié)做粗過濾把搜索范圍大幅縮小二是每一段文本都帶著章節(jié)路徑回答時(shí)引用位置就能寫到“第3.2.1節(jié)”這種級別而不是籠統(tǒng)說“某個(gè)文檔里提到了”。清洗完成之后要給每個(gè)知識塊設(shè)計(jì)元數(shù)據(jù)。我的做法是每個(gè)塊固定掛六個(gè)字段來源文件名、版本號、章節(jié)路徑、頁碼、內(nèi)容類型正文/表格/步驟、創(chuàng)建時(shí)間。這些字段決定了后續(xù)檢索過濾、版本隔離、引用格式能否落地越早定越好。等索引建完再回頭補(bǔ)元數(shù)據(jù)等于重做一遍。2.2 切塊策略三個(gè)參數(shù)如何定切塊是知識庫Agent里最容易被低估的環(huán)節(jié)。很多人以為隨便按固定字?jǐn)?shù)切就行實(shí)際上一旦切錯(cuò)后面所有環(huán)節(jié)都在錯(cuò)誤的數(shù)據(jù)上做文章效果怎么調(diào)都上不去。先解釋為什么要切塊。Embedding模型對輸入長度有限制當(dāng)前常用的中文向量模型一般在8192個(gè)token以內(nèi)但即使沒超過上限太長的文本經(jīng)過向量化后語義會被“平均”稀釋——一段512字的文本里可能包含三個(gè)不同主題向量最終呈現(xiàn)的是三個(gè)主題混在一起的模糊語義檢索時(shí)哪個(gè)都命不準(zhǔn)。檢索的目標(biāo)是“返回和問題最相關(guān)的局部片段”不是“返回包含答案的整個(gè)章節(jié)”所以切塊粒度直接決定召回質(zhì)量。我用的切塊策略可以總結(jié)為“結(jié)構(gòu)優(yōu)先、定長兜底”。具體分四步用文檔的標(biāo)題層級先把整份文檔切成大塊保證同一個(gè)大塊內(nèi)主題一致。大塊內(nèi)部如果超過閾值再按自然段落分割。段落仍然超長時(shí)用定長滑動窗口兜底。相鄰塊之間設(shè)置一定重疊防止上下文在切縫處斷裂。三個(gè)核心參數(shù)里chunk_size和overlap是繞不開的。中文工業(yè)文檔我建議以“字符數(shù)”而不是token數(shù)來衡量中文字符和token的比例大約是1:1.5直接按token切容易把一句話攔腰截?cái)?。我的參?shù)范圍供參考chunk_size取512到768字符overlap取64到128字符。塊太大會混入無關(guān)信息塊太小則語義不完整比如“禁止在未泄壓狀態(tài)下拆卸”本來是一個(gè)完整的安全警告切成“禁止在未泄壓”和“狀態(tài)下拆卸”兩塊語義就廢了。另一個(gè)關(guān)鍵點(diǎn)是表格的切法。工業(yè)文檔里的表格是“另一條主線”不能和普通文本混在一起切。一個(gè)表格應(yīng)該作為一個(gè)整體塊保留包括表頭、單位和備注說明如果表格行數(shù)太多必須按行切每一行都要冗余攜帶表頭信息。這個(gè)做法反直覺但非常有用否則“22.8”這個(gè)數(shù)字脫離列名和單位之后誰都不知道它是什么。2.3 向量索引與檢索接口選型清洗和切塊完成后下一步就是把知識塊向量化并建立索引。向量模型我選了BGE-M3中文效果好而且是開源模型支持稠密向量和稀疏向量兩種表示后面做混合檢索時(shí)同一個(gè)模型就能輸出兩種索引省了不少事。如果環(huán)境受限、下載不了大模型退而求其次用text2vec-base-chinese也能跑起來只是準(zhǔn)確率會打些折扣。66頁文檔切出來的知識塊數(shù)量很小大概也就幾百個(gè)塊用FAISS內(nèi)存索引完全夠用連獨(dú)立的向量數(shù)據(jù)庫服務(wù)都不用部署。但我還是把檢索接口封裝成了一個(gè)獨(dú)立服務(wù)。這么做的原因很樸素項(xiàng)目起步只有66頁后面一定會擴(kuò)展到更多設(shè)備手冊如果一開始就把索引邏輯寫死在業(yè)務(wù)代碼里后面擴(kuò)展時(shí)就得重構(gòu)。把檢索抽象成獨(dú)立接口后續(xù)換成Milvus或者Qdrant只需要替換底層實(shí)現(xiàn)上層Agent的代碼一行都不用動。索引建設(shè)的代碼邏輯大致是這樣的from pymupdf import open as pdf_open from bge_m3 import BGEM3EmbeddingModel doc pdf_open(industrial_lib_v2.pdf) blocks extract_structured_blocks(doc) # 返回帶元數(shù)據(jù)的知識塊列表 model BGEM3EmbeddingModel(model_nameBAAI/bge-m3) chunk_texts [b[text] for b in blocks] embeddings model.encode(chunk_texts)[dense_vecs] # 每個(gè)塊保存文本和元數(shù)據(jù) for idx, block in enumerate(blocks): block[embedding] embeddings[idx] block[id] fblock_{idx} # 寫入FAISS索引 import faiss import numpy as np dim embeddings.shape[1] index faiss.IndexFlatIP(dim) faiss.normalize_L2(embeddings) index.add(embeddings) faiss.write_index(index, industrial_blocks.index)要強(qiáng)調(diào)的是Embedding模型選型不是一勞永逸的。換了模型后必須重建索引否則新舊向量不在同一個(gè)語義空間里檢索結(jié)果會變得毫無意義。踩過一次坑之后我把索引重建做成了流水線上的固定步驟每次更新Embedding版本都跑一遍全量重建。3. 檢索與生成的Agent閉環(huán)核心實(shí)現(xiàn)拆解3.1 混合檢索向量不夠BM25兜底工業(yè)庫檢索有個(gè)很實(shí)際的痛點(diǎn)純向量檢索對專有名詞和縮寫不友好。像“SOP”“PLC”“HVAC”這種縮寫以及“A/B-3000”這種帶特殊符號的型號Embedding模型經(jīng)常把它們當(dāng)成普通詞組導(dǎo)致語義相近的段落湊上來精確匹配的段落反而排到后面去。解決辦法是混合檢索。向量檢索負(fù)責(zé)捕捉語義相關(guān)性BM25這類稀疏檢索負(fù)責(zé)精確匹配專有名詞最后把兩路結(jié)果融合排序。融合用的算法是RRFReciprocal Rank Fusion原理不復(fù)雜每個(gè)文檔在兩路結(jié)果里都有一個(gè)排名融合分?jǐn)?shù)就是每個(gè)排名倒數(shù)之和排名越靠前貢獻(xiàn)越大。這樣語義和關(guān)鍵詞兩條線索都能發(fā)揮各自優(yōu)勢不會被某一方的偏差帶偏。核心邏輯長這樣from rank_bm25 import BM25Okapi # 用BGE-M3的sparse_vecs同時(shí)做BM25式匹配 bm25 BM25Okapi(tokenized_chunks) def hybrid_search(query, top_k5): query_vec embedding_model.encode([query])[dense_vecs] dense_scores, dense_indices faiss_index.search(query_vec, top_k) bm25_scores bm25.get_scores(tokenize(query)) top_bm25 sorted(range(len(bm25_scores)), keylambda i: bm25_scores[i], reverseTrue)[:top_k] # RRF融合 fused {} for rank, idx in enumerate(dense_indices[0]): fused[idx] fused.get(idx, 0) 1 / (60 rank) for rank, idx in enumerate(top_bm25): fused[idx] fused.get(idx, 0) 1 / (60 rank) return sorted(fused.items(), keylambda x: x[1], reverseTrue)[:top_k]實(shí)測下來加了BM25混合檢索之后像“報(bào)警代碼E-204”聯(lián)合“處置建議”這種查詢精準(zhǔn)命中率提升非常明顯。純向量檢索經(jīng)常把“報(bào)警代碼”相關(guān)的其他段落也排上來但精確帶著“E-204”的那一段反而沉在下面。工業(yè)文檔里大量存在“型號故障”這種組合查詢BM25對這類模式就是天然的強(qiáng)項(xiàng)。3.2 Agent如何把“一個(gè)難題”拆成“幾次查詢”知識庫Agent和普通RAG最核心的區(qū)別在于它把LLM從“直接答題的人”變成了“調(diào)度問題的人”。用戶提一個(gè)復(fù)雜問題Agent先判斷這個(gè)問題需要哪些信息再決定調(diào)用幾次檢索工具最后匯總成答案。我用一個(gè)實(shí)際例子說明。用戶問“空壓機(jī)排氣溫度高報(bào)警怎么處置”這個(gè)問題的正確回答需要三塊知識空壓機(jī)型號對應(yīng)的排氣溫度正常范圍、報(bào)警閾值、對應(yīng)型號的處置步驟。如果只做一次檢索返回的可能是報(bào)警處置步驟也可能是參數(shù)表里的溫度范圍反正很難一次拿全。Agent的做法是把一個(gè)問題改寫成三個(gè)子查詢子查詢一空壓機(jī)XX型號排氣溫度報(bào)警閾值是多少子查詢二排氣溫度高報(bào)警的處置步驟子查詢?nèi)諌簷C(jī)高溫報(bào)警的安全注意事項(xiàng)每個(gè)子查詢單獨(dú)走一遍檢索把三段結(jié)果拼接起來再讓LLM組織成完整回答。這樣每一步檢索都是精準(zhǔn)的最后給出的答案信息完整、邏輯連貫而不是大段堆砌無關(guān)內(nèi)容。要想讓Agent正確地做多步檢索關(guān)鍵在于工具定義寫得到位。LangChain或自建Agent框架里每個(gè)工具有一個(gè)descriptionLLM就是靠這個(gè)描述來決定何時(shí)調(diào)用工具的。描述寫得太簡略比如“知識庫檢索工具”模型就很容易在第一次檢索拿到不相關(guān)內(nèi)容后直接放棄或者反復(fù)調(diào)用同一個(gè)工具碰運(yùn)氣。我會寫清楚這個(gè)工具能搜什么、什么時(shí)候用、返回什么格式。工具定義示意tools [ { name: search_kb, description: 在工業(yè)知識庫中檢索設(shè)備參數(shù)、操作流程、報(bào)警處置、安全注意事項(xiàng)。 當(dāng)用戶問題涉及具體設(shè)備型號、數(shù)值范圍、操作步驟時(shí)必須調(diào)用此工具。 支持傳入關(guān)鍵詞組合例如空壓機(jī) 排氣溫度 報(bào)警閾值。, parameters: {query: string} } ] def agent_loop(user_query, memory): # 1. 判斷是否需要拆解子問題 sub_queries plan_subqueries(user_query, memory) # 2. 逐個(gè)子查詢調(diào)用檢索工具 contexts [] for sub_q in sub_queries: results search_kb(sub_q, top_k3) contexts.extend(results) # 3. 生成帶引用的最終回答 answer generate_with_sources(user_query, contexts) return answer還需要處理多輪對話記憶。工業(yè)場景下用戶不太會一句話把所有信息說全更常見的是“3號空壓機(jī)排氣溫度高報(bào)警了怎么辦”Agent回答完之后用戶接著問“那壓力上限呢”。如果不記憶上一輪的設(shè)備型號這個(gè)問題就失去了主語。我在會話狀態(tài)里維護(hù)了兩個(gè)變量——“當(dāng)前設(shè)備型號”和“當(dāng)前討論故障”每當(dāng)識別到新的設(shè)備型號就更新后續(xù)提問如果缺少主語自動從會話狀態(tài)中補(bǔ)全。這個(gè)小功能看著不起眼但操作工用起來會明顯覺得“這個(gè)機(jī)器人是懂上下文的”。3.3 回答紀(jì)律提示詞里寫死的三條底線知識庫Agent的LLM生成環(huán)節(jié)提示詞設(shè)計(jì)不能只考慮“答得準(zhǔn)”更要考慮“答得安全”。工業(yè)場景下我直接寫死了三條紀(jì)律。第一條是強(qiáng)制引用。回答中涉及的所有具體參數(shù)、步驟、報(bào)警代碼必須附上引用來源格式為“依據(jù)文件名 第X頁 第X節(jié)”。這不僅是可解釋性問題更是合規(guī)問題。操作工需要一個(gè)可以翻紙質(zhì)手冊復(fù)核的答案而不是一個(gè)“看起來對但找不到依據(jù)”的結(jié)論。第二條是找不到就明說。如果檢索到的上下文不足以支撐回答模型必須輸出“該問題在當(dāng)前知識庫中沒有找到明確依據(jù)請轉(zhuǎn)人工確認(rèn)后再執(zhí)行操作”而不是基于通用知識自行推斷。工業(yè)領(lǐng)域最大的風(fēng)險(xiǎn)不是“答不上來”而是“答錯(cuò)了還理直氣壯”。我把這條寫進(jìn)提示詞后無依據(jù)亂答的比例大幅下降。第三條是安全操作加現(xiàn)場確認(rèn)。凡是涉及設(shè)備操作、安全閾值、應(yīng)急處置的回答結(jié)尾自動追加一句“具體操作請結(jié)合現(xiàn)場設(shè)備狀態(tài)和本地操作規(guī)程確認(rèn)”。這句話不是廢話它是在暗示用戶系統(tǒng)給出的內(nèi)容是知識庫中的標(biāo)準(zhǔn)規(guī)定但現(xiàn)場可能有標(biāo)準(zhǔn)之外的特殊情況操作前必須二次確認(rèn)。給出一段可以直接參考的回答提示詞模板你是一個(gè)工業(yè)知識庫問答助手。請嚴(yán)格遵循以下規(guī)則 1. 只依據(jù)上下文檢索片段回答不得使用訓(xùn)練數(shù)據(jù)中的通用知識。 2. 回答中涉及參數(shù)、報(bào)警代碼、操作步驟時(shí)必須標(biāo)注引用來源格式為依據(jù)文件名 第X頁。 3. 如果上下文不足以回答用戶問題明確回復(fù)“該問題在當(dāng)前知識庫中沒有找到明確依據(jù)請轉(zhuǎn)人工確認(rèn)后再執(zhí)行操作?!?4. 涉及設(shè)備操作、安全閾值、應(yīng)急處置的回答結(jié)尾必須追加“具體操作請結(jié)合現(xiàn)場設(shè)備和本地操作規(guī)程確認(rèn)?!?5. 用簡潔的中文回答不要重復(fù)問題不要展開與問題無關(guān)的內(nèi)容。這套提示詞實(shí)際跑下來回答風(fēng)格變得非?!翱酥啤鄙踔劣袝r(shí)候顯得啰嗦但用戶接受度反而更高。工業(yè)場景的訴求是“我不需要你聰明我需要你靠譜”這三條紀(jì)律就是朝著靠譜去的。4. 實(shí)測評估與調(diào)優(yōu)從“能用”到“敢用”4.1 三類測試問題與評估指標(biāo)知識庫Agent做出來能不能上線不能靠“感覺還行”必須有一套可量化的評估標(biāo)準(zhǔn)。我把測試問題分成三類每類準(zhǔn)備30條。第一類是事實(shí)查詢型問的是“XX設(shè)備額定功率是多少”“濾芯型號是多少”。這類問題答案是唯一的檢索定位精準(zhǔn)度就是核心指標(biāo)。第二類是操作流程型問的是“更換濾芯的具體步驟是什么”“多久做一次保養(yǎng)”。這類問題答案跨度大往往分布在好幾頁考察的是檢索結(jié)果覆蓋是否完整。第三類是故障處置型問的是“排氣溫度高報(bào)警怎么處置”“油壓過低會有什么后果”。這類問題還需要關(guān)聯(lián)安全注意事項(xiàng)考察的是Agent多步檢索和信息整合能力。這90條測試問題里有一半來自真實(shí)運(yùn)維群里的歷史提問記錄另一半是我模擬新人操作工的口頭問法。這個(gè)做法很關(guān)鍵——如果只靠自己順著文檔猜問題來測試很容易高估系統(tǒng)效果因?yàn)椴碌膯栴}往往正好落在文檔的關(guān)鍵句上。真實(shí)問題則五花八門有問“怎么會這樣的”、有問“要不要緊的”數(shù)據(jù)才能暴露系統(tǒng)的短板。評估指標(biāo)我用四個(gè)檢索命中率Top3結(jié)果里有沒有包含關(guān)鍵答案段落、最終答案引用正確率、無依據(jù)回答比例越低越好、平均響應(yīng)時(shí)間。檢索命中率是基礎(chǔ)指標(biāo)引用正確率決定系統(tǒng)能不能“敢用”無依據(jù)回答比例體現(xiàn)安全底線。4.2 調(diào)優(yōu)過程中的參數(shù)與結(jié)果調(diào)優(yōu)過程有點(diǎn)像一個(gè)漏斗每一步都在修上一輪暴露的問題。我把每次改動和效果記錄下來方便后面復(fù)盤。第一版是純向量檢索chunk_size取1024字符沒有重疊沒有混合檢索。結(jié)果檢索命中率只有50%出頭而且經(jīng)常出現(xiàn)“文檔里明明有答案但系統(tǒng)答不對”的情況。原因很明確塊太大一個(gè)塊里信息太雜向量被稀釋沒有重疊關(guān)鍵句正好卡在切縫處時(shí)就整句丟失。第二版把chunk_size降到768overlap設(shè)為96同時(shí)把切塊方式改成“結(jié)構(gòu)優(yōu)先、定長兜底”命中率提升到70%左右。這個(gè)提升主要靠數(shù)據(jù)質(zhì)量和模型沒什么關(guān)系。第三版最大的變化是表格獨(dú)立切塊、按行切時(shí)冗余表頭命中率升到80%。到這里基本達(dá)到了“能用”的門檻但離“敢用”還差一口氣。第四版加入BM25混合檢索加RRF融合命中率到了90%左右尤其是故障處置型問題的表現(xiàn)改善明顯。第五版加了BGE-Reranker做結(jié)果重排把檢索出的Top20精排到Top5Top1準(zhǔn)確率明顯改善最終答案的引用正確率也隨之提升。各階段效果對比如下階段主要改動檢索命中率引用正確率無依據(jù)回答比例V1純向量chunk_size102452%40%22%V2chunk_size768overlap96結(jié)構(gòu)切塊70%58%14%V3表格獨(dú)立切塊80%70%9%V4混合檢索RRF89%81%6%V5加Rerank精排93%88%3%調(diào)優(yōu)順序給我的體會是先管數(shù)據(jù)質(zhì)量再上重武器。前期最大的提升來自切塊方式和表格處理而不是換更大的模型或更復(fù)雜的算法。等到數(shù)據(jù)質(zhì)量穩(wěn)定了Rerank這類重型手段才發(fā)揮出價(jià)值。如果順序反了數(shù)據(jù)質(zhì)量一團(tuán)糟的時(shí)候上Rerank相當(dāng)于在污水里做精過濾效果有限還浪費(fèi)算力。5. 踩坑實(shí)錄知識庫Agent最常見的七個(gè)問題5.1 檢索為空時(shí)按什么鏈路排查知識庫Agent上線后最讓人頭疼的問題就是“檢索返回為空”或“答非所問”表現(xiàn)形式五花八門但排查邏輯是有規(guī)律的按鏈路一步步走基本都能定位。排查順序第一檢查Embedding是否成功有沒有特殊字符導(dǎo)致文本被截?cái)嗟诙z查切塊是否存在過短或語義不完整的情況比如一個(gè)塊只有十幾個(gè)字符向量化后基本沒有語義信息第三檢查索引里有沒有該文檔的條目更新文檔后漏了重建索引是最常見的原因第四檢查混合檢索的融合權(quán)重看是不是某一方分?jǐn)?shù)過高壓掉了另一方。一個(gè)實(shí)用技巧上線后在日志里把每次檢索的“Top5命中片段文本相似度分?jǐn)?shù)”全部打出來。肉眼掃一遍日志就能判斷問題出在切塊、向量還是融合環(huán)節(jié)。不要靠猜靠日志里的實(shí)際返回內(nèi)容定位。5.2 表格被“切碎”后的修復(fù)方案我踩過最深的一個(gè)坑就是報(bào)警代碼表被普通切塊方式切碎。那張表有三列報(bào)警代碼、含義、處置建議。用普通段落切法表頭單獨(dú)成塊數(shù)據(jù)行單獨(dú)成塊嵌入檢索時(shí)表頭和數(shù)據(jù)行完全分離。用戶搜“E-204報(bào)警怎么處置”時(shí)檢索到報(bào)警代碼“E-204”那個(gè)塊但處置建議字段已經(jīng)跑到下一個(gè)塊里了導(dǎo)致答案缺一半。修復(fù)方案就是我前面說的表格獨(dú)立通道一個(gè)表格作為一個(gè)整體塊大表按行切分時(shí)每一行都冗余攜帶表頭列名每個(gè)表格塊的類型標(biāo)記為“table”檢索時(shí)優(yōu)先匹配類型為“table”的塊把表頭行和命中行拼成完整句子后再交給LLM。這個(gè)方案對所有以數(shù)值、字段為核心的工業(yè)文檔都適用。5.3 版本污染新舊文檔打架怎么治理工業(yè)文檔最頻繁的變更就是版本更新。有一次我把新版設(shè)備手冊索引進(jìn)去之后發(fā)現(xiàn)同一個(gè)問題有時(shí)返回新參數(shù)、有時(shí)返回舊參數(shù)原因是舊版文檔還留在索引里。向量檢索按相似度排序新舊兩塊文本相似度都很高模型也不清楚該用哪個(gè)版本。治理方案有兩個(gè)一是在元數(shù)據(jù)里加版本號檢索時(shí)過濾條件只保留當(dāng)前有效版本二是更新文檔時(shí)對同一“來源文件章節(jié)路徑”的舊塊做標(biāo)記下線不直接物理刪除方便回溯歷史。每次版本更新后我會人工抽查20個(gè)典型問題確保新舊文檔切換后沒有交叉污染。5.4 常見問題速查表最后整理一張速查表把我在這個(gè)項(xiàng)目里遇到頻率最高的七類問題匯總在一起方便后面排查時(shí)快速對照。現(xiàn)象可能原因解法檢索結(jié)果為空文檔未重建索引、Embedding失敗檢查索引版本查看切塊文本是否完整檢索命中但答案不對切塊太大導(dǎo)致語義混雜調(diào)低chunk_size增加overlap答案像是編的提示詞未強(qiáng)制引用、上下文不足加引用約束無依據(jù)時(shí)明確拒絕回答表格數(shù)據(jù)殘缺表格被當(dāng)普通文本切碎表格獨(dú)立切塊按行切時(shí)冗余表頭多輪對話丟失上下文會話狀態(tài)未維護(hù)設(shè)備型號增加會話變量記錄設(shè)備型號和故障主題新舊文檔答案打架舊版本未下線元數(shù)據(jù)版本過濾更新后人工抽查專有名詞檢索不準(zhǔn)Embedding不認(rèn)識縮寫/型號加BM25混合檢索建立同義詞擴(kuò)展表最后說一點(diǎn)個(gè)人體會。做完這個(gè)項(xiàng)目我最深的感受是知識庫Agent的主線并不取決于初始數(shù)據(jù)是66頁還是66萬頁而是取決于你是否愿意把每一份文檔當(dāng)成知識資產(chǎn)來加工。66頁的好處恰恰在于體量小你有能力逐頁閱讀、逐表校對把每個(gè)知識塊都親手處理到位——這種精細(xì)度在大型自動化流水線上反而不容易做到。如果你手頭也有一堆不起眼的技術(shù)文檔、操作手冊、規(guī)范規(guī)程別等著數(shù)據(jù)攢齊了再動手。先拿這份小家底把閉環(huán)跑通后面每擴(kuò)展一份文檔都只是沿著這條主線再加一個(gè)分支而已。