如何让 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 模型库