热闻岛
返回全网热点

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank

7小时前12 阅读
RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图
很多人做 RAG,第一反应是:“我已经把文档向量化了,为什么还是搜不准?” 问题通常不在大模型,而在检索。RAG 的核心不是把所有文档都塞给模型,而是在用户问题进来后,从知识库里找到最能支撑答案的证据。证据找错了,模型再强也只能“认真胡说”
RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

很多人做 RAG,第一反应是:“我已经把文档向量化了,为什么还是搜不准?”

问题通常不在大模型,而在检索。RAG 的核心不是把所有文档都塞给模型,而是在用户问题进来后,从知识库里找到最能支撑答案的证据。证据找错了,模型再强也只能“认真胡说”。

这一章重点讲清楚几件事:关键词检索和向量检索到底有什么区别?为什么生产环境很少只用纯向量检索?混合检索为什么要用 RRF?Rerank 又解决什么问题?

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

一、检索要解决的核心问题

检索的本质很简单:给定一个用户问题,从海量文档中找出最相关的几条。

但“相关”有两种完全不同的理解。第一种是字面相关,也就是查询词和文档里的词重叠;第二种是语义相关,也就是表达不同,但意思接近。

比如用户问“苹果手机怎么截图”,文档里写的是“iPhone 如何截屏”。从字面看,“苹果手机”和“iPhone”不一样,“截图”和“截屏”也不一样;但从语义看,它们说的是同一件事。

这就是为什么 RAG 里会同时出现关键词检索、向量检索、混合检索、Rerank 等多种策略。它们不是重复造轮子,而是在解决不同类型的“相关”。

二、关键词检索:字面匹配,靠统计

关键词检索的代表是 BM25。它的核心不是“理解意思”,而是判断查询词在文档里有没有出现、出现得多不多、这个词在全库里稀不稀缺。

可以把它想成一个图书管理员:他给每个词都建了一张卡片,记录这个词出现在哪些文档里。用户来查“手机 截图”,系统会快速找到包含这些词的文档,再按相关性排序。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

BM25 的优势非常明显:只要查询里有产品型号、人名、版本号、代码、法规条款、缩写,它通常比向量检索更稳。比如“M4 Pro”“CUDA 12.4”“RAG”“iPhone 15 Pro Max”,这些词只要文档里出现,BM25 很容易精准命中。

它的短板也很明显:不懂同义词。用户搜“截图”,文档写“截屏”;用户搜“报销”,文档写“费用 reimbursement”;词面不重叠时,BM25 很容易漏召回。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图
# 用 rank_bm25 做关键词检索的极简示例
from rank_bm25 import BM25Okapi
corpus = [
["苹果", "手机", "截图", "方法"],
["iPhone", "截屏", "教程"],
["安卓", "手机", "拍照"],
]
bm25 = BM25Okapi(corpus)
query = ["苹果", "手机", "截图"]
scores = bm25.get_scores(query)
print(scores) # 每篇文档的 BM25 分数

三、向量检索:语义匹配,靠 Embedding

向量检索的核心思路是:先用 Embedding 模型把文本变成一串数字向量,再用向量距离判断语义是否接近。

在这个空间里,“苹果手机怎么截图”和“iPhone 如何截屏”虽然词面不同,但意思相近,所以向量距离会更近;“数据库索引优化”和“手机截屏教程”虽然都可能包含技术词,但语义距离会更远。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

Embedding 把文本投影到语义空间,语义相近的文本距离更近。

向量检索最擅长解决“换一种说法”的问题,比如同义词、近义词、口语化表达、概念相关问题。用户不需要说出文档里的原词,系统也能找到大致相关的内容。

但向量检索不是万能的。它对精确词不如 BM25 稳,尤其是产品型号、版本号、代码、参数、人名、专有名词。比如“Pro Max 256GB”和“Pro 128GB”在语义上很近,但业务上可能完全不同。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

向量检索通常使用 ANN 索引快速找近邻,用速度换取可接受的召回精度。

# 伪代码:向量检索的基本过程
query_vector = embedding_model.embed_query("iPhone 如何截屏")
results = vector_store.search(
vector=query_vector,
top_k=20,
filter={"doc_type": "help_center"}
)
for item in results:
print(item.score, item.text[:80])

四、关键词检索和向量检索的核心区别

如果只记一句话:BM25 负责精确命中,向量检索负责语义召回。

两者不是谁更高级的问题,而是各自解决的问题不同。BM25 像“按字找”,向量检索像“按意思找”。生产级 RAG 如果只用一种方式,通常都会有明显盲区。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

五、混合检索:两路都跑,合并取长补短

既然 BM25 和向量检索各有盲区,最自然的工程方案就是:两路都跑。

用户问题进来后,一路走 BM25,保证专有名词、编号、代码、版本号不丢;另一路走向量检索,保证同义词、口语表达、语义相关内容能召回。最后把两路结果去重、融合、排序。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

混合检索通常把 BM25 和向量检索并行执行,再用融合算法合并结果。

这里有一个关键点:不能简单把 BM25 分数和向量相似度相加。因为二者分数体系完全不同。BM25 是统计分数,可能是任意正数;向量相似度常见是余弦值,通常在 -1 到 1 或 0 到 1 的区间。直接加权就像把摄氏度和公里数加在一起,数学上能算,业务上没意义。

所以工程上常用 RRF,也就是 Reciprocal Rank Fusion。它不看原始分数,只看每路结果的排名。一个文档如果在 BM25 和向量检索里都排得靠前,它最终排名就会很高。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

RRF 用排名倒数融合多路检索结果,适合分数体系不同的召回通道。

def reciprocal_rank_fusion(results_list, k=60):
"""
results_list: 多路检索结果,每路是按相关性排序的 doc_id 列表
k: 平滑参数,常用 60,避免第一名权重过大
"""
scores = {}
for results in results_list:
for rank, doc_id in enumerate(results, start=1):
scores[doc_id] = scores.get(doc_id, 0.0) + 1.0 / (k + rank)
return sorted(scores.items(), key=lambda x: x[1], reverse=True)
vector_results = ["doc_a", "doc_b", "doc_c"]
bm25_results = ["doc_b", "doc_d", "doc_a"]
merged = reciprocal_rank_fusion([vector_results, bm25_results])
print(merged)

六、Rerank:召回之后,还要精排

混合检索解决的是“候选尽量别漏”。但候选多了以后,噪声也会增加。Rerank 解决的就是“谁更应该排在前面”。

典型做法是两阶段:第一阶段用 BM25 / 向量检索快速召回 Top-50 或 Top-100;第二阶段用 Reranker 对 query-document 逐对判断,重新排序,最后只把 Top-5 或 Top-10 放进 Prompt。

为什么不一开始就用 Reranker?因为 Cross-Encoder 或 LLM 评审成本高、延迟高,不能直接对全库扫描。它适合做精排,不适合做大规模初筛。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图
# 伪代码:召回 + Rerank + Prompt 组装
query = "M4 Pro 芯片参数是多少?"
bm25_docs = bm25_retriever.search(query, top_k=50)
vector_docs = vector_retriever.search(query, top_k=50)
candidates = rrf_merge([bm25_docs, vector_docs], top_k=80)
ranked_docs = reranker.rerank(query, candidates, top_k=8)
context = build_context(ranked_docs)
answer = llm.generate(question=query, context=context)

七、检索前的 Query 处理:别让坏问题直接进检索器

很多 RAG 系统搜不准,不是因为向量库差,而是用户问题本身太短、太口语、太含糊。

比如用户问“这个怎么弄?”如果没有上下文,检索器根本不知道“这个”指什么。再比如用户问“报销有什么要求”,文档里可能写的是“费用 reimbursement policy”,直接检索就可能漏。

因此,在线 RAG 常在检索前增加 Query Rewrite、Multi-Query、HyDE、Decomposition、Self-Query 等处理,让检索器看到更适合搜索的问题。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

Query Transform 让用户问题更适合检索,尤其适合复杂和模糊问题。

这些策略不能无脑全开。Multi-Query 会增加召回量,也会增加 Rerank 成本;HyDE 对抽象概念问题有帮助,但对精确事实问题可能引入偏差;问题拆解适合多跳查询,但简单 FAQ 用它反而浪费延迟。

八、不同场景怎么选检索策略

检索策略不是越复杂越好。正确的做法是先判断问题类型,再选择合适的召回方式。

如果问题里有强精确词,比如型号、订单号、法律条款、函数名,优先用 BM25;如果问题是自然语言描述、同义词很多,优先向量检索;如果是企业知识库,大多数情况下建议直接上混合检索;如果候选噪声大,再加 Rerank。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

检索策略选型可以从问题形态出发,而不是一味堆复杂度。

九、生产级 RAG 检索链路怎么搭

一个可上线的 RAG 检索系统,通常不是一个 vector_store.similarity_search 这么简单。它至少要包含 Query 处理、多路召回、过滤、融合、精排、证据压缩、引用校验和日志追踪。

生产环境还要考虑权限过滤、租户隔离、缓存、超时降级、冷启动、索引更新、召回效果评测和线上错误分析。否则系统刚 Demo 时看起来很准,一到真实业务就开始不稳定。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

生产级在线检索链路需要质量、延迟、成本和可观测性一起设计。

十、怎么判断检索方式真的变好了

检索优化不能只靠“感觉答案更像了”。正确做法是先构建一批黄金问答集,每个问题标注正确证据,再分别评估召回和生成。

常用指标包括 Recall@K、Hit@K、MRR、nDCG、Rerank 后正确证据位置、引用覆盖率、空召回率、P95 延迟和单次请求成本。

如果只看最终答案,很难定位问题。答案错了,可能是没召回,也可能是召回了但排太后,也可能是 Prompt 截断了,还可能是模型生成时没遵守证据。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

十一、常见坑:检索方式越多,不代表系统越准

很多团队做 RAG 优化,第一反应是加策略:加 Multi-Query、加 HyDE、加 Rerank、加 Agentic RAG。结果候选越来越多,延迟越来越高,答案却没有明显提升。

原因是:检索系统的瓶颈不一定在召回数量。很多时候是 Chunk 质量、元数据过滤、Rerank 截断、Prompt 组装、权限过滤、索引更新出了问题。

RAG 检索方式全解析:关键词、向量、混合检索与 Rerank配图

十二、面试回答模板

如果面试官问:关键词检索和向量检索有什么区别?可以这样回答:

关键词检索以 BM25 为代表,基于倒排索引和词频统计,优势是精确命中强,适合产品型号、专有名词、代码、版本号等场景;短板是无法处理同义词和语义相关表达。

向量检索基于 Embedding,把文本映射到语义空间,通过向量距离找相似内容,优势是能处理同义词、口语化和模糊语义;短板是对精确词、数字、型号不够敏感,解释性也弱。

生产级 RAG 通常不会二选一,而是用混合检索:BM25 和向量检索并行召回,用 RRF 融合排序,再用 Reranker 做精排,最后把高质量证据交给 LLM 生成答案。

要点速读

很多人做 RAG,第一反应是:“我已经把文档向量化了,为什么还是搜不准?” 问题通常不在大模型,而在检索。RAG 的核心

  • 很多人做 RAG,第一反应是:“我已经把文档向量化了,为什么还是搜不准
  • ” 问题通常不在大模型,而在检索
  • RAG 的核心