RAG 检索模块怎么提升相关性?
三种方法原理详解:Query Rewriting、HyDE、重排序
原题:请说明RAG系统中检索模块的工作机制,并列举至少三种提升检索结果相关性的方法及其原理。
RAG基础 · 字节真题
回答与解析
检索模块工作机制
RAG检索模块的核心流程:
- 索引构建:文档切分→Embedding编码→写入向量数据库
- 在线检索:查询向量化→近似最近邻搜索(ANN)→返回TopK候选
- 结果组装:结合元数据过滤,送入生成模块
三种提升相关性的方法
1. 混合检索(Hybrid Search)
- 原理:融合向量语义检索 + 关键词匹配(BM25),解决向量检索对专有名词、ID类信息召回不足的问题
- 融合策略:线性加权
score = α·dense_score + (1-α)·sparse_score,或RRF倒数排序融合
2. 重排序(Re-ranking)
- 原理:用Cross-encoder等交互式模型对初筛结果精细打分。双塔模型(Bi-encoder)分离编码查询和文档,精度受限;Cross-encoder拼接输入做交互注意力,相关性判断更准确
- 实践:先用向量检索召回100条,再用轻量重排模型筛Top5,平衡延迟与效果
3. 查询改写(Query Rewriting)
- 原理:原始查询可能表述模糊或与文档措辞不一致。通过LLM扩展同义表达、生成伪答案、或HyDE(假设文档嵌入)——让模型先写理想答案,再用答案向量去检索
- 典型场景:用户问"怎么省钱" → 改写为"降低成本的策略/方法/技巧"
其他补充手段
- 上下文压缩:检索长文档后,用LLM提取与查询相关的片段,减少噪声
- 元数据过滤:先按时间、类别等标签粗筛,缩小向量搜索空间
实际落地需权衡:重排序和查询改写增加延迟,建议根据场景选择组合策略。
学习建议
建议系统学习该知识点
口语版讲法(约4分钟)
- 一句话定位:RAG检索本质是平衡召回率与精度的工程问题
- 检索模块的工作流程:索引构建、在线检索、结果组装
- 提升相关性的三个方法:混合检索、重排序、查询改写
- 落地风险与取舍:延迟、一致性、场景适配
这道题问的是RAG检索模块,其实本质是问怎么在召回率和精度之间做工程取舍,而不是单纯讲流程。我按自己的理解来拆解一下。
先说检索模块怎么工作。核心就三步:第一步,离线把文档切碎,然后用 Embedding 模型编码成向量,存到 Vector Database 里。第二步,用户来了一个查询,同样编码成向量,然后做 ANN 近似最近邻搜索,召回 TopK 候选。第三步,把结果和元数据拼起来,送到生成模块。这里面有个容易忽略的细节:切分策略直接影响检索质量。比如固定大小切分,简单但容易切断语义,导致召回片段不完整;而语义切分虽然好,但依赖模型质量,而且对长文档可能切出太多碎片。所以实际落地时,我倾向于用分层切分:先按段落切,再对过长段落做滑动窗口,同时保留父子文档的映射关系,这样检索时可以用子块匹配,返回时带出父块上下文。
接下来重点讲三个提升相关性的方法,也是我实际中经常组合用的。
先看混合检索。说白了就是向量语义检索加关键词匹配,比如 BM25。向量检索擅长语义相似,但遇到专有名词、订单号这种精确匹配就抓瞎。举个例子,电商客服场景,用户问“退款到哪了”,向量检索可能召回各种退款流程的文档,但关键词“退款订单号”能直接命中具体记录。我一般用 RRF 倒数排序融合,简单有效。这里有个前提:你得有好的分词器和倒排索引,不然关键词检索本身就不准。
接着说重排序。向量检索用的是 Bi-Encoder,查询和文档分开编码,效率高但精度有限。重排阶段我会换成 Cross-Encoder,把查询和文档拼在一起做交互注意力,相关性打分更准。但代价是慢,所以一般走两阶段:先用向量检索召回 Top 100,再用轻量重排模型筛出 Top 5。这样延迟增加不大,但精度提升明显。
再补充查询改写。用户的问题经常表述模糊,比如“怎么省钱”,文档里写的可能是“降低成本的策略”。直接检索可能漏掉。我会用 LLM 做同义扩展,或者用 HyDE 方法:让模型先根据问题写一个理想答案,然后用答案的向量去检索。这样隐式地把问题转成了文档侧的表达。但有个风险:如果 LLM 生成的假答案质量差,反而会带偏检索。所以 HyDE 更适合问题清晰但措辞不匹配的场景,如果问题本身就很模糊,不如先做多轮对话澄清。
其实还有一个方向是上下文压缩,检索回来的长文档里经常夹杂噪声,用 LLM 提取相关片段能提升生成质量。但这里有个取舍:压缩本身增加了延迟和成本,而且压缩模型如果不够强,可能丢掉关键信息。所以 我更倾向把压缩作为可选模块,只在文档特别长、噪声特别大时才启用。
最后总结一下我的判断:没有银弹。混合检索是基础,几乎必上;重排序是精度提升的利器,但延迟敏感场景要慎用;查询改写适合问题模糊的交互场景。上线前我会特别关注检索延迟和召回率之间的平衡,用一组离线 query 做回归测试,确保改动不导致 Recall 掉点。如果只让我选一个方向深耕,我会选 重排序,因为它直接提升最终生成质量,而且随着 Cross-Encoder 模型越来越轻量,延迟问题在逐步缓解。
关键一句:上下文压缩作为可选模块,在文档长噪声大时启用,但需权衡延迟和成本。
面试官还可能这样问
- 问法 1 · 场景切入
假设你在做电商客服系统,用户问“上次那款手机有优惠吗”,但系统里商品描述是“限时折扣”,直接向量检索可能匹配不上。你会怎么设计检索模块,让这种同义但措辞不同的查询也能找到正确答案?
- 问法 2 · 层层追问
RAG系统里检索是怎么工作的?……如果用户查询“怎么退款”,但文档里写的是“退货流程”,你如何提升相关性?……还有没有其他方法,比如在查询或者结果上做文章?
- 问法 3 · 直球架构
请说明RAG检索模块的工作机制,然后列举至少三种提升检索结果相关性的方法,并解释每种方法的原理。