当前位置: 首页 > news >正文

RAG优化的多路召回-混合检索

总结:

混合检索 = 关键词 + 语义向量检索

建两套索引,一个关键词 (稀疏检索,BM25),一个向量(稠密检索

多路召回怎么融合,最简单的就是排名求和(倒数排序融合),计算两种索引召回准确率的排名,然后把段落排名求和取排名最前的,文本片段。

---------详细介绍--------------------------------------

先搞清:RAG 的检索召回层在干嘛?

把 RAG 想象成一个开卷考试的学霸

  • 用户问一个问题(考题)

  • 他先去翻一堆参考书(检索召回),找到最相关的几段话

  • 然后把这些段落抄下来,结合自己的理解,拼成最终答案(生成

你问的“检索召回层”,就是那个翻书找段落的环节。它不用生成任何新内容,只管“找到可能用得上的资料”。


为什么需要“混合检索”?单一检索不够吗?

早期翻书只有一种方法:看关键词。比如你搜“苹果手机”,它就去找所有包含“苹果手机”这四个字的页面。这叫关键词检索(像图书馆的卡片索引,学名稀疏检索,BM25 是代表作)。

但问题来了——用户问“水果里那种红红的、脆甜的果子”,它一个字都没提“苹果”,关键词检索就会傻眼,什么都找不到。

后来有了大模型,能把句子变成一串数字(向量),意思相近的句子,数字也挨得近。于是可以按语义找,你说“红红的脆甜果子”,它能找到“苹果”的段落。这叫语义检索(也叫稠密检索)。

但语义检索也不是万能:

  • 它可能把“苹果手机”和“苹果水果”搞混(模糊性)

  • 对一些特别精确、专有的名词(比如产品型号 XJ-882),反而容易漏掉,不如直接搜字符串来得准。

所以,混合检索 = 关键词检索 + 语义检索。两者互补,一个抓精确匹配,一个抓意思相近,召回的段落更全更准。


实际工程中,到底是怎么做的?

这就好比你要同时查两种目录:一个是传统的书末“关键词索引”,一个是新潮的“概念地图”。在工程上,你需要搭建两个不同的“索引库”,然后把两个结果巧妙地揉在一起。

第一步:建好两个“库”

你得预先把所有参考书(你的文档库)处理成两种形态:

  1. 关键词索引库(给 BM25 用)

    • 把每段文本拆词,建立“倒排索引”:哪个词出现在了哪几个段落里。

    • 常用工具:Elasticsearch(最常用)、OpenSearch、Lucene。它们自带强悍的 BM25 算法。

    • 你只需要把文本丢进去,它内部就建好了。

  2. 语义向量库(给向量检索用)

    • 用一个大模型(比如 text-embedding-ada-002 或开源的 BGE)把每个段落都算成一个向量(比如 1024 维的一串小数)。

    • 把这些向量存进一个专门的向量数据库

    • 常用工具:Milvus、Pinecone、Weaviate、Qdrant、FAISS(Facebook 的库,常被集成)。

所以,你的一份文档,会变成两份副本,存在两个不同的库里。这叫双索引架构。

第二步:接到问题,同时发问

当用户问题来了,你也得准备两路:

  • 关键词查询:直接把问题文本丢给 Elasticsearch,让它用 BM25 去找。Elasticsearch 会返回最匹配的 N 个段落,并给每个段落打个相关性分数(比如 score=5.2)。

  • 语义查询:用同一个 embedding 模型把用户问题也转成向量,然后去向量数据库里搜最相似的 M 个段落。向量库也会返回每个段落一个相似度分数(比如 0.89)。

这两路查询完全独立,可以同时进行,不会相互等待。这是工程上能快的关键。

第三步:把两个结果“揉”在一起(这才是难点)

现在你手上有两份结果列表,可能长这样:

  • 关键词结果(BM25): [(段落A, 5.2), (段落B, 4.1), (段落D, 3.8) ...]

  • 语义结果(向量): [(段落C, 0.91), (段落A, 0.88), (段落B, 0.75) ...]

你想把它们合成一个最终列表,给大模型去读。怎么合?直接用分数相加吗?绝对不行!因为分数的尺度不一样:BM25 的分数可能是 1 到几十,向量相似度是 0 到 1。直接加,谁大谁说了算,完全乱套。

工程师们主要有两种成熟招数:

招数一:排名融合(RRF,倒数排序融合)——最流行、最省事
完全不看具体分数,只看排名。

  • 段落A:在关键词路排第1,在语义路排第2。

  • 段落C:在语义路排第1,在关键词路压根没进前10(排第20)。

  • RRF 会给每个排名位置一个固定的分:第1名得1/(60+1),第2名得1/(60+2)...(60是个魔术常数)。

  • 然后把同一段落在不同路上的分加起来,按总分重新排。这样,两边都靠前的段落会排在前面,只在一边露头的也能有个说得过去的分数。

招数二:分数校准后加权求和——需要调参
用一些数学方法(比如把分数都映射到差不多的范围,或用统计分布)把两路分数变得可比,然后按权重相加:最终分 = a * BM25分 + b * 向量分。这要求你调权重ab,比较吃经验,换一批文档可能又要重调。

实际工程中,RRF 因为零参数、效果好,被大量使用。

一个典型的实际架构图(手绘版)

text

用户问题 | +-------------------+ | | [关键词查询] [语义向量化] | | Elasticsearch 向量数据库 (BM25检索) (ANN近似检索) | | 结果集1 (带BM25分) 结果集2 (带相似度分) | | +----> 结果融合器 <---+ (例如RRF算法) | 最终 Top-K 段落 | 发给大模型生成

有没有更省事的一站式方案?

有的。现在很多新式数据库看到了这个需求,直接在一个系统里同时维护关键词索引和向量索引,你只需要一次查询,它内部就帮你把混合检索做了。比如:

  • Elasticsearch 8.x+:自带了向量字段,一条查询可以同时写 BM25 条件和 kNN 向量搜索,内部用线性加权或 RRF 融合。

  • Weaviate、Pinecone等现代向量数据库:大多都增加了 BM25 或混合搜索的支持。

但即使如此,理解上述分离的原理也至关重要,因为调优时你还是得知道里面发生了什么。

总结:实际工程的三个核心

  1. 双索引:同时维护一个倒排索引和一个向量索引。

  2. 多路并发:查询时间时并行发出,汇合结果。

  3. 排名融合:用类似 RRF 这样不看绝对分数的技巧,公平地合并两个排名。

这就是现在绝大多数 RAG 系统在做“混合检索”时的落地方式。它不神秘,就是把两种找资料的方法结合起来,用“排名”而不是“分数”来达成共识。希望这样讲,你能抓住它的工程内核。如果还有想深挖的点,随时聊

http://www.jsqmd.com/news/1082697/

相关文章:

  • 3个游戏性能优化难题,DLSS Swapper如何帮你一键解决?
  • SQL注入实战:UNION注入原理、手工利用与自动化工具防御
  • Plan-And-Solve 智能体模式:深入解析与实践指南
  • 外区域拉格朗日平均曲率方程:解的存在性、渐近行为与关键技术分析
  • FigmaCN:5分钟让你的Figma界面变中文,设计效率翻倍!
  • 如何通过代理抓包技术实现跨平台网络资源下载
  • 量子图Morita等价性:算子代数框架下的量子信息不变量研究
  • 反激式变压器设计工具:不必再靠感觉和 Excel 反复试算
  • FreeClip2音质变糊?原来是出音孔堵住了!
  • ThinkPHP任意文件下载漏洞原理与自动化验证脚本实战
  • 【数字孪生实战案例】怎样基于数据判定不同线路,完成多路径小车动画的切换展示效果?~山海鲸可视化
  • Raspberry Pi 500+深度定制:从SSD升级到QMK键位编程全攻略
  • 3步搞定!IPXWrapper终极方案:让经典游戏在现代Windows上重获联机功能
  • 数学星球之三大陆
  • 科研干货 | X射线光电子能谱(XPS)化学位移
  • 与自己的全部,温柔相拥
  • 知网文献批量下载工具:3步解决学术研究的文献获取难题
  • 番茄小说下载器架构解析:基于Rust的高性能离线阅读解决方案
  • 终极指南:让Foobar2000歌词体验媲美专业音乐APP
  • N_m3u8DL-RE专业指南:高效流媒体下载实战与深度解析
  • 河道水情数据录入审核与统计分析:从数据底账到调度复盘的业务闭环
  • SNK施努卡GCU控制器自动化产线:120秒节拍,5人完成高节拍智造
  • 终极宝可梦游戏随机化器:Universal Pokemon Randomizer ZX完整指南
  • 实现链表分割
  • 大模型 API 选型方法论:成本与稳定性之间的工程权衡
  • 三分钟玩转大气层整合包系统:轻松解锁Switch无限潜能
  • 芯片干货 |异步内置MOS升压恒压芯片 FP6291,最高输出5-12V/5-7W,输入限流可调
  • 判断提质,而非加速漏斗:AI招聘正在重写HR的核心能力坐标
  • 【每日复盘与反思】2026.6.23
  • Nginx高性能配置与优化实战:从10万并发到100万并发的调优秘籍