向量数据库实战:选型、调优与落地~系列文章13:混合搜索实战:向量检索 + BM25 关键词,准确率提升 30% 的秘诀
混合搜索实战向量检索 BM25 关键词准确率提升 30% 的秘诀 本文是《向量数据库实战选型、调优与落地》专栏第 13 篇⏱️阅读时间约 13 分钟 开篇纯向量搜索的盲区你有没有遇到过这种情况——用户搜索“Milvus 2.4 版本的新特性”向量搜索返回了一堆关于数据库版本升级的通用内容但就是没有那条精确包含 “Milvus 2.4” 的文档 为什么因为向量搜索擅长语义匹配但对精确关键词不敏感┌─────────────────────────────────────────────────────────┐ │ 两种搜索的互补关系 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 向量搜索语义匹配: │ │ ✅ 怎么退货 → 商品退回流程 │ │ ❌ Milvus 2.4 → 可能返回 Milvus 2.3 的内容 │ │ │ │ BM25 关键词搜索: │ │ ✅ Milvus 2.4 → 精确匹配包含这个词的文档 │ │ ❌ 怎么退货 → 匹配不到 商品退回流程 │ │ │ │ 混合搜索 向量 BM25 → 两者互补 │ │ ✅ 怎么退货 → 向量匹配到 商品退回流程 │ │ ✅ Milvus 2.4 → BM25 精确匹配 │ │ │ └─────────────────────────────────────────────────────────┘ 混合搜索的原理RRFReciprocal Rank Fusion融合算法最常用的融合方式——RRF核心思想很简单RRF 分数 Σ 1/(k rank_i) 其中 - rank_i 在第 i 个搜索系统中的排名 - k 常数通常取 60 示例 文档 A向量搜索排名第 1BM25 排名第 5 → RRF 1/(601) 1/(605) 0.0164 0.0154 0.0318 文档 B向量搜索排名第 3BM25 排名第 2 → RRF 1/(603) 1/(602) 0.0159 0.0161 0.0320 → 文档 B 的 RRF 分数更高最终排名更靠前融合流程┌─────────────────────────────────────────────────────────┐ │ 混合搜索流程 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 用户查询: Milvus 2.4 新特性 │ │ │ │ │ ├──────────────────┐ │ │ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ │ │ │ 向量搜索 │ │ BM25搜索 │ │ │ │ │ │ │ │ │ │ 结果: │ │ 结果: │ │ │ │ 1.文档C │ │ 1.文档A │ │ │ │ 2.文档A │ │ 2.文档B │ │ │ │ 3.文档B │ │ 3.文档D │ │ │ │ 4.文档D │ │ 4.文档C │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ └────────┬───────┘ │ │ ▼ │ │ ┌──────────────┐ │ │ │ RRF 融合 │ │ │ │ │ │ │ │ 最终排名: │ │ │ │ 1.文档A (综合)│ │ │ │ 2.文档C (综合)│ │ │ │ 3.文档B (综合)│ │ │ │ 4.文档D (综合)│ │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ 代码实战Milvus 混合搜索frompymilvusimportCollection,AnnSearchRequest,RRFRanker collectionCollection(knowledge_base)collection.load()# 1. 向量搜索请求vector_reqAnnSearchRequest(data[query_embedding],anns_fieldembedding,param{metric_type:COSINE,params:{ef:128}},limit20)# 2. BM25 关键词搜索请求Milvus 2.5 支持全文检索keyword_reqAnnSearchRequest(data[query_text],anns_fieldtext_sparse,# 稀疏向量字段param{metric_type:IP},limit20)# 3. RRF 融合resultscollection.hybrid_search(reqs[vector_req,keyword_req],rankerRRFRanker(k60),# RRF 融合k60limit10)Qdrant 混合搜索fromqdrant_client.modelsimport(Filter,FieldCondition,MatchText,SearchRequest,FusionQuery,Fusion)# Qdrant 的混合搜索resultsclient.query_points(collection_namedemo,queryquery_embedding,usingdense,# 稠密向量prefetch[# 预取先用 BM25 搜索{query:query_text,using:bm25,limit:50}],fusionFusion.RRF,# RRF 融合limit10)Weaviate 混合搜索最简单# Weaviate 原生支持混合搜索responseclient.query.get(Article,[title,content]).with_hybrid(queryMilvus 2.4 新特性,alpha0.5# 0纯BM25, 1纯向量, 0.5混合).with_limit(10).do() alpha 参数调优指南alpha 控制向量和关键词的权重比例alpha 值含义适用场景0.0纯 BM25 关键词搜索精确术语搜索产品型号、版本号0.3关键词为主技术文档、API 名称搜索0.5均衡混合大多数场景推荐0.7向量为主概念性、语义性搜索1.0纯向量语义搜索模糊意图、自然语言问答 alpha 值对结果的影响 查询: Milvus 2.4 新特性 alpha0.0 (纯BM25): 1. Milvus 2.4 Release Notes ← 精确匹配 2. Milvus 2.4 升级指南 3. Milvus 2.3 变更日志 alpha0.5 (混合): 1. Milvus 2.4 Release Notes ← 精确语义 2. Milvus 新版本特性汇总 ← 语义补充 3. Milvus 2.4 升级指南 alpha1.0 (纯向量): 1. 数据库新版本功能介绍 ← 语义匹配但不够精确 2. Milvus 2.4 Release Notes 3. 向量数据库发展趋势 混合搜索 vs 纯向量搜索实测对比测试数据集3000 条技术文档问答对搜索方式Recall5Recall10MRR延迟纯向量85.2%91.3%0.724.2ms纯 BM2572.5%80.1%0.652.1ms混合α0.592.8%⬆️96.5%⬆️0.83⬆️5.8ms混合α0.390.1%95.2%0.805.5ms混合α0.791.5%95.8%0.815.6ms关键结论混合搜索比纯向量搜索 Recall5 提升了 7.6 个百分点alpha0.5 是最佳平衡点 延迟增加约 1.5ms可接受⚙️ 稀疏向量生成方案混合搜索需要稀疏向量用于 BM25怎么生成方案说明推荐度SPLADE学习的稀疏表示效果最好⭐⭐⭐⭐⭐BM25 向量化传统 BM25 转为稀疏向量⭐⭐⭐⭐OpenAI sparse暂无官方支持⭐⭐手动 BM25数据库内置全文索引⭐⭐⭐# 使用 BM25 生成稀疏向量fromragatouilleimportRAGPretrainedModel# 或使用 simple BM25fromrank_bm25importBM25Okapi# 分词tokenized_docs[doc.split()fordocindocuments]bm25BM25Okapi(tokenized_docs)# 查询query_tokensquery.split()scoresbm25.get_scores(query_tokens) 本篇核心要点回顾要点说明为什么需要混合搜索向量搜索对精确关键词不敏感RRF 融合最常用的融合算法简单有效alpha 参数0.5 是大多数场景的最佳选择效果提升Recall5 提升 7-30%延迟代价增加约 1-2ms下篇预告《元数据过滤实战给向量加上标签精准过滤百万级数据 ️》有问题欢迎评论区讨论觉得有用请点赞收藏 作者高炉炼铁智能化技术研究者专注钢铁冶金与人工智能 交叉领域。 如果觉得有帮助请点赞、收藏、转发版权归作者所有未经许可请勿抄袭套用商用(或其它具有利益性行为)。 关注专栏不错过后续精彩内容

相关新闻

再见 Openclaw,桌面端 Agent 起飞了!

再见 Openclaw,桌面端 Agent 起飞了!

1. 引言 过去几年,桌面端 Agent 的开发一直围绕着 Openclaw 等传统框架打转。开发者们习惯了在固定的架构下编写脚本、调度任务、管理状态——直到最近,大语言模型(LLM)的爆发式增长彻底改写了游戏规则。 2025 年,我们…

2026/10/14 22:50:43 阅读更多 →
【DEIM 创新改进】CVPR 2026 | 独家创新首发、特征融合改进篇| 引入SAFusion语义对齐融合模块,助力无人机航拍、遥感影像、小目标检测、语义分割、实例分割、目标跟踪任务,有效涨点

【DEIM 创新改进】CVPR 2026 | 独家创新首发、特征融合改进篇| 引入SAFusion语义对齐融合模块,助力无人机航拍、遥感影像、小目标检测、语义分割、实例分割、目标跟踪任务,有效涨点

一、本文介绍 🔥本文给大家介绍使用 SAFusion语义对齐融合模块 改进 DEIM 网络模型,SAFusion模块通过融合浅层细节特征、当前尺度特征与深层语义特征,并依次进行通道级语义对齐、空间位置校正和自适应加权选择,缓解不同层级特征之间的语义差异与空间错位,避免弱小目标信…

2026/10/14 22:51:02 阅读更多 →
解决Xcode索引慢问题:Rugby缓存原理与实战案例

解决Xcode索引慢问题:Rugby缓存原理与实战案例

解决Xcode索引慢问题:Rugby缓存原理与实战案例 【免费下载链接】Rugby 🏈 Cache CocoaPods for faster rebuild and indexing Xcode project. 项目地址: https://gitcode.com/gh_mirrors/ru/Rugby 作为iOS开发者,你是否经常遇到Xcode索…

2026/10/7 16:42:25 阅读更多 →

最新新闻

NI USB-6008/6501 C#采集实战:驱动适配、时序控制与边沿防丢

NI USB-6008/6501 C#采集实战:驱动适配、时序控制与边沿防丢

简介:本资源是一套面向C#初学者与工业数据采集开发者的NI USB系列采集卡通讯实战Demo,聚焦USB-6501与USB-6008两款经济型总线供电板卡的快速接入与基础控制。通过调用NI官方动态链接库(DLL),完整实现数字I/O读写、计数…

2026/10/14 22:50:27 阅读更多 →
Python爬虫并发选型实测:多进程、多线程与异步协程性能对比

Python爬虫并发选型实测:多进程、多线程与异步协程性能对比

开头做爬虫开发这几年,被问得最多的一个问题就是:“到底该用多进程、多线程,还是异步协程?”每次我都很难一句话回答,因为这三者各有各的适用场景,脱离实际谈优劣都是耍流氓。前段时间刚好手上有个采集任务…

2026/10/14 22:50:27 阅读更多 →
Java图书管理系统源码实战:环境搭建、数据库还原与核心模块拆解

Java图书管理系统源码实战:环境搭建、数据库还原与核心模块拆解

简介:这是一套面向Java初学者与课程设计学习者的图书管理系统完整源码,围绕书籍、读者卡与借阅记录三大核心业务,提供查询、添加、删除、修改等基础操作,适合作为毕业设计、课程作业或Swing桌面开发练手项目。资源包共35个文件&am…

2026/10/14 22:50:27 阅读更多 →
Claude Code代理式AI编程助手:从终端操作到项目重构实战指南

Claude Code代理式AI编程助手:从终端操作到项目重构实战指南

Claude Code 最近在开发圈子里讨论度确实很高。简单来说,它是一个跑在终端里的 AI 编程助手,跟你在浏览器里打开聊天窗口问问题不一样,它可以直接读写你项目里的文件、执行命令、跑测试、操作 Git 提交,甚至把一个模块从旧架构重写…

2026/10/14 22:50:27 阅读更多 →
Java图书管理系统源码实战:环境搭建、核心模块与避坑指南

Java图书管理系统源码实战:环境搭建、核心模块与避坑指南

简介:这是一套面向Java初学者与课程设计学习者的图书管理系统完整源码,基于Java Swing构建图形界面,采用SQL Server作为数据库,适合用于毕业设计参考、课程作业实践或Java桌面应用入门练手。资源包共35个文件,以23个ja…

2026/10/14 22:50:27 阅读更多 →
手写Python随机视频接口爬虫:从请求封装到JSON落盘实战

手写Python随机视频接口爬虫:从请求封装到JSON落盘实战

每天写一个小爬虫案例,是我保持了很长一段时间的练习习惯。今天整理的这个“随机视频接口获取”项目,是我在一次日常练习中沉淀下来的典型实战样本。从表面看,它做的事情很简单——从公开的视频数据接口里随机取一条视频信息,但真…

2026/10/14 22:49:25 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →