混合检索milvus推荐的密集嵌入bm25

接入与开发

讲清 Milvus 混合检索里密集嵌入与 BM25 的搭配思路:权重怎么调、字段怎么建、效果怎么测、什么时候不该用混合。

做 RAG 时纯向量召回老漏关键词,纯 BM25 又抓不住同义改写,于是想上 Milvus 的混合检索——结果卡在嵌入模型挑哪个、BM25 要不要单独建字段、两路分数怎么加权、调完怎么知道变好了。这篇不讲原理,只给一套能照着落地的搭配与验证流程,以及什么场景下混合反而不划算。

做 RAG 到一定阶段基本都会撞上这个组合需求:纯向量召回老漏掉型号、订单号、人名这类裸露关键词,纯 BM25 又抓不住用户的同义改写。于是想到 Milvus 的混合检索,把密集嵌入和 BM25 两路并起来。想的没错,但真动手时问题全冒出来了——嵌入模型挑哪个、BM25 要不要单独建字段、两路分数怎么加权、调完怎么知道确实变好了。

这篇不讲向量原理也不推导公式,只给一套能照着落地的搭配与验证流程。核心思路是:先把「该不该上混合」判断清楚,再定嵌入与字段,最后用一份可复现的评测集把权重调出来。反过来,如果场景本来就不适合混合,硬上只会让调参和运维成本翻倍。

先判断该不该上混合:三类信号

别一上来就配混合。先看线上日志里有没有这样的样本:向量没召回、但人工一看明显该召回。把这些样本捞出来看它们长什么样,是判断要不要上混合最省钱的办法。

  • 查询里带型号、订单号、人名、专有名词,纯向量经常召不回——这是混合最典型的适用信号
  • 用户提问是短句、几乎没有语义上下文,向量表示本身就虚,BM25 那一路反而更稳
  • 纯口语化长问句、以同义改写为主的场景,BM25 命中率低,加进来只增加调参负担
日志里的现象更该动的地方
漏召回的样本多是裸露关键词值得上混合,BM25 补关键词那一路
漏召回多是语义漂移、改写没抓住先调分块策略和嵌入模型,不是加 BM25
两路单独跑都还行,合起来反而变差问题在融合权重或候选条数,先调融合
库很小、查询类型单一单路加重排往往就够,别急着上混合

密集嵌入怎么挑:先对齐语言与维度预算

嵌入模型的选择要落到你自己的库上,而不是榜单上。中文为主的语料优先选中文语料训练过的模型;中英混排的库一定要拿真实混合样本测,别只看单语表现。想横向看同类模型的规格与说明,可以去 嵌入模型(/embeddings) 页面核对,但具体效果以自测为准。

维度是另一个要先想清楚的变量。维度越高,存储和检索开销越大;而且在 Milvus 里维度一旦写进集合 schema 就固定了,换模型基本等于重建集合。所以流程应该是先小样本对比几个候选,定下来再灌全量数据。

  1. 准备业务配对样本从真实问题里挑几十到上百条,人工标出应该召回的文档,这是后面所有比较的基准。
  2. 按语言筛候选先按语料语言过滤掉明显不匹配的模型,剩下三到五个候选进下一轮。
  3. 小样本对比同一批样本分别跑候选模型,看召回情况和前几条命中,别只看一个平均分。
  4. 定维度再灌数确认模型与维度后建集合,把配置记进版本文件,后面换模型要能追溯。

BM25 那一路在 Milvus 里怎么落

BM25 靠的是文本字段的分词与倒排,所以文档原文必须以可分词字段存进集合,不能只存向量。中文要先定好分词方式,分词一变结果全变。权重也不该一套走天下:短查询、含专名的查询给 BM25 更高权重,长问句给向量更高权重。

  • 入库前定分词、停用词、是否需要 n-gram,事后改要重刷数据
  • 两路各自出候选后用加权求和或排名融合合并,具体接口参数去官方文档核对
  • 站内工程视角可参考 向量检索、全文检索、混合检索(/guides/vector-fulltext-hybrid-search) 这篇
  • 字段长度和文本清洗方式会直接影响 BM25 打分,别等上线才发现
BM25 的分数只在同一套分词和字段配置下可比,跨配置比大小没有意义。

调参与验收:别凭感觉,留一条可复现的评测

混合检索最容易犯的错是凭单条体验调权重。今天觉得这条好了就加一点,明天又改回去。要避免这个,就得有一份固定的评测集和固定的配置记录。

  1. 建评测集准备 50 到 200 条业务问题并标注正确答案。数量不用多,但要覆盖短查询和长问句两类。
  2. 固定变量把嵌入模型、分词配置、融合权重、候选条数写进配置文件,每次只改一个变量再重跑。
  3. 两路分开看融合前先各自拉前 N 条人眼看。很多时候是某一路本身召回差,融合只是在给坏结果加权。
  4. 分层监控上线后短查询和长查询分开统计,混在一起的平均值会掩盖问题。
要记录的项为什么
嵌入模型标识换模型等于换召回分布,不记就说不清变化来源
分词与字段配置分词一变 BM25 结果全变
融合方式与权重调参的主要旋钮,必须可回滚
候选条数影响召回上限和延迟,和权重是一组
评测集版本样本换了,历史结论就不一定成立

什么情况下不该硬上混合

混合不是越复杂越好。下面几种情况更该先收手:库很小、查询语义单一,单路向量加一个重排往往就够,加 BM25 只会让调参和运维成本翻倍;对延迟极敏感,混合要多跑一路、多一次融合,链路更长,压测不过关就退回单路。

  • 没有标注数据也抽不出人工样本时,无法判断哪套权重更好,先补评测集再谈混合
  • 已有重排环节的,先确认重排调到位没有,它本身就能纠一部分召回噪声
  • 纯口语化短问答场景,第二路召回收益有限,先优化分块和提示词
  • 团队没有精力维护两套配置时,简单可控比理论上的召回上限更重要
下一步把你要用的嵌入模型和检索方案放到同一批样本上比一次,再决定要不要上混合。站内的模型规格与工具目录可以先扫一遍,配合自己的评测集用,比看别人的结论靠谱。

常见问题

Milvus 混合检索里密集嵌入和 BM25 的权重一般怎么定?

没有通用值,取决于查询形态。实践做法是给短查询和含专名的查询调高 BM25 权重,给长问句调高向量权重,然后用自己业务的问题集跑对比。先固定候选条数,只调权重这一个变量,跑几轮看排序变化,别一次改好几项。

BM25 那一路需要把文档原文也存进 Milvus 吗?

需要。BM25 依赖文本字段和分词后的倒排索引,只存向量是跑不起来的。原文要落在可分词字段里,中文还要先定分词方式,因为分词规则一变召回结果就变,改分词往往要重刷数据,所以入库前就要想清楚。

怎么判断加了混合检索确实变好了?

靠可复现的评测集,不靠单条体验。准备一份带标注答案的业务问题集,改动前后各跑一遍,比较召回率和前排命中情况,同时把嵌入模型版本、分词配置、权重都记录下来。只有配置固定,两次结果才有可比性。

本文依据各平台公开文档与官方公告整理,只做中文归纳;具体做法、参数与限制以官方文档为准。