目录
🔹 一、合理设置 Top-K:别让生成模型“信息过载”或“营养不良”
🔹 三、引入重排序(Re-ranking):把最相关的文档推到前面
🔹 四、优化查询扩展(Query Expansion):把用户“含糊其辞”变成“有问有答”
🔹 五、引入双向改写:Query 改写 + Document 改写双管齐下
🔹 六、索引扩展(Index Enrichment):让文档本身更易被命中
随着大语言模型(LLM)的飞速发展,RAG(Retrieval-Augmented Generation,检索增强生成) 成为让模型“接入知识”的关键机制。然而,在实际应用中,你可能会发现:
“为什么我明明上传了文档,模型却总是答不到点子上?”
问题往往不在生成环节,而是——召回阶段的精准性不足。
在这篇文章中,我们围绕六大关键维度,系统性探讨如何提升 RAG 系统的检索召回质量,让生成结果更有“料”。
🔹 一、合理设置 Top-K:别让生成模型“信息过载”或“营养不良”
在 RAG 系统中:
docs = retriever.similarity_search(query, k=10)
这里的 k=10
表示从向量数据库中返回与 query 最相似的前 10 条文档。
📌 设置建议:
应用场景 | 推荐 top_k 范围 | 原因说明 |
---|---|---|
简答问答、定义类 | 3~5 | 信息集中、提升精度 |
综合推理、决策类 | 8~15 | 覆盖更多背景信息,支持生成逻辑 |
多文档对比类 | 15~30 | 增强信息多样性 |
❗ 过小 → 信息缺失;过大 → prompt 长度溢出、混淆焦点。
建议配合 MMR(Maximal Marginal Relevance)
进行 去冗余 Top-k 策略。
🔹 二、改进索引算法:别让检索器拖慢大模型的后腿
默认的向量索引方式(如 FAISS 的 Flat)检索速度快,但在数据规模增大后,效果不佳。
✅ 高效索引方式推荐:
索引类型 | 特点 | 适用场景 |
---|---|---|
FAISS IVF/IVFPQ | 分段倒排 + 量化加速 | 百万级文档、高并发 |
HNSW(Qdrant) | 近似图结构,支持 ANN | 实时搜索、高精召回 |
DiskANN / ScaNN | 超大规模向量,Google 出品 | 亿级文档,Web 级搜索 |
⚙️ 示例:构建 HNSW 索引
import qdrant_client
client = qdrant_client.QdrantClient(...)
client.create_collection(..., hnsw_config={"m": 16, "ef_construct": 100})
🔹 三、引入重排序(Re-ranking):把最相关的文档推到前面
初始召回只是第一步,排序才是精度保障!
重排序(Re-ranking)采用一个 更强的语义模型 来重新评估候选文档与 query 的匹配度,常用模型包括:
-
🔥
BAAI/bge-reranker-base
-
🔥
nq-distilbert-base-v2
✅ 示例代码(LangChain):
from langchain.retrievers.document_compressors import LLMReranker
reranker = LLMReranker(model="bge-reranker-base", top_n=5)
retriever = ContextualCompressionRetriever(
base_compressor=reranker,
base_retriever=vectorstore.as_retriever()
)
⏱ 成本略高,但显著提升召回结果的相关性,强烈推荐用于生产环境。
🔹 四、优化查询扩展(Query Expansion):把用户“含糊其辞”变成“有问有答”
用户的问题通常非常简短,比如:“RAG 怎么用?”——这远远不足以匹配语义向量!
🚀 优化策略:
技术 | 描述 |
---|---|
同义词扩展 | 替换关键词,如 “使用” -> “应用” |
自动问句生成 | 用 LLM 自动生成多个 Query 变体 |
查询拆解 | 拆成多个子问题并分别检索 |
✅ 多 Query 检索(LangChain 示例):
from langchain.retrievers.multi_query import MultiQueryRetriever
retriever = MultiQueryRetriever.from_llm(
retriever=vectorstore.as_retriever(),
llm=ChatOpenAI(temperature=0)
)
多角度覆盖,显著提高匹配文档的覆盖度。
🔹 五、引入双向改写:Query 改写 + Document 改写双管齐下
除了扩展 query,还可以从文档端入手:
-
🔄 Query Rewriting:将含糊问题转为明确意图
-
🔄 Doc-to-Query(倒推问题):为每段文档生成可能的问题(LlamaIndex 支持)
📘 实战案例:
用户问:“它的原理是什么?” → 重写为 → “RAG 的原理是什么?”
query_engine = HyDEQueryTransform(llm=ChatOpenAI())
此类技术显著提升在对话式 RAG 场景下的召回效果。
🔹 六、索引扩展(Index Enrichment):让文档本身更易被命中
在建立向量索引时,仅用原始文本会导致检索命中率不足。可以通过以下方式增强向量语义表达:
✅ 增强方式:
技术手段 | 描述 |
---|---|
元信息拼接 | 如 标题 + 段落内容 |
文本摘要增强 | 用 LLM 提取段落摘要,再合并进 chunk |
doc-to-query 扩展 | 对每段文档生成可能的问题并加入 index |
✅ 示例(LLM 文本摘要):
chunk = f"{title} - {summary}: {paragraph}" embedding = embedding_model.embed(chunk)
这样可以大幅提升模糊提问下的召回命中率。
✅ 总结:六大策略构建高效召回的“金字塔”
┌─────────────────────┐
│ 索引扩展 │
├─────────────────────┤
│ 双向改写 / Query 扩展 │
├─────────────────────┤
│ 重排序(Rerank) │
├─────────────────────┤
│ 改进索引结构(HNSW等) │
├─────────────────────┤
│ Top-K 优化 │
└─────────────────────┘
越往上,对召回质量的影响越大,但也越复杂。建议根据你的数据规模、实时性要求逐步迭代升级。
📌 附:推荐工具 & 模型
工具/模型 | 用途 | 说明 |
---|---|---|
FAISS / Qdrant | 向量索引 | 支持 HNSW、高性能 |
BGE Embedding | 中文语义向量 | 推荐用于中文语料 |
BGE Reranker | 重排序模型 | 精度大幅提升 |
LangChain | 多检索模块支持 | 快速接入 MMR、Rerank、MultiQuery |
LlamaIndex | Query transform | 支持 Doc-to-Query、HyDE 等 |