当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > 向量检索与关键词检索怎样做混合召回

向量检索与关键词检索怎样做混合召回

来源:17golang原创 2026-10-08 12:32:43 0浏览 收藏

向量检索与关键词检索做混合召回,最稳妥的起点是:两路使用同一查询并行取候选,先各自保留排名,再用 RRF(Reciprocal Rank Fusion,倒数排名融合)合成统一顺序。不要直接把 BM25 分数和向量相似度相加,因为两者的范围、分布和含义不同,换模型或换语料后还会漂移。

核心方案
  • 关键词路负责产品编号、错误码、专有名词、日期和精确短语。
  • 向量路负责同义改写、自然语言问题和概念相近但字面不同的内容。
  • 两路候选按稳定文档 ID 去重,用 RRF 合并名次;权限过滤必须在两路保持一致。
  • 如果还需要更高精度,可在融合后的较小候选集上增加交叉编码器或语义重排。

混合召回解决的不是二选一

关键词检索依赖倒排索引,常见排序基础是 BM25。它擅长精确词面:查询“ERR_CONNECTION_RESET”、SKU“AX-1042”或法规编号时,字面命中通常比语义近似更可靠。它的盲区是同义表达,例如文档写“撤销订单”,用户问“怎么取消购买”,如果没有同义词扩展,召回可能偏低。

向量检索把查询和文档映射到同一个嵌入空间,再按余弦、点积或欧氏距离寻找近邻。它能找出语义接近的改写,但对极短编号、罕见人名、版本号和精确短语未必稳定。混合召回的价值,就是让一个通道补另一个通道的盲区,而不是简单选一个“更先进”的通道。

关键词 BM25 与向量相似度两路候选经过权限过滤和 RRF 合并的静态结构图
图1:关键词与向量双路召回的静态结构图,两路候选先独立排序再融合。

支持范围:先统一文档粒度、标识和过滤

两路结果能不能正确合并,关键不在模型,而在索引契约。关键词索引与向量索引必须指向同一个稳定 doc_id,并尽量使用相同的分块粒度。如果关键词路返回整篇文章、向量路返回段落,融合时就会出现一篇文档挤占多个位置或证据定位不一致。

权限、租户、语言、时间范围和内容状态也必须保持一致。多租户知识库中,不能让向量路先召回全库内容,再依赖最后一步隐藏无权文档;正确做法是让两路都带上可执行的权限过滤,或在进入融合前完成同等强度的过滤。

查询特征更有优势的通道混合时的处理
编号、错误码、专有名词关键词保留精确匹配,必要时提高关键词路候选量
口语问题、同义改写向量用向量路补充字面不一致的内容
既有术语又有描述两者并行召回后用 RRF 合并
强权限或租户隔离两者都必须过滤统一过滤条件,不能只在最终展示层处理

最小实现:用 RRF 合并两组名次

RRF 不关心两路原始分数,只关心每个文档在各自结果中的名次。文档在某一路的贡献是 1 / (k + rank);如果它同时出现在多路结果中,就把贡献相加。k 用来减弱第一名与后续名次的陡峭差异,实践中常从 60 开始,再用评估集决定是否调整。

from collections import defaultdict

def rrf_fuse(rankings: list[list[str]], k: int = 60) -> list[tuple[str, float]]:
    """把多路文档排名合并为统一的 RRF 排名。"""
    scores: dict[str, float] = defaultdict(float)

    for ranking in rankings:
        # rank 从 1 开始;某文档未出现在该路时不增加贡献。
        for rank, doc_id in enumerate(ranking, start=1):
            scores[doc_id] += 1.0 / (k + rank)

    # 分数降序,doc_id 作为稳定次级排序,避免同分时随机抖动。
    return sorted(scores.items(), key=lambda item: (-item[1], item[0]))


keyword_topk = ["doc-a", "doc-b", "doc-c"]
vector_topk = ["doc-b", "doc-d", "doc-a"]

# 两路都靠前的 doc-b 会累加两份倒数名次贡献。
merged = rrf_fuse([keyword_topk, vector_topk], k=60)
print(merged[:3])

实际系统中,关键词检索与向量检索应并行执行,各自取比最终返回数更大的候选。例如最终需要 10 条,可以先让每路取 30~100 条,再融合、去重、过滤并截取 TopN。具体候选量不能照抄固定值,应由语料规模、查询类型、延迟预算和 Recall@K 实验决定。

BM25 排名与向量排名通过倒数名次贡献形成 RRF 融合排名的静态说明图
图2:RRF 名次融合静态说明图,双路靠前的文档会累加更多贡献。

兼容处理:什么时候不用纯 RRF

RRF 是很好的默认方案,因为它不要求分数同量纲,也不需要先训练校准器。但它只利用名次,不利用“第一名比第二名究竟高多少”的置信差距。如果你已经有稳定标注集,并能把 BM25 与向量分数校准到可比较范围,就可以尝试线性加权;否则直接写 0.5 × BM25 + 0.5 × cosine 往往只是看起来公平。

另一种常见结构是“混合召回 + 二阶段重排”。先用 RRF 得到几十条候选,再让交叉编码器或语义排序器结合查询和正文重排。它通常能提升前几位精度,但会增加推理延迟与成本,因此适合只处理小候选集,而不是对整个语料逐条打分。

如果业务查询有明显类型,也可以做轻量路由:纯编号查询提高关键词候选配额,自然语言问题提高向量候选配额,但仍保留另一条通道作为兜底。路由规则必须通过真实查询日志和标注集验证,不能只凭长度或是否含空格做武断判断。

性能与安全:并行、超时、去重和权限

两路串行会把延迟相加,因此应并行发起并设置独立超时。若一个通道超时,可在明确降级策略下返回另一路结果,同时记录降级率;如果搜索用于高风险决策或强一致场景,则应选择失败而不是静默降级。

融合前先用稳定 ID 去重,融合后再执行内容级去重,避免同一文章相邻分块占满结果。向量生成模型、分块策略或 BM25 字段权重发生变化时,应视为检索版本变更,重新跑离线评估,而不是只观察点击率。

安全边界比排序更优先:关键词与向量索引都要带租户、ACL 和内容状态;缓存键必须包含租户与权限摘要;调试日志可以记录文档 ID、通道名和排名,但不要记录敏感正文、用户私有查询或向量原值。

用评估集决定参数,而不是凭感觉调权重

准备一组来自真实业务的查询,并为每个查询标注相关文档。至少对比三条基线:关键词单路、向量单路、混合召回。召回阶段关注 Recall@K,排序质量可看 MRR 或 nDCG@K,同时记录 P50/P95 延迟、超时率和每次查询成本。

调参时一次只改一个变量:每路 TopK、RRF 的 k、向量权重、过滤位置或重排候选数。特别检查“精确术语”“同义改写”“多语言”“短查询”“长问题”和“无答案查询”几个切片。只有混合方案在核心切片上稳定优于单路基线,且延迟与成本可接受,才算完成验收。

相关问题

RRF 中的 k 和向量检索 TopK 是同一个参数吗?

不是。RRF 的 k 是平滑名次贡献的常量;向量检索的 TopK 是候选数量。两者应分别调节。

关键词和向量结果一定要各占一半吗?

不需要。RRF 默认按名次贡献,也可以为不同通道加入权重;但权重应来自标注集,而不是为了形式上的五五开。

混合召回后还需要重排吗?

取决于目标。如果只要求较高召回和低延迟,RRF 可能已经足够;如果前几位精度直接影响 RAG 答案质量,可以在小候选集上增加二阶段重排。

过滤应该在融合前还是融合后?

权限和租户过滤必须尽量在两路检索时执行,并在融合前确保一致;普通业务筛选可按引擎能力选择前置或后置,但要评估它对候选数量和召回率的影响。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
事务已经回滚却仍占用连接,常见的资源遗漏在哪里事务已经回滚却仍占用连接,常见的资源遗漏在哪里
上一篇
事务已经回滚却仍占用连接,常见的资源遗漏在哪里
Claude Sonnet 5.5 更新后,企业为何更看重速度与单位成本
下一篇
Claude Sonnet 5.5 更新后,企业为何更看重速度与单位成本
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    375次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    445次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    454次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    399次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    226次使用