AIGC标识 RAG Hybrid 到底混合了什么

Hybrid 检索混合的是字面召回和语义召回两套能力,而不是简单相加两个分数;RRF 和 rerank 各有清晰位置。>
阅读时间​:约 6 分钟

很多 RAG 方案都会写“Hybrid = BM25 + 向量 + rerank”。这句话没错,但太短了,短到容易把三件事混成一团。

真正需要问的是:

  • BM25 在哪一步工作
  • 向量索引在找什么
  • 两路分数怎么合
  • rerank 为什么不能直接跑全库

把这些问题放进一条检索漏斗里,Hybrid 就清楚了。


inline-01.png

图:Hybrid 检索漏斗

先把检索漏斗放正

一次 query 进入 RAG 系统后,通常不会直接交给大模型。它先经过检索层,把知识库里可能相关的片段筛出来。

Hybrid 的完整路径可以压成这张图:
mermaid-01.png

这条链路里有三个容易混淆的位置:

  • BM25 是字面召回内部的排序算法
  • RRF 负责把两路召回结果合成一个候选列表
  • rerank 在漏斗尾部精排,不参与全库召回

所以,“检索”不是单个动作。它是一组接力:先尽量召回,再合并候选,最后用更贵的模型重新排序。


字面路线负责找“词对得上”的内容

字面检索解决的问题很具体:用户输入几个词,系统要快速找到包含这些词的文档或片段,并排出相关性。

它的流水线通常是这样:
mermaid-02.png

分词先解决边界问题。英文天然有空格,中文没有。“中文分词”可以切成 中文 / 文分 / 分词,这类 bigram 切法不依赖词典,覆盖率高,但会产生 文分 这种没有语义的词元。

分词必须和索引对齐

常见切法的取舍如下:

方法 切法例子 主要取舍
unigram 中 / 文 / 分 / 词 几乎不漏,误匹配多
bigram 中文 / 文分 / 分词 不依赖词典,索引更大
词典分词 中文 / 分词 更贴语义,需要维护词典

倒排索引让查询避开全库扫描

倒排索引解决速度问题。普通正排结构是“文档 -> 词”,查的时候要扫文档。倒排结构改成“词 -> 文档列表”:

"中文" -> [文档 1, 文档 5, 文档 8]
"分词" -> [文档 1, 文档 8, 文档 20]

查“中文分词”时,只要取两个列表的交集,就能直接拿到文档 1 和文档 8。SQLite FTS5、Lucene、Elasticsearch 都建立在这个基本结构之上,区别主要在工程规模和功能完整度。

BM25 只接手命中后的排序

BM25 接在倒排索引后面。它不负责“找出哪些文档命中”,只负责“命中的文档谁更靠前”。

BM25 的排序直觉有三条:

  • 词频越高,通常越相关,但会有饱和上限
  • 越稀有的词权重越高,常见虚词权重低
  • 长文档天然更容易命中,需要做长度归一化

覆盖率过滤负责拦掉低命中噪声

最后还会加覆盖率过滤。用户搜“中文分词算法原理”,某篇文档只命中“原理”,BM25 也可能给它一个低分。覆盖率过滤会看 query 词元命中了多少比例,低于阈值就直接丢掉。

这一整套路线很稳定,尤其擅长专名、型号、错误码和罕见术语。它的短板也明显:用户换一种说法,字面没重合,它就容易漏。


语义路线负责找“意思对得上”的内容

语义检索处理的是另一个问题:query 和文档没有相同词,但表达的是同一个意思。

例如用户搜“怎么让搜索更准”,知识库里写的是“检索质量优化”。字面路线可能抓不到,语义路线有机会命中。

它的链路通常这样走:
mermaid-03.png

chunk 是先被迫出现的。长文档直接做 embedding 有两个问题:

  • embedding 模型有输入长度上限
  • 一篇长文可能同时讲多个主题,压成一个向量会稀释语义

RAG 还要把检索结果塞回 LLM 上下文窗口。窗口有限,系统只能投喂小段内容。所以语义检索通常先切 chunk,再对每个 chunk 建向量。

embedding 把文本压成一串数字,也就是语义坐标。query 和文档片段都用同一个模型编码,坐标越近,语义越接近。

这里用的是 Bi-Encoder 思路:query 和文档分开编码。文档向量可以提前算好,在线查询时只需要算 query 向量,再去库里找最近邻。

向量索引用 ANN(Approximate Nearest Neighbor,近似最近邻)解决速度问题。精确做法是把 query 向量和库里每个向量都算一遍距离,结果最准,但库大以后太慢。ANN 用近似路径快速找一批大概率接近的向量,可能漏掉少数最佳结果,换来查询速度。

语义路线的排序依据通常是余弦相似度。它在这条路线里的位置,和 BM25 在字面路线里的位置相似:候选拿到以后,用一个分数排先后。


Hybrid 的关键动作是融合名次

字面路线和语义路线互补:

路线 强项 盲区
字面检索 专名、型号、错误码、生僻术语 同义改写和意图表达
语义检索 同义表达、自然语言问题、概念相近内容 精确词和罕见实体

Hybrid 的做法直接:两路都跑,各自给出候选,然后合并。

问题在合并环节。BM25 分数和向量相似度不是同一种量纲,直接相加没有意义。

常用方法是 RRF(Reciprocal Rank Fusion,倒数排名融合)。它不看原始分数,只看同一个 chunk 在两路列表里的名次。

排名越靠前,贡献越大。同一个 chunk 在两路都靠前,就更容易进入最终候选。

这也是为什么很多系统会让两路检索基于同一批 chunk 建索引。只有候选对象一致,RRF 才能把两个列表里的名次合到一起。


rerank 在最后一段重新判相关性

融合后的候选仍然偏粗。rerank 的职责,是在更小的候选集合上重新判断 query 和文档片段的相关性。

它常用 Cross-Encoder:把 query 和 chunk 拼在一起送进模型,现场算一个相关性分。

Cross-Encoder 比 Bi-Encoder 更准,因为模型能同时看见 query 和候选内容,直接比较二者关系。代价也很清楚:

  • 文档不能提前离线编码成可复用向量
  • 每个候选都要在线重算
  • 成本高,不能对全库逐条跑

所以 rerank 只能放在漏斗末端。前面两路召回负责“快而全”,它负责“慢而准”。

这也解释了一个常见困惑:BM25 是排序,rerank 也是排序,二者是否重复?

不重复。排序在不同阶段反复发生:

  1. BM25 在字面召回内部粗排
  2. 向量相似度在语义召回内部粗排
  3. RRF 按两路名次合并
  4. rerank 对融合候选精排

它们处理的候选范围不同,使用的判断依据也不同。


索引只解决速度,不直接等于质量

理解 Hybrid 前,还要把“算法”和“索引”拆开。

BM25 是打分算法,倒排索引是加速结构。理论上,你可以不用倒排索引,改用全表扫描找出含词文档,再套 BM25 公式打分。结果不变,只是慢得多。

向量路线也一样。余弦相似度是打分方式,ANN 是加速结构。

你可以不用 ANN,改成暴力 KNN,对每个向量逐条计算相似度。结果更精确,但大规模场景跑不动。

对照关系如下:

环节 字面路线 语义路线
打分算法 BM25 / TF-IDF 余弦相似度
加速索引 倒排索引 ANN,如 HNSW / IVF
不用索引时 全表扫描或 grep 式匹配 暴力 KNN
代价 结果不变,速度下降 速度下降,精度通常更高

索引换来的主要是速度和可扩展性。ANN 甚至会为了速度牺牲一点精度。

这个区分能避免两个误读:把 BM25 等同于倒排索引,把向量检索等同于向量库。算法决定怎么打分,索引决定怎么更快找到候选。


离线建库决定两路能不能并起来

线上 query 能不能顺利走 Hybrid,取决于离线阶段有没有把同一批内容准备成两套索引。

常见建库流程如下:

原始文件(PDF / Word / HTML)
  -> 解析抽取纯文本
  -> 清理格式、图片和无关排版
  -> 切成 chunk
  -> 对同一批 chunk 建两套索引:
       1. 分词后写入倒排索引,供 BM25 使用
       2. 通过 embedding 生成向量,写入向量索引

所以,支持 Hybrid 需要系统主动维护倒排索引。它不是“向量库顺手送了关键词检索”。

这件事有实际成本:建库时间、额外存储、两路查询和融合计算。

Weaviate、Qdrant、Milvus、Elasticsearch 等系统提供 Hybrid 能力,本质也是帮你在一份数据上维护两套检索结构。

如果系统只做传统全文检索,而且结果直接给人看,不喂给 LLM,也不需要 embedding,那么可以直接对整篇原文建倒排索引。chunk 不是 BM25 的硬要求,它主要来自向量模型长度和 LLM 上下文窗口限制。

一旦 RAG 决定按 chunk 工作,BM25 也应该在同一批 chunk 上建索引。这样字面候选和语义候选才有共同对象,后面的 RRF、rerank 和 Top-K 才能接起来。


最后把几个词钉住

retrievalrecall 在中文里常被一起叫“召回”,但它们不是同一层东西。

  • 召回(retrieval)是流水线阶段:用索引找候选,再做粗排
  • 召回率(recall)是评估指标:相关结果里有多少被找出来了

BM25 和向量检索都属于召回器。rerank 在召回后面,它可以提高最终 Top-K 的相关性,也可能改变召回率指标的表现,但它不是第一段召回动作本身。

把这几个位置摆正以后,Hybrid 的定义就不再含糊:

Hybrid = 字面召回 + 语义召回 + RRF 融合 + rerank 精排 + Top-K 投喂

它混合的是两套互补的召回能力。BM25 兜住精确词,向量兜住语义相近,rerank 再用更贵的模型做最后判断。

RAG 检索的质量,往往就卡在这些边界上:该快的地方要快,该准的地方再花钱,别把一个环节误当成整条链路。

推荐阅读

LLM 强化学习为什么能落地

DeepSeek Harness 的 Agent 运行时设计

长任务 Coding Agent 的关键不是写代码,而是交付链路

当 LoRA 变成 Agent 工具:模型会不会开始管理自己的长期记忆

好的 AI 办公应用,不是聊天框,而是能跑完流程

posted @ 2026-09-09 09:28  AI小老六  阅读(74)  评论(0)    收藏  举报