Skip to content

向量检索

🎯 学习目标

  • 按规模与部署方式选择合适的向量库
  • 理解 Hybrid(向量 + BM25)何时优于纯向量
  • 知道 MultiQuery 与压缩检索解决的问题与成本
  • 配置相似度阈值实现「查不到就拒答」

引言

InMemoryVectorStore 适合学习;上线后你要面对百万 chunk、过滤条件、P99 延迟。本节讲向量库选型与检索优化套路,让 recall 与 precision 可 trade-off。

章节正文

第 1 步:向量库选型维度

类型代表适用
内存FAISS、numpy原型、<100万向量
自托管Chroma、Qdrant、Milvus企业 VPC、要 metadata filter
云托管Pinecone、Zilliz Cloud免运维、弹性 scale

选型问:数据量、QPS、是否要 Hybrid 内置、多租户隔离、备份与合规地域。

第 2 步:Hybrid 检索(向量 + BM25)

纯向量对专有名词、型号、错误码弱;BM25 擅精确词匹配。

python
# 概念:分别召回后 RRF 融合
vector_hits = store.search(query_vec, top_k=20)
bm25_hits = bm25_index.search(query_text, top_k=20)
merged = reciprocal_rank_fusion(vector_hits, bm25_hits)[:10]

代码、日志、SKU 类知识库建议默认 Hybrid。

第 3 步:MultiQueryRetriever

用户口语与文档用语不一致时,让 LLM 生成 3–5 个查询变体,分别检索后去重合并:

python
variants = llm.generate(f"为检索生成3个同义查询:{question}")
all_hits = []
for q in variants:
    all_hits.extend(rag_retrieve(store, q, top_k=5))
hits = dedupe_by_chunk_id(all_hits)

提升 recall,但增加 embedding 与检索成本,适合「问法多样、漏召回严重」场景。

第 4 步:压缩检索与阈值拒答

Top-K 片段仍可能很长。Contextual Compression:用小模型或 LLM 对每段 extract 相关句,再注入 Prompt。

python
if hits[0][0] < SIMILARITY_THRESHOLD:
    return {"answer": "知识库中未找到足够相关资料,请咨询人工。", "sources": []}

阈值需按 embedding 模型校准,勿直接抄他人默认值。

第 5 步:metadata 过滤与性能

检索前 filter:product=payments AND version>=2,缩小搜索空间。

索引侧:HNSW 参数、量化(PQ)权衡 recall vs 内存;热数据与冷数据分 collection。监控:P95 检索延迟、hit@K、空结果率。

动手练习

  1. 用 Chroma 或 Qdrant 复现 4.4 索引,对比 InMemory 与持久化差异。
  2. 对含 SKU「XJ-9001」的语料,对比纯向量 vs Hybrid 的 hit@1。
  3. 实现 MultiQuery 3 变体检索,统计 recall 提升与延迟增加。
  4. 画 SIMILARITY_THRESHOLD 曲线:拒答率 vs 人工 judged 准确率。
  5. 设计 metadata filter(product + lang),验证 filter 错误时「空结果」如何提示用户。

常见问题

Q:HNSW 是什么?

近似最近邻图索引,牺牲少量 recall 换大幅提速。向量库默认多为此类;参数 efConstruction、M 影响构建时间与查询质量。

Q:MultiQuery 会不会引入噪声?

会。合并后应 dedupe、可 rerank(4.6),并限制变体数量。对精确 FAQ 有时反而 hurt precision。

Q:云向量库贵怎么办?

热冷分层、减小 embedding 维度(在质量允许下)、批量离线检索、缓存热门 query 结果;中小规模自托管 Qdrant 常更省。

本节小结

向量库按规模与合规选型;Hybrid 补专有词;MultiQuery 补 recall;压缩与阈值平衡窗口与拒答。优化前先 baseline 指标,避免同时改多变量。