跳到内容

进阶★★★★10 分钟阅读

RAG 系统用 hybrid search(BM25 + 向量)

纯向量搜索抓不到关键字,纯关键字搜索抓不到语义。结合起来,这是食谱。

登入以收藏

如果你出货过纯向量搜索的 RAG,你大概有遇过这种震惊:用户打了清楚关键字 query 像「退款政策」,结果检索没抓到那份标题就叫「退款政策」的文档。这不是 bug,是向量搜索本来就会这样。

Hybrid search —— BM25(词汇 / 关键字)加 dense vector(语义)—— 就是来解这个的。它不是 2026 的新发明,在 production RAG 系统里已经当黄金标准两年了。如果你在做认真的检索,该用。

为什么纯向量会漏东西

Dense embedding 抓意思强,但抓「精确识别字」很烂:

  • 产品 SKU XB-447-Z。embedding 模型没看过它,跟任何东西的 cosine 相似度都没意义。
  • 人名「Ahmadinejad」。罕见 token,embedding 变异很大。
  • 缩写 RAG 跟单词 rag。embedding 一样。
  • 最新新闻「DeepSeek V4 release」—— 如果在 embedding 模型训练截止之后,它基本上是随机的。

BM25 是反过来。它擅长精确比对。「退款政策」会找到含这些字的文档;它抓不到改写 —— 「退货流程」不会比对到「退款政策」即使意思一样。

Hybrid 同时拿到两种能力。

BM25 30 秒解释

BM25(Best Match 25)是 1990 年代基于词频的评分函数。对 query Q 跟文档 D:

  1. Q 里每个词,数它在 D 里出现几次(term frequency)。
  2. 用 inverse document frequency 惩罚常见词(the、a)。
  3. 对文档长度做规范化(避免长文档偏误)。
  4. 每个词的分数加总。

单一个方程式,有对的索引能在百万文档上毫秒响应,在 Elasticsearch 跟 Lucene 里当默认搜索算法已经几十年。现代变体(BM25F、BM25+)调 edge case,核心想法没变。

BM25 不需要 GPU、embedding 或训练。倒排索引就好。

食谱:并行 + 结合

基本 hybrid pattern:

  1. 把用户 query 并行送到两个系统。
  2. 各回 top K 结果加分数。
  3. 把排名结合成单一列表。
  4. 可选:用 cross-encoder 重排。

结合那步是有选择的地方。三种常见做法:

RRF(Reciprocal Rank Fusion)

最简单而且意外地好用:

对任一结果列表里的文档 d:
  score(d) = 1/(k + rank_bm25(d)) + 1/(k + rank_vector(d))

k 是常数(60 是标准)。在任一列表排前面的文档拿高分,在两边都排前面的拿最高。RRF 不在乎两个系统的绝对分数,只看相对排名。这很稳,因为 BM25 分数跟 cosine 相似度不能直接比。

这是默认值。没理由不用就用这个。

加权分数融合

把两边分数规范化,加权加总:

final = alpha * normalized_bm25 + (1 - alpha) * normalized_vector

控制更多。你可以针对领域调 alpha(法律 / 医疗多重词汇、客服聊天多重语义)。要做超参数搜索,所以大部分人就用 RRF。

Cross-encoder 重排

贵但最准的选项:

  1. BM25 拿 top 50 + 向量拿 top 50,去重。
  2. 大约 100 个候选全部跑 cross-encoder(例如 BAAI/bge-reranker-v2-m3、Cohere Rerank、Jina Reranker v2)。
  3. 拿 cross-encoder 的 top 10。

Cross-encoder 用 attention 同时比对 query 跟文档,所以抓到 bi-encoder embedding 漏掉的细节。它较慢(每个 (query, doc) 对都要推理)但 top-K 明显更好。

2026 年认真系统的做法:BM25 + 向量候选 → reranker → 最终 K。

2026 的实作

看你的 stack 三条路:

路径 1:Postgres + pgvector

数据已经在 Postgres,加 pg_trgm 做 trigram BM25-ish 搜索,加 pgvector 做向量:

-- BM25-ish 用 tsvector + tsrank
SELECT id, ts_rank(content_tsv, plainto_tsquery('退款政策')) AS bm_score
FROM docs
ORDER BY bm_score DESC LIMIT 50;

-- 向量
SELECT id, 1 - (embedding <=> $1) AS vec_score
FROM docs
ORDER BY embedding <=> $1 LIMIT 50;

-- 在应用代码里用 RRF 结合

Production 级 Postgres BM25 用 paradedb extension(2024 发布),提供真正 SQL 内 BM25。2026 年最干净的单数据库 hybrid 配置。

路径 2:Elasticsearch / OpenSearch

Elasticsearch 自 2022 就有 dense_vector field type,BM25 一直都有。跑两个 query(文字 + kNN),用 RRF 或 rank block 结合:

{
  "retriever": {
    "rrf": {
      "retrievers": [
        { "standard": { "query": { "match": { "content": "退款政策" } } } },
        { "knn": { "field": "embedding", "query_vector": [...], "k": 50 } }
      ]
    }
  }
}

ES 8.8 加入了原生 RRF。已经在用 Elasticsearch 的话这是最干净配置。

路径 3:Vector DB + 独立 BM25 服务

用 Pinecone、Qdrant、Weaviate、LanceDB?大部分现在都内建 BM25 / sparse vector 支持:

  • Qdrant。 2024 年原生 sparse vector + BM25 内建。
  • Weaviate。 原生 hybrid query 模式,alpha 参数调校。
  • Pinecone。 Sparse-dense hybrid 用他们的 splade 风格 sparse vector。
  • LanceDB。 FTS + 向量内建融合。

不用 Postgres 或 Elastic 的话挑这些其中一个。

调校建议

Hybrid 接好后:

  • 跑你的 eval set(你有对吧?看 RAG evaluation 那篇)。比较 hybrid 跟纯向量的 recall@K。Hybrid 在真实 query 上通常赢纯向量 5-15% recall,在多关键字 query 上更多。
  • 不要过度调 alpha。 RRF k=60 是稳固基线。只有你的领域严重偏向(法律文档需要更多词汇、聊天需要更多语义)才调。
  • 检索看起来 OK 之后加 reranker。 重排会叠加效益:hybrid + reranker 通常比纯向量单独好 20-30%。
  • 盯延迟。 两次检索 + rerank = 200-400ms。用户感觉得到就把 BM25 跟向量调用并行化(它们独立),而且考虑把 reranker 放 GPU 上跑。

什么时候不必做

  • 小 corpus(<1000 文档)。 纯向量就好。recall 差距是噪声。
  • 你的 query 都是自然语言改写。 纯语义实际赢。用户从不打关键字,BM25 没帮助。
  • 你还没建 eval set。 先做那个,没它你判断不出 hybrid 有没有真的帮到。

务实默认

从零开始要一个决定:Qdrant + Cohere Rerank(2026 年)。Qdrant 给你原生 hybrid、快、好操作。Cohere Rerank 是托管 API 中质量最高的 reranker(每 1000 个文档重排 $0.002,基本免费)。总基础建设:一个 Qdrant cluster、一个 API key、三行接合代码。这配置赢 95% 定制检索管线。

不能用外部 API,把 Cohere 换成单张 GPU 自架的 BAAI/bge-reranker-v2-m3

下一步

  • Pretrained Transformers for Text Ranking: BERT and Beyond —— dense retrieval 经典。
  • BEIR benchmark 论文 —— 跨领域检索评测,验证 hybrid 优越性。
  • Vespa / Pinecone / Qdrant 博客的 production hybrid setup 文章。
  • 查这些词:SPLADE、ColBERT、BM25 vs SPLADE、query expansion。

最后更新: 2026-04-29

We use cookies

Anonymous analytics help us improve the site. You can opt out anytime. Learn more

RAG 系统用 hybrid search(BM25 + 向量) · BuilderWorld