庫搭建全流程:從文本拆解到檢索優(yōu)化的實(shí)戰(zhàn)指南)
最近聊 RAG 的朋友特別多從剛接觸大模型的初學(xué)者到已經(jīng)在做企業(yè)知識(shí)庫落地的工程師都在問同一個(gè)問題RAG 到底怎么搭、怎么做才能真的解決問題。我最早接觸 RAG 是在給內(nèi)部團(tuán)隊(duì)做文檔問答的時(shí)候當(dāng)時(shí)的痛點(diǎn)是模型再強(qiáng)也記不住我們自己的業(yè)務(wù)文檔微調(diào)成本又太高RAG 幾乎是唯一的合理選擇。陸陸續(xù)續(xù)做了幾個(gè)項(xiàng)目之后我發(fā)現(xiàn)自己踩過的坑、調(diào)過的參數(shù)、換過的方案其實(shí)是可以沉淀成一套有章可循的方法的。這篇文章就是把我從零開始搭建 RAG 的過程梳理出來的完整記錄包括核心鏈路、文本拆解、向量化、檢索優(yōu)化、工具選型以及那些最容易讓人抓狂的細(xì)節(jié)問題。如果你正準(zhǔn)備做一個(gè)知識(shí)庫問答、文檔助手或者只是想把 RAG 跑通并搞清楚它的邊界這篇文章應(yīng)該能幫你省下不少摸索的時(shí)間。1. RAG 到底是什么先搞清楚它解決了什么問題1.1 大模型不是搜索引擎它只“記得”訓(xùn)練時(shí)見過的內(nèi)容很多人第一次接觸 RAG 時(shí)的第一反應(yīng)是大模型不是什么都知道嗎為什么還要外掛一個(gè)知識(shí)庫這個(gè)理解偏差是后面所有困惑的根源。大模型在你提問時(shí)給出的答案本質(zhì)上是對(duì)訓(xùn)練語料里學(xué)到的統(tǒng)計(jì)規(guī)律做逐詞生成它沒有能力去“查”任何實(shí)時(shí)資料。你問它今年發(fā)布的新產(chǎn)品規(guī)格它回答不出來不是它笨而是那些信息根本不在它的訓(xùn)練數(shù)據(jù)里。它也沒有辦法區(qū)分哪些信息是真實(shí)的、哪些是編造的因?yàn)樗皇窃谧龈怕噬系睦m(xù)寫。所以當(dāng)你要讓模型回答“我們公司內(nèi)部規(guī)章里遲到怎么定義”這種問題時(shí)如果你只把問題丟給模型它只會(huì)給你一段聽起來合理但完全不可信的答案。RAG 做的事情就是改變這個(gè)局面在你的問題進(jìn)入模型之前先從一個(gè)外部知識(shí)庫里檢索出相關(guān)的內(nèi)容片段把這些片段作為背景材料拼進(jìn)提示詞里再讓模型基于這些材料生成答案。這樣一來模型回答的內(nèi)容就不再依賴它“記得什么”而是依賴你的知識(shí)庫里“有什么”準(zhǔn)確性、時(shí)效性、可追溯性都發(fā)生了本質(zhì)變化。用一句話概括RAG 是把“生成”和“檢索”組合起來的問答架構(gòu)外部知識(shí)庫負(fù)責(zé)找材料大模型負(fù)責(zé)寫答案。它最典型的應(yīng)用場景就是企業(yè)內(nèi)部知識(shí)問答、產(chǎn)品文檔助手、合規(guī)審查輔助、客服工單處理這類“答案必須出自指定資料”的任務(wù)。適合的人群也很寬——在校學(xué)生、后端工程師、算法工程師、產(chǎn)品經(jīng)理都可以通過它快速做出一個(gè)可用的問答系統(tǒng)而且不需要從頭訓(xùn)練任何模型。1.2 RAG 的核心鏈路從文檔到知識(shí)的五步流程RAG 的完整鏈路可以拆成兩個(gè)階段。第一個(gè)階段是知識(shí)庫構(gòu)建也就是“離線處理”把原始文檔變成可以被檢索的形式。第二個(gè)階段是在線問答用戶提問后實(shí)時(shí)檢索并生成回答。離線構(gòu)建階段通常分五步文檔加載、文本拆解、向量化、建索引、存儲(chǔ)。文檔加載是指把 PDF、Word、Markdown、網(wǎng)頁等不同格式的內(nèi)容讀成純文本文本拆解是把長文檔切成適合檢索的小段也就是業(yè)內(nèi)常說的 chunk向量化是調(diào)用 embedding 模型把每個(gè)文本段轉(zhuǎn)換成一串浮點(diǎn)數(shù)向量讓語義相近的文本在向量空間里距離更近建索引和存儲(chǔ)則是把這些向量連同原文一起寫入向量數(shù)據(jù)庫方便后續(xù)快速查找。在線問答階段也有固定流程把用戶問題同樣轉(zhuǎn)成向量到向量數(shù)據(jù)庫里做相似度檢索取回最相關(guān)的一批文本段再把這些文本段和原始問題一起組裝成提示詞交給大模型生成最終答案。我第一次看這個(gè)流程時(shí)覺得不復(fù)雜但真正動(dòng)手做才發(fā)現(xiàn)每一步都有不少隱藏的變量。文本拆成多長合適向量模型選哪個(gè)檢索結(jié)果怎么排序這些問題如果只是默認(rèn)參數(shù)跑通一遍出來的效果往往很一般。后文我會(huì)逐個(gè)環(huán)節(jié)展開講具體怎么調(diào)。1.3 什么時(shí)候該用 RAG什么時(shí)候不該用RAG 不是萬能方案它也有自己的適用邊界。首先需要明確一點(diǎn)如果你的問題都能被模型自身知識(shí)準(zhǔn)確回答且不需要引用任何外部資料那就不需要 RAG。比如“Python 列表怎么去重”這種基礎(chǔ)問題直接問模型就夠了加一套檢索鏈路反而增加了延遲和復(fù)雜度。RAG 真正發(fā)揮價(jià)值的地方有三個(gè)特征一是答案必須來自特定資料比如公司內(nèi)部制度、產(chǎn)品技術(shù)文檔二是資料內(nèi)容會(huì)持續(xù)更新比如每周發(fā)布的新版本說明不可能每次更新都重新微調(diào)模型三是需要答案可溯源用戶抽查時(shí)能知道回答來自哪一份文檔的哪一段。反過來如果這些問題涉及大量跨文檔推理、需要多步邏輯鏈或者問題本身就是開放的、沒有確定答案純粹的 RAG 就會(huì)比較吃力這類任務(wù)通常要引入智能體或多跳檢索機(jī)制而不是簡單的一次檢索一次生成。明白邊界之后再接具體項(xiàng)目就不會(huì)亂。下面我從知識(shí)庫構(gòu)建開始帶你走一遍完整的實(shí)操步驟。2. 從零搭一個(gè) RAG 知識(shí)庫文本拆解和向量化2.1 文檔接入前的第一步格式歸一化與文本抽取很多人拿到一批 PDF 就直接開始做切分這是第一個(gè)坑。PDF 里的內(nèi)容并不都是“文本”大量商業(yè)文檔里含掃描圖片、復(fù)雜表格、頁眉頁腳直接抽取出來的文本經(jīng)常是亂序或者缺失的。我處理過一份內(nèi)部制度文件PDF 里正文分成了兩欄默認(rèn)抽取工具把左右兩欄交叉讀出來句子完全錯(cuò)亂檢索結(jié)果自然慘不忍睹。所以文檔接入的第一步不是切分而是格式歸一化。把所有源文件統(tǒng)一轉(zhuǎn)成干凈、規(guī)范的純文本或者結(jié)構(gòu)化 Markdown再進(jìn)入后續(xù)流程。對(duì) Word、Markdown、HTML 這類本身就帶文本層的內(nèi)容標(biāo)準(zhǔn)做法是優(yōu)先保留原有結(jié)構(gòu)——標(biāo)題、列表、表格里的內(nèi)容按層級(jí)提取。對(duì) PDF處理方案取決于文件質(zhì)量如果是數(shù)字生成的 PDF直接用 pdfplumber 或者 PyMuPDF 提取文本保留基礎(chǔ)版式如果是掃描件則需要先做 OCR這一步可以調(diào)用本地 Tesseract也可以接 PaddleOCR 這類效果更好的引擎。這里要重點(diǎn)說一個(gè)工具Unstructured。它是一個(gè)專門做文檔解析的開源庫能把 PDF、Word、PPT、HTML 等格式解析成帶元數(shù)據(jù)的元素列表比如每個(gè)元素是標(biāo)題、正文、表格還是圖片。我在 Mac 上做本地解析時(shí)常用它配一個(gè)簡單的 Python 腳本就能把整批文檔抽出干凈文本。如果你處理的是學(xué)術(shù)論文或者產(chǎn)品手冊(cè)還可以試試 Marker它能把 PDF 直接轉(zhuǎn)成帶層級(jí)結(jié)構(gòu)的 Markdown對(duì)雙欄和表格支持比普通 PDF 抽取庫好很多。文本抽取這個(gè)環(huán)節(jié)多花二十分鐘后面檢索效果能提升一個(gè)檔次這是性價(jià)比最高的前期投入。2.2 文本拆解的“體感調(diào)參”chunk size 與 overlap文本拆解是 RAG 項(xiàng)目里讓人又愛又恨的環(huán)節(jié)。切得太短語義碎片化一個(gè)問題可能被拆散到好幾塊里檢索時(shí)哪一塊里都找不到完整信息切得太長噪聲太多向量化后語義被稀釋檢索出來的內(nèi)容里真正有用的可能只有一兩句話大模型還要從一大段廢話里挑答案準(zhǔn)確率同樣下降。我常用的起點(diǎn)參數(shù)是 chunk size 在 256 到 512 token 之間overlap 按 chunk size 的 10% 到 20% 設(shè)置。以 512 token 的 chunk、64 token 的 overlap 為例相鄰兩個(gè)文本塊之間會(huì)共享一部分內(nèi)容這樣即使一個(gè)關(guān)鍵句恰好落在前一個(gè)塊的末尾也能在后一個(gè)塊的開頭再出現(xiàn)一次避免漏檢。這個(gè)參數(shù)組合對(duì)絕大多數(shù)中文文檔都算穩(wěn)妥但實(shí)際效果仍然要按內(nèi)容類型做調(diào)整。2.3 向量化與 embedding 模型選型文本切好之后下一步是把每一塊轉(zhuǎn)成向量。embedding 模型的選擇直接決定了檢索的召回質(zhì)量這是 RAG 項(xiàng)目里最不該隨便應(yīng)付的環(huán)節(jié)。開箱即用的方案是調(diào)用 OpenAI 的 text-embedding-3-small 這類在線接口質(zhì)量穩(wěn)定、接入快缺點(diǎn)是每一篇文檔都要上傳到外部服務(wù)對(duì)數(shù)據(jù)敏感的內(nèi)網(wǎng)項(xiàng)目不適用。本地部署的方案里我測試過 BGE 系列模型表現(xiàn)很好尤其是 BGE-M3在中文語義理解上比很多同體量英文模型強(qiáng)很多同時(shí)支持稠密檢索和稀疏檢索兩種模式后面做混合檢索時(shí)可以共用一套向量。如果你的環(huán)境跑不了大模型也可以用更輕量的 text2vec 或者 m3e 系列效果略遜一籌但速度更快。最近 Ollama 也支持了 nomic-embed-text 和 bge-m3一條命令就能在本地起一個(gè) embedding 服務(wù)對(duì)做實(shí)驗(yàn)和搭建個(gè)人知識(shí)庫來說性價(jià)比很高。選模型的時(shí)候有一個(gè)容易忽略的細(xì)節(jié)檢索用的 embedding 模型和生成回答的大模型不需要來自同一家公司也不需要綁定運(yùn)行。常有人覺得“我用 Llama 本地部署那 embedding 也必須用 Llama 系列”其實(shí)沒有這個(gè)限制embedding 和生成兩套模型是獨(dú)立的可以分開選型。只要保證一個(gè)關(guān)鍵前提所有文檔切片和用戶查詢都要用同一個(gè) embedding 模型不能用兩個(gè)不同的模型分別向量化否則向量空間不一致相似度計(jì)算就沒有意義了。3. 知識(shí)庫到底能不能存圖片多模態(tài) RAG 的邊界3.1 為什么圖片經(jīng)常“進(jìn)不了”知識(shí)庫“RAG 知識(shí)庫能存圖片嗎”是搜索熱度很高的問題也是很多初學(xué)者繞不過去的困惑。直接回答純文本 RAG 的向量庫不能直接理解圖片內(nèi)容。原因在于最主流的 embedding 模型處理的是文本圖片直接送進(jìn)去沒有任何意義。很多人在本地搭建知識(shí)庫時(shí)發(fā)現(xiàn)傳了幾張截圖進(jìn)去檢索的時(shí)候卻完全檢索不到就是因?yàn)闆]有對(duì)圖片做任何處理圖片壓根沒有變成可檢索的文本。這并不意味著知識(shí)庫完全和圖片絕緣。如果你用的向量數(shù)據(jù)庫本身支持多模態(tài)向量比如 Milvus 這類專業(yè)向量庫接入了 CLIP 或 ImageBind 模型確實(shí)可以把圖片編碼成向量做圖搜圖。但這屬于多模態(tài)檢索的范疇實(shí)現(xiàn)成本和工程復(fù)雜度比普通文本 RAG 高不少初學(xué)者通常不需要一上來就走這條路。3.2 實(shí)際可行的做法圖片轉(zhuǎn)描述再入庫對(duì)絕大多數(shù)知識(shí)庫場景最穩(wěn)妥的做法不是把圖片直接入庫而是把圖片“翻譯”成文本描述之后再把文本放進(jìn)知識(shí)庫。具體流程是用大模型或者專門的圖像理解模型給每一張圖片生成一段文字說明比如“圖中展示的是系統(tǒng)登錄界面左上角為用戶名輸入框右側(cè)為驗(yàn)證碼區(qū)域”然后把這段描述和圖片在文檔中的上下文一起拼成文本塊入庫。用戶提問時(shí)檢索發(fā)生在文字描述層模型讀到的是“圖片內(nèi)容的文字版”照樣能給出有用回答。我實(shí)際處理過一個(gè)產(chǎn)品說明書項(xiàng)目文檔里有大量界面截圖和流程圖最初直接用 PDF 抽取圖片內(nèi)容全部丟失導(dǎo)致很多問題回答不了。后來我把 PDF 先轉(zhuǎn)成 Markdown再用多模態(tài)模型對(duì)圖片逐張生成描述插入到對(duì)應(yīng)章節(jié)的位置整個(gè)知識(shí)庫的召回率明顯提升。這個(gè)流程現(xiàn)在有標(biāo)準(zhǔn)化的開源工具可以做比如一些文檔解析庫已經(jīng)內(nèi)置了“OCR 圖像理解 文本化”的流水線無需自己組裝。3.3 表格、PDF 掃描件這類“偽圖片”怎么處理有些內(nèi)容看起來不是圖片但處理方式卻和圖片類似。表格就是最常見的例子原生從 PDF 抽取出來的表格經(jīng)常是一堆散落的字符行列關(guān)系全丟掃描版的合同、發(fā)票就更不用提本質(zhì)上就是圖片。這些內(nèi)容如果直接丟進(jìn)文本 RAG檢索到之后回答質(zhì)量大概率是不合格的。表格類內(nèi)容的推薦做法是轉(zhuǎn)成 Markdown 表格或者 JSON 結(jié)構(gòu)化之后當(dāng)作一個(gè)整體 chunk 存入知識(shí)庫。大模型對(duì) Markdown 表格格式的識(shí)別能力很強(qiáng)只要文本塊里保留了完整結(jié)構(gòu)它在生成答案時(shí)就能正確理解“第一列是配置項(xiàng)第二列是默認(rèn)值”這類關(guān)系。掃描件則必須走 OCR這一步做完之后還要做版式還原盡量把識(shí)別出來的文本按原始閱讀順序重新拼接。我見過不少項(xiàng)目卡在“掃描件檢索到了但答案不對(duì)”這個(gè)問題上排查下來都是 OCR 文本順序出了問題排版亂掉的文本塊比檢索不到更誤導(dǎo)模型。4. 檢索鏈路才是 RAG 的靈魂檢索增強(qiáng)不只是搜一下4.1 相似度檢索的局限關(guān)鍵詞與語義之間的平衡很多初學(xué)者以為 RAG 的檢索就是用向量數(shù)據(jù)庫查一下相似度跑通之后發(fā)現(xiàn)效果時(shí)好時(shí)壞。原因在于純向量檢索對(duì)長尾關(guān)鍵詞、編號(hào)、產(chǎn)品型號(hào)這類精確信息并不敏感。比如用戶問“CH-3200 的額定功率是多少”向量模型可能把這串型號(hào)理解成“某個(gè)設(shè)備型號(hào)”但“CH-3200”這個(gè)精確匹配信號(hào)在向量檢索里并不占優(yōu)勢(shì)最相關(guān)的文檔反而排不到前面。解決這個(gè)問題需要意識(shí)到RAG 的檢索本質(zhì)上應(yīng)該分兩路走一路做語義召回靠向量相似度找到意思相近的內(nèi)容另一路做關(guān)鍵詞召回靠 BM25 這類經(jīng)典算法做精確匹配。然后把兩路結(jié)果做合并和重排術(shù)語叫“混合檢索”Hybrid Search。我用過的方案里向量庫用 Milvus 或者 Qdrant關(guān)鍵詞檢索可以直接用 Elasticsearch也可以用一個(gè)更輕量的 MeiliSearch 或者 SQLite FTS5按數(shù)據(jù)量級(jí)來選。合并策略上常用的是用倒數(shù)排名融合RRF算法把兩份結(jié)果按排名做加權(quán)合并保證兩路召回的內(nèi)容都有機(jī)會(huì)進(jìn)到最終候選集。4.2 重排序讓最相關(guān)的答案排到最前面混合檢索拿到一批候選文檔之后另一個(gè)關(guān)鍵步驟是重排序。向量相似度衡量的是“整段文本語義上有多接近”但語義接近不等于“問題中的核心信息在答案里都有”。做重排序最有效的方法是引入一個(gè)專門的重排模型reranker它會(huì)把問題和候選文檔逐條拼接起來計(jì)算相關(guān)性得分這種交互式打分比純向量距離更精準(zhǔn)。開源方案里我會(huì)優(yōu)先推薦 BGE-Reranker它的模型設(shè)計(jì)就是針對(duì)中文問答場景做的重排效果和推理速度平衡得不錯(cuò)。實(shí)測下來一個(gè)嵌入模型召回后有 30 條候選的查詢用重排模型重新排一遍之后Top 1 結(jié)果往往和實(shí)際需要的答案高度相關(guān)對(duì)比不重排的情況提升顯著。需要注意重排模型也是本地部署時(shí)的主要算力消耗點(diǎn)之一對(duì)性能要求高的線上場景一些團(tuán)隊(duì)甚至?xí)iT做緩存和并發(fā)優(yōu)化。但哪怕只是做一個(gè)小工具我認(rèn)為重排這一步也不該省它是性價(jià)比非常高的精度提升手段。4.3 知識(shí)圖譜 RAG 和 RAG 智能體的差異“知識(shí)圖譜 RAG”和“RAG 智能體”是最近熱度很高的兩個(gè)詞初學(xué)者容易混為一談。簡單來說知識(shí)圖譜 RAG 是在傳統(tǒng) RAG 基礎(chǔ)上額外引入了一層的結(jié)構(gòu)化知識(shí)文檔切塊和向量化照舊做但你同時(shí)把文檔里的實(shí)體、關(guān)系抽取出來建成圖譜結(jié)構(gòu)比如“張三”是“市場部”的“員工”“市場部”的“負(fù)責(zé)人”是“李四”。圖譜可以回答那些依賴多級(jí)關(guān)聯(lián)的問題比如“張三的部門負(fù)責(zé)人是誰”普通 RAG 需要從多篇文檔里拼湊推理知識(shí)圖譜可以直接走關(guān)系路徑。這類方案搭建成本高因?yàn)閷?shí)體識(shí)別、關(guān)系抽取都要精確處理但對(duì)特定領(lǐng)域比如醫(yī)療、法律的關(guān)聯(lián)問答場景收益明顯。RAG 智能體則是把 RAG 從“查一次、答一次”升級(jí)成“可以多輪決策”的形態(tài)。智能體收到問題后先判斷要不要檢索再?zèng)Q定檢索哪幾個(gè)知識(shí)庫對(duì)結(jié)果不滿意就改關(guān)鍵詞再檢索一次甚至同時(shí)調(diào)用另外一個(gè) API 獲取結(jié)構(gòu)化數(shù)據(jù)最后把多來源信息組裝成答案。它的核心特征是擁有循環(huán)和工具調(diào)用能力適合復(fù)雜查詢。但代價(jià)是可控性下降出問題的時(shí)候排查鏈路變長。對(duì)初學(xué)者我的建議是先扎實(shí)掌握普通 RAG 和混合檢索再研究知識(shí)圖譜和智能體否則很容易陷入“什么都要接智能體但什么問題都回答不準(zhǔn)”的泥潭。5. 本地搭建 RAG 的常見路徑與工具選型5.1 在自己電腦上搭建 RAG 的配置思路以 Mac 為例“怎么在 Mac 上搭建 RAG 知識(shí)庫”是搜索量很高的問題確實(shí)很多剛接觸大模型應(yīng)用的朋友手上只有一臺(tái) Mac不想上來就買服務(wù)器。以一臺(tái) Apple Silicon 芯片的 Mac 為例完全可以在本地跑起一套完整的 RAG 鏈路Ollama 負(fù)責(zé)本地大模型和 embeddingChroma 做向量庫再加一個(gè)小型 Python 腳本做文檔處理全部內(nèi)網(wǎng)運(yùn)行數(shù)據(jù)不出本機(jī)。具體流程我建議按這樣走第一步安裝 Ollama拉取一個(gè)大語言模型起步可以用 qwen2.5:7b 這類中文表現(xiàn)不錯(cuò)的 7B 模型再拉一個(gè) bge-m3 作為 embedding 模型第二步用 Python 寫一個(gè)簡單的文檔加載腳本把 Markdown、TXT 這些文本類型直接讀入PDF 用 Unstructured 解析第三步把文本塊交給 embedding 模型轉(zhuǎn)成向量寫入 Chroma 持久化目錄第四步寫一個(gè)查詢函數(shù)用戶輸入問題后先向量化再從 Chroma 取出相似度最高的幾個(gè)文本塊連同問題一起拼進(jìn)提示詞交給 Ollama 生成回答。整個(gè)過程不依賴任何外部云服務(wù)一臺(tái) 16G 內(nèi)存的 Mac 跑 7B 模型雖然速度不算快但做學(xué)習(xí)驗(yàn)證和個(gè)人知識(shí)庫完全夠用。如果你不想寫代碼也可以直接用現(xiàn)成的開源應(yīng)用。RAGFlow 是我實(shí)測下來對(duì)新手比較友好的一套系統(tǒng)它自帶文檔解析、知識(shí)庫管理、問答界面部署后就能用對(duì)中文文檔支持也很好。LangChain 和 LlamaIndex 則更適合想深入理解原理、通過代碼自由控制流程的人兩者定位略有差異LangChain 的組件生態(tài)更豐富適合構(gòu)建復(fù)雜鏈路LlamaIndex 主打文檔索引和檢索對(duì) RAG 場景更聚焦。5.2 常見開源 RAG 框架怎么選框架選型是大家問得最多的問題之一我把幾種典型方案的定位和適用場景整理成了表格方便對(duì)比。方案核心定位上手難度適合場景自研腳本Ollama Chroma最小可用鏈路低學(xué)習(xí)原理、快速驗(yàn)證LangChain / LlamaIndex開發(fā)框架中定制化程度高、需要代碼控制RAGFlow開箱即用系統(tǒng)低快速搭建知識(shí)庫應(yīng)用中文友好Dify低代碼平臺(tái)低面向業(yè)務(wù)配置、可視化流程編排企業(yè)級(jí)生產(chǎn)方案Milvus Elasticsearch 等生產(chǎn)級(jí)鏈路高高并發(fā)、大規(guī)模文檔、需要精細(xì)化治理初學(xué)者選擇時(shí)不要一上來就上最重的框架。我見過不少朋友第一天就在折騰生產(chǎn)級(jí)集群最后光部署就卡了一周核心鏈路反而沒跑通。建議先用手寫腳本跑通最小鏈路切身理解每一環(huán)的功能之后再挑選框架去簡化開發(fā)。紙上談兵沒有意義跑通一次你對(duì) RAG 的體感會(huì)完全不同。5.3 從“demo”到“可用”要跨過的幾道坎把 RAG 從演示跑通變成能穩(wěn)定使用中間有幾道坎幾乎人人都會(huì)遇到。第一道坎是文檔更新機(jī)制。很多人做了知識(shí)庫之后就忘記更新文檔內(nèi)容已經(jīng)變了檢索出來的還是舊信息。這個(gè)問題不解決知識(shí)庫很快失去價(jià)值。第二道坎是檢索質(zhì)量評(píng)估。跑一次效果好不好是主觀感受但上線前需要建立客觀評(píng)估基準(zhǔn)準(zhǔn)備一批有確定答案的測試問題統(tǒng)計(jì)檢索結(jié)果里包含正確答案的比例用這個(gè)指標(biāo)來驅(qū)動(dòng)參數(shù)調(diào)優(yōu)。第三道坎是提示詞穩(wěn)定性。同樣的檢索結(jié)果提示詞寫法不同回答質(zhì)量可能差異巨大需要反復(fù)調(diào)試才能穩(wěn)定輸出。這三道坎不是一次性工程而是持續(xù)迭代的過程。我在做完第一個(gè)可用版本后花了將近一半的時(shí)間在整理測試集和調(diào)提示詞上這個(gè)投入非常值得。后面常見問題部分我會(huì)再展開講幾個(gè)高頻故障的排查思路。6. 常見問題與排查技巧實(shí)錄6.1 檢索結(jié)果差是模型的問題還是檢索的問題這是排查 RAG 問題時(shí)的第一個(gè)分岔路。一個(gè)常見的錯(cuò)誤是回答質(zhì)量差就先怪大模型但很多時(shí)候問題出在檢索環(huán)節(jié)知識(shí)庫里根本沒有相關(guān)內(nèi)容或者相關(guān)內(nèi)容沒有被正確召回。排查方法很簡單先在系統(tǒng)里把檢索到的文本塊原樣打印出來人工判斷這些文本塊是否真的能回答問題。如果檢索結(jié)果本身就對(duì)不上說明問題在文檔處理、切分、向量模型或檢索策略換再大的生成模型也沒用如果檢索結(jié)果是對(duì)的但模型回答得不好那才需要優(yōu)化提示詞或者換一個(gè)更強(qiáng)的生成模型。我經(jīng)常用一個(gè)比喻RAG 系統(tǒng)的效果上限由檢索決定下限由生成決定。檢索不到關(guān)鍵信息再強(qiáng)的模型也巧婦難為無米之炊檢索到了關(guān)鍵信息至少模型不會(huì)胡編太離譜。所以排查問題永遠(yuǎn)先查檢索再查生成。6.2 知識(shí)庫更新了為什么回答還是舊內(nèi)容這個(gè)問題的根因幾乎都是緩存和索引不同步。向量數(shù)據(jù)庫里的數(shù)據(jù)是構(gòu)建索引時(shí)刻的快照如果新增或者修改了文檔但沒有重新執(zhí)行向量化和寫入流程檢索結(jié)果自然不包含新內(nèi)容。解決思路是建立清晰的更新策略全量重建用在小規(guī)模知識(shí)庫上最簡單可靠每次變更后直接清空舊索引、重新入庫增量更新用在內(nèi)容經(jīng)常變動(dòng)的場景需要根據(jù)文檔的唯一標(biāo)識(shí)判斷新增、修改、刪除再對(duì)應(yīng)地做向量寫入和刪除。增量更新實(shí)現(xiàn)起來比全量重建復(fù)雜得多如果文檔總量不大系統(tǒng)設(shè)計(jì)時(shí)我傾向于先用全量重建每天定時(shí)跑一次成本不高邏輯還不會(huì)出錯(cuò)。等到文檔量級(jí)上來之后再遷移到增量策略。6.3 RAG 的瓶頸與它不適用的場景明確說出瓶頸在哪里也很重要。當(dāng)前 RAG 最主要的瓶頸有三個(gè)一是長文檔多跳問題的推理能力弱當(dāng)答案需要跨多個(gè)文檔片段組合推理時(shí)單次檢索往往漏掉必要信息二是知識(shí)沖突處理難同一問題在知識(shí)庫不同位置有矛盾表述時(shí)模型很難判斷以哪個(gè)為準(zhǔn)三是評(píng)估困難沒有標(biāo)準(zhǔn)化的評(píng)測集和統(tǒng)一指標(biāo)很難準(zhǔn)確判斷系統(tǒng)的真實(shí)水平。不適合的場景同樣需要警惕回答開放性的主觀題、需要最新實(shí)時(shí)信息的強(qiáng)時(shí)效任務(wù)、以及需要深度邏輯推理的復(fù)雜分析這些場景里 RAG 的表現(xiàn)都會(huì)打折扣需要配合其他架構(gòu)解決。說到底R(shí)AG 是一個(gè)需要持續(xù)調(diào)優(yōu)的系統(tǒng)工程不是跑通 Demo 就結(jié)束的事情。根據(jù)我個(gè)人在這些項(xiàng)目里的體會(huì)投入產(chǎn)出比最高的三件事分別是前期的文檔解析質(zhì)量、檢索階段的重排序、以及一套能重復(fù)使用的評(píng)測問題集。把這三件事做好你的 RAG 項(xiàng)目就已經(jīng)超過了大多數(shù)停留在平均水平的實(shí)現(xiàn)剩下的就是在具體數(shù)據(jù)上持續(xù)迭代了。