很多人做 RAG第一反应是“我已经把文档向量化了为什么还是搜不准”问题通常不在大模型而在检索。RAG 的核心不是把所有文档都塞给模型而是在用户问题进来后从知识库里找到最能支撑答案的证据。证据找错了模型再强也只能“认真胡说”。这一章重点讲清楚几件事关键词检索和向量检索到底有什么区别为什么生产环境很少只用纯向量检索混合检索为什么要用 RRFRerank 又解决什么问题一、检索要解决的核心问题检索的本质很简单给定一个用户问题从海量文档中找出最相关的几条。但“相关”有两种完全不同的理解。第一种是字面相关也就是查询词和文档里的词重叠第二种是语义相关也就是表达不同但意思接近。比如用户问“苹果手机怎么截图”文档里写的是“iPhone 如何截屏”。从字面看“苹果手机”和“iPhone”不一样“截图”和“截屏”也不一样但从语义看它们说的是同一件事。这就是为什么 RAG 里会同时出现关键词检索、向量检索、混合检索、Rerank 等多种策略。它们不是重复造轮子而是在解决不同类型的“相关”。二、关键词检索字面匹配靠统计关键词检索的代表是 BM25。它的核心不是“理解意思”而是判断查询词在文档里有没有出现、出现得多不多、这个词在全库里稀不稀缺。可以把它想成一个图书管理员他给每个词都建了一张卡片记录这个词出现在哪些文档里。用户来查“手机 截图”系统会快速找到包含这些词的文档再按相关性排序。BM25 的优势非常明显只要查询里有产品型号、人名、版本号、代码、法规条款、缩写它通常比向量检索更稳。比如“M4 Pro”“CUDA 12.4”“RAG”“iPhone 15 Pro Max”这些词只要文档里出现BM25 很容易精准命中。它的短板也很明显不懂同义词。用户搜“截图”文档写“截屏”用户搜“报销”文档写“费用 reimbursement”词面不重叠时BM25 很容易漏召回。# 用 rank_bm25 做关键词检索的极简示例from rank_bm25importBM25Okapi corpus[[苹果,手机,截图,方法],[iPhone,截屏,教程],[安卓,手机,拍照],]bm25BM25Okapi(corpus)query[苹果,手机,截图]scoresbm25.get_scores(query)print(scores)# 每篇文档的 BM25 分数三、向量检索语义匹配靠 Embedding向量检索的核心思路是先用 Embedding 模型把文本变成一串数字向量再用向量距离判断语义是否接近。在这个空间里“苹果手机怎么截图”和“iPhone 如何截屏”虽然词面不同但意思相近所以向量距离会更近“数据库索引优化”和“手机截屏教程”虽然都可能包含技术词但语义距离会更远。Embedding 把文本投影到语义空间语义相近的文本距离更近。向量检索最擅长解决“换一种说法”的问题比如同义词、近义词、口语化表达、概念相关问题。用户不需要说出文档里的原词系统也能找到大致相关的内容。但向量检索不是万能的。它对精确词不如 BM25 稳尤其是产品型号、版本号、代码、参数、人名、专有名词。比如“Pro Max 256GB”和“Pro 128GB”在语义上很近但业务上可能完全不同。向量检索通常使用 ANN 索引快速找近邻用速度换取可接受的召回精度。# 伪代码向量检索的基本过程query_vectorembedding_model.embed_query(iPhone 如何截屏)resultsvector_store.search(vectorquery_vector,top_k20,filter{doc_type:help_center})foriteminresults: print(item.score, item.text[:80])四、关键词检索和向量检索的核心区别如果只记一句话BM25 负责精确命中向量检索负责语义召回。两者不是谁更高级的问题而是各自解决的问题不同。BM25 像“按字找”向量检索像“按意思找”。生产级 RAG 如果只用一种方式通常都会有明显盲区。五、混合检索两路都跑合并取长补短既然 BM25 和向量检索各有盲区最自然的工程方案就是两路都跑。用户问题进来后一路走 BM25保证专有名词、编号、代码、版本号不丢另一路走向量检索保证同义词、口语表达、语义相关内容能召回。最后把两路结果去重、融合、排序。混合检索通常把 BM25 和向量检索并行执行再用融合算法合并结果。这里有一个关键点不能简单把 BM25 分数和向量相似度相加。因为二者分数体系完全不同。BM25 是统计分数可能是任意正数向量相似度常见是余弦值通常在 -1 到 1 或 0 到 1 的区间。直接加权就像把摄氏度和公里数加在一起数学上能算业务上没意义。所以工程上常用 RRF也就是 Reciprocal Rank Fusion。它不看原始分数只看每路结果的排名。一个文档如果在 BM25 和向量检索里都排得靠前它最终排名就会很高。RRF 用排名倒数融合多路检索结果适合分数体系不同的召回通道。def reciprocal_rank_fusion(results_list,k60): results_list: 多路检索结果每路是按相关性排序的 doc_id 列表 k: 平滑参数常用60避免第一名权重过大 scores{}forresultsinresults_list:forrank, doc_idinenumerate(results,start1): scores[doc_id]scores.get(doc_id,0.0)1.0/(k rank)returnsorted(scores.items(),keylambda x: x[1],reverseTrue)vector_results[doc_a,doc_b,doc_c]bm25_results[doc_b,doc_d,doc_a]mergedreciprocal_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 评审成本高、延迟高不能直接对全库扫描。它适合做精排不适合做大规模初筛。# 伪代码召回 Rerank Prompt 组装queryM4 Pro 芯片参数是多少bm25_docsbm25_retriever.search(query,top_k50)vector_docsvector_retriever.search(query,top_k50)candidatesrrf_merge([bm25_docs, vector_docs],top_k80)ranked_docsreranker.rerank(query, candidates,top_k8)contextbuild_context(ranked_docs)answerllm.generate(questionquery,contextcontext)七、检索前的 Query 处理别让坏问题直接进检索器很多 RAG 系统搜不准不是因为向量库差而是用户问题本身太短、太口语、太含糊。比如用户问“这个怎么弄”如果没有上下文检索器根本不知道“这个”指什么。再比如用户问“报销有什么要求”文档里可能写的是“费用 reimbursement policy”直接检索就可能漏。因此在线 RAG 常在检索前增加 Query Rewrite、Multi-Query、HyDE、Decomposition、Self-Query 等处理让检索器看到更适合搜索的问题。Query Transform 让用户问题更适合检索尤其适合复杂和模糊问题。这些策略不能无脑全开。Multi-Query 会增加召回量也会增加 Rerank 成本HyDE 对抽象概念问题有帮助但对精确事实问题可能引入偏差问题拆解适合多跳查询但简单 FAQ 用它反而浪费延迟。八、不同场景怎么选检索策略检索策略不是越复杂越好。正确的做法是先判断问题类型再选择合适的召回方式。如果问题里有强精确词比如型号、订单号、法律条款、函数名优先用 BM25如果问题是自然语言描述、同义词很多优先向量检索如果是企业知识库大多数情况下建议直接上混合检索如果候选噪声大再加 Rerank。检索策略选型可以从问题形态出发而不是一味堆复杂度。九、生产级 RAG 检索链路怎么搭一个可上线的 RAG 检索系统通常不是一个 vector_store.similarity_search 这么简单。它至少要包含 Query 处理、多路召回、过滤、融合、精排、证据压缩、引用校验和日志追踪。生产环境还要考虑权限过滤、租户隔离、缓存、超时降级、冷启动、索引更新、召回效果评测和线上错误分析。否则系统刚 Demo 时看起来很准一到真实业务就开始不稳定。生产级在线检索链路需要质量、延迟、成本和可观测性一起设计。十、怎么判断检索方式真的变好了检索优化不能只靠“感觉答案更像了”。正确做法是先构建一批黄金问答集每个问题标注正确证据再分别评估召回和生成。常用指标包括 RecallK、HitK、MRR、nDCG、Rerank 后正确证据位置、引用覆盖率、空召回率、P95 延迟和单次请求成本。如果只看最终答案很难定位问题。答案错了可能是没召回也可能是召回了但排太后也可能是 Prompt 截断了还可能是模型生成时没遵守证据。十一、常见坑检索方式越多不代表系统越准很多团队做 RAG 优化第一反应是加策略加 Multi-Query、加 HyDE、加 Rerank、加 Agentic RAG。结果候选越来越多延迟越来越高答案却没有明显提升。原因是检索系统的瓶颈不一定在召回数量。很多时候是 Chunk 质量、元数据过滤、Rerank 截断、Prompt 组装、权限过滤、索引更新出了问题。十二、面试回答模板如果面试官问关键词检索和向量检索有什么区别可以这样回答关键词检索以 BM25 为代表基于倒排索引和词频统计优势是精确命中强适合产品型号、专有名词、代码、版本号等场景短板是无法处理同义词和语义相关表达。向量检索基于 Embedding把文本映射到语义空间通过向量距离找相似内容优势是能处理同义词、口语化和模糊语义短板是对精确词、数字、型号不够敏感解释性也弱。生产级 RAG 通常不会二选一而是用混合检索BM25 和向量检索并行召回用 RRF 融合排序再用 Reranker 做精排最后把高质量证据交给 LLM 生成答案。