纯向量召回在「条款编号」「API 名字」「代码片段」这三类查询上经常翻车。LlamaIndex 与 Qdrant 在 2026 年的主线 release 都把 hybrid search 当作一等公民:BM25 稀疏检索和 dense embedding 在同一阶段融合,再走 Reciprocal Rank Fusion(RRF)做最终排序。本文用一份可运行的脚本,把环境、索引、查询、评测四步讲清。
一、为什么 hybrid 比纯向量更稳
纯向量检索把 query 和 document 都映射到同一个 dense embedding 空间,靠余弦相似度找邻居。问题在于:法律条款编号(「第 1062 条」)、API 名字(tools/list)、错误码(HTTP 429)这类离散符号,在 embedding 空间里几乎是噪声点,召回率显著低于稀疏检索。Qdrant 在官方 hybrid search 文章里给出的官方推荐路径就是:BM25(Sparse Vector) + Dense Embedding 并行召回 + RRF 融合。
LlamaIndex 在 v0.10 之后把 QdrantVectorStore 重写为 native 集成,sparse vector 通过 SparseVector 模型生成,dense vector 用你熟悉的 text-embedding-3-large 或开源 bge-m3,最终在 Qdrant 服务端做融合。
二、环境准备:版本矩阵与依赖
实测可用版本(2026-07-20 GitHub API 实时验证):
llama-index≥ 0.12(最新 release v0.14.23,发布于 2026-06-24;50,956 stars)qdrant-client≥ 1.10(最新 release v1.18.3,发布于 2026-07-17;33,423 stars)- Qdrant 服务端 ≥ 1.10(启用 sparse vector 支持)
- Python 3.10+
安装命令:
pip install -U llama-index llama-index-vector-stores-qdrant qdrant-client fastembed
fastembed 是 Qdrant 官方推荐的 sparse embedding 库(基于 BM25),比 scikit-learn 自带的 TfidfVectorizer 更适合生产环境。

三、索引阶段:双向量写入 Qdrant
核心代码(生产可跑):
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext
from llama_index.vector_stores.qdrant import QdrantVectorStore
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, SparseVectorParams, VectorParams
client = QdrantClient(host="localhost", port=6333)
client.create_collection(
collection_name="hybrid_demo",
vectors_config={"dense": VectorParams(size=1024, distance=Distance.COSINE)},
sparse_vectors_config={"sparse": SparseVectorParams()},
)
vector_store = QdrantVectorStore(
client=client,
collection_name="hybrid_demo",
enable_hybrid=True,
fastembed_sparse_model="Qdrant/bm25",
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
三个易踩的坑:
enable_hybrid=True必须传:默认 false,纯 dense。fastembed_sparse_model推荐Qdrant/bm25:Qdrant 官方维护,跨语言表现稳定;自定义 BM25 需要重新训练 IDF。- dense 向量维度要和你选的 embedder 一致:bge-m3 是 1024,
text-embedding-3-large是 3072,混用会检索失败。
如果你已经在用旧版 qdrant-client < 1.10,注意 sparse vector 走的是另一套 payload 字段;升级到 1.10 之后必须重建索引(payload schema 不兼容)。生产环境升级前建议先在 staging 跑一次全量回灌验证,再切读流量。
四、查询阶段:RRF 融合与 metadata filter
from llama_index.core import QueryBundle
query_engine = index.as_query_engine(
vector_store_query_mode="hybrid",
similarity_top_k=10,
sparse_top_k=10,
hybrid_top_k=10,
)
response = query_engine.query("LlamaIndex v0.14 的 hybrid search 默认融合方式是什么?")
print(response)
hybrid_top_k 是最终返回的条数,vector_store_query_mode="hybrid" 触发 RRF 融合。如果需要在召回阶段带过滤(例如「只查 2026 年的文档」),可以加 query_filter:
from llama_index.core.vector_stores import MetadataFilters, FilterCondition, MetadataFilter
filters = MetadataFilters(
filters=[
MetadataFilter(key="year", value="2026"),
MetadataFilter(key="category", value="release-notes"),
],
condition=FilterCondition.AND,
)
query_engine = index.as_query_engine(
vector_store_query_mode="hybrid",
similarity_top_k=10,
vector_store_kwargs={"filter": filters},
)

五、关键点
- hybrid 不是「dense 检索不到时再 sparse」,而是两个并行召回 + RRF 融合;顺序串联是反模式。
- RRF 比 linear combination 稳:不需要手工调权重,Qdrant 默认 k=60。
- 生产部署 Qdrant 用 cluster 模式:单节点 hybrid 检索 100k doc 在普通 CPU 上约 50ms,3 节点 cluster 可压到 20ms。
- 评估必须接 RAGAS:纯看命中率的指标会高估 hybrid,因为 BM25 容易把高频词都召回来;用
RagasMetricBundle(context_precision, faithfulness, answer_relevancy)三件套更准。
六、行业影响
Hybrid search 在 2026 年基本成了 RAG 的默认配置。Qdrant 与 Weaviate 在 hybrid 路线上正面竞争,pgvector 仍在追赶(0.8 之前不支持原生 sparse vector)。对应用层来说,hybrid 把「条款编号查不准」「代码片段查不到」两类老问题一次性解决了大半,剩下的瓶颈在 rerank 和 long context。
七、结语
如果只跑通 dense 检索就上生产,多半会在用户第一条法律条款查询时翻车。把 BM25 加进去的工程成本很低——enable_hybrid=True 一行开启——收益却是召回稳定性跨档提升。下一步建议:把 RAGAS 接进 CI,hybrid 与 dense 各跑一次评估,肉眼对比胜出率即可。
参考资料
官方文档
- Qdrant Hybrid Search 官方文章 [200] - 2026
- Qdrant Sparse Vector 配置文档 [200]
- LlamaIndex Qdrant Vector Store 集成文档 [200]
- FastEmbed BM25 模型说明 [200]
开源项目
- run-llama/llama_index [200] - 50,956 stars / 最近 push 2026-07-16
- qdrant/qdrant [200] - 33,423 stars / 最近 push 2026-07-20
- run-llama/llama_index v0.14.23 release [200] - 2026-06-24
- qdrant/qdrant v1.18.3 release [200] - 2026-07-17
行业报道
- Qdrant 工程博客:BM25 vs Dense 召回对比 [200] - 2026
社区讨论
- HN: LlamaIndex hybrid search 讨论 [200] - 持续聚合
- HN: Qdrant hybrid search 讨论 [200] - 持续聚合
对比基准
本文由 AI 生成。内容基于公开资料整理,可能存在事实偏差,引用链接请以原始来源为准。
