如何讓 RAG 檢索更高效?——大模型召回策略全解
一、引子:RAG 的“強”靠得住嗎?
RAG(Retrieval-Augmented Generation)作為一種將文檔檢索與大語言模型結合的框架,已成為企業落地知識問答、搜索增強、智能客服的首選。
但現實中我們常聽到:
- “模型答得不準”
- “文檔檢索到的都不相關”
- “返回的內容一堆沒用的廢話”
這些問題的核心,往往出在了檢索階段的“召回”環節。
二、什么是召回?RAG 的第一道門檻
在 RAG 中,“召回”指的是:
從海量文檔中選出一小批候選文檔,作為模型生成答案的“上下文”。
流程大致如下(見圖1):
- 用戶提問(Query)
- 檢索系統用 embedding(向量)或關鍵詞查找文檔
- 將 N 篇文檔拼接進 prompt,送入語言模型
- 模型基于這些上下文生成答案
如果第2步召回錯了,后面再強的大模型也無能為力。
三、常見召回方式有哪些?
RAG 的召回方式,按復雜度從低到高大致可分為以下幾類:
1. 基于關鍵詞的召回(BM25 等)
- 最經典的搜索引擎方法
- 基于詞頻、TF-IDF 計算相關性
- 優點:快、無需訓練
- 缺點:語義能力弱,容易漏召
適合冷啟動或低資源場景。
2. 基于向量的語義召回(Embedding 檢索)
- 利用 embedding 模型(如 BGE、E5)將 query 和文檔轉換為向量
- 用余弦相似度 / 點積進行匹配
- 通常結合 Faiss、Milvus 等向量引擎使用
優點:
- 語義匹配強,不拘泥于關鍵詞
- 可擴展性好,支持十億級別文檔庫
缺點:
- 需構建向量庫
- 語義漂移風險(召回相關但不精確)
3. 多階段召回(Hybrid Retrieval)
結合多種召回方式,通常分為兩個階段:
第一階段用 BM25 等快速粗篩,
第二階段用向量匹配 / reranker 精排。
示意圖見圖2。
常見方式包括:
- Union(并集): 關鍵詞 + 向量合并
- Stacking: BM25 → Embedding → rerank
- Embedding + rerank(推薦)
優點:召回率和精準率都更高
缺點:延遲更高,依賴 reranker 質量
四、提升召回效果的高級技巧 – 優化檢索質量
1. Query Rewriting(問題改寫)
對用戶 query 進行改寫,提高檢索相關性
如加上領域詞、消歧義、重構句式
例:
“他是誰?” → “曹操是誰?”
2. Query Expansion(問題擴展)
將 query 拓展為多個語義接近的問題,以召回更多候選文檔
例:
“中國主席是誰” → “中國國家領導人是誰”
可直接采用 LangChain 提供的 MultiQueryRetriever
部署該功能:
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain.vectorstores import FAISS
from langchain.llms import OpenAI# 加載向量數據庫(示例用 Faiss)
vectorstore = FAISS.load_local("faiss_index", embeddings)# 初始化 LLM(也可以換成其他如 ChatGLM)
llm = OpenAI(temperature=0)# 創建多查詢檢索器
retriever = MultiQueryRetriever.from_llm( ## 這里,看這里 !!!!!!在這里啊啊啊 !retriever=vectorstore.as_retriever(),llm=llm
)# 輸入用戶問題
query = "中國主席是誰?"# 自動擴展多個語義相似 query 并執行召回
docs = retriever.get_relevant_documents(query)
LLM 自動將原始 query 改寫成多個相關問法, 各自檢索召回文檔, 之后聚合或融合多組結果
3. 多視角查詢(Multi-view Retrieval)
對 query 使用不同 embedding 模型(如 domain-specific、cross-lingual)同時召回
適合跨語言、多模態場景,如醫療報告、PDF等
4. Chunk 優化
RAG 中通常將文檔切分為小段(chunk)后進行召回
但:
- 切太短容易丟上下文
- 切太長又不便檢索與嵌入
常見做法:
- 固定窗口滑動切分
- 按語義段落切分(推薦)
- 結合摘要進行“chunk pooling”
5. 使用 Reranker 精排模型
可對 top-K 召回結果重新排序 (重排排的是 – 問題和召回結果的相關程度),顯著提升 Top-1 命中率
常見 Reranker 精排模型 如:
- 【商用 API】Cohere Rerank
- 【開源】BGE Reranker(下方有使用代碼示例)
# 安裝依賴(首次使用時運行一次)
# pip install transformers torchfrom transformers import AutoTokenizer, AutoModelForSequenceClassification
import torch# 1. 加載 BGE-Reranker 模型和分詞器(首次運行會自動從 HuggingFace 下載)
model_name = "BAAI/bge-reranker-large"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name)
model.eval()# 2. 輸入一個查詢 + 文檔對(可以用于 rerank 檢索結果)
pairs = [["what is panda?", "The giant panda is a bear species."]]# 3. 編碼并送入模型推理
inputs = tokenizer(pairs, padding=True, truncation=True, return_tensors="pt")
with torch.no_grad():scores = model(**inputs).logits.view(-1).float()print(scores) # 輸出相關性得分,例如 tensor([4.95])# 高相關性:3.0~10.0
# 中等相關性:0.0~3.0
# 低相關性/不相關:負數(如-5.0以下)
6. 知識圖譜增強召回(KG-Augmented Retrieval)
利用外部或企業內部的知識圖譜(Knowledge Graph),將用戶查詢中的關鍵詞映射為圖譜中的實體,結合語義關系(上下位、同義詞、連接路徑)進行 query 擴展與實體增強,進一步提高文檔召回的準確性與泛化能力。
適合對實體識別要求高、推理路徑明確的任務(如金融、法律、醫療場景)。
常見方式包括:
- 實體鏈接(Entity Linking)
- 知識圖譜輔助 query 改寫
- 基于圖譜的多跳路徑查詢
7. Small-to-Big 檢索策略(多文檔場景推薦)
當文檔較長或數量龐大時,可采用 Small-to-Big 策略提高檢索效率與精準度:
核心思想:先索引文檔中較短的結構(如摘要、關鍵句、段落標題),快速定位相關內容,再鏈接回對應的完整文檔獲取上下文。
適用場景:論文庫、PDF、多段落文檔、金融合規材料等結構清晰內容。
優勢:顯著減少冗余匹配,提升響應速度,同時增強大模型回答的上下文連貫性。
📌 簡單來說,就是先匹“小塊”,再補“大塊”。
五、召回失敗的常見原因排查清單
癥狀 | 可能原因 | 對策 |
---|---|---|
召回內容完全無關 | Embedding 模型不匹配、未微調 | 更換為領域專用模型或 fine-tune |
文檔相關但答非所問 | Chunk 粒度太大 / 太碎 | 優化切分策略 |
某些關鍵詞缺失 | Query 不完整、實體消歧失敗 | 使用 Query Rewriting |
多輪問答上下文缺失 | 檢索不含對話歷史 | 構造完整對話序列或長上下文支持 |
返回文檔太多 / 太慢 | 無 top-K 控制、未加權排序 | 控制召回數量、使用 reranker |
六、實際工程建議
- 新項目冷啟動:先上 BM25 或 embedding 檢索,配合簡單 rule-based rerank
- 領域任務(金融、法律等):訓練專用 embedding 模型 + 加強 query 改寫
- 性能敏感場景:多階段檢索+輕量化 reranker(如 BGE + Faiss + MonoT5)
- 高精度要求:使用 reranker + chunk 聚合 + CoT 強化(結合 RAFT 訓練)
七、小結:好召回勝過大模型
在 RAG 中,“召回是輸入,生成是輸出”,而“輸入錯了,一切皆錯”。
高效召回系統的構建,并非靠堆算力,而是靠 工程細節 + 策略優化。在知識密集型任務中,它決定了整個 RAG 系統的下限。
推薦閱讀與工具資源
- RAG 高級實踐手冊(知乎@逆流)
- RAGathon (cohere)
- BGE Embedding + Reranker 模型庫