純 Vector Search 在大量文件下命中率往往只有 60–70%。混合搜尋(Hybrid)+ Reranker 是把命中率拉到 90% 的關鍵組合拳。
Vector Search 為什麼不夠?
Vector Search 找的是「語義相近」,但有些情境語義抓不到:
- 專有名詞(型號、產品 ID)
- 數字(年份、版本)
- 縮寫(HR、IT)
這些情境,傳統的 BM25 關鍵字搜尋反而強。
Hybrid Search:BM25 + Vector
同時跑兩種搜尋,然後合併排序:
# 簡化邏輯
bm25_results = bm25_search(query, top_k=20)
vector_results = vector_search(query, top_k=20)
# RRF (Reciprocal Rank Fusion) 合併
def rrf_score(rank, k=60):
return 1 / (k + rank)
combined = {}
for i, doc in enumerate(bm25_results):
combined[doc.id] = combined.get(doc.id, 0) + rrf_score(i+1)
for i, doc in enumerate(vector_results):
combined[doc.id] = combined.get(doc.id, 0) + rrf_score(i+1)
ranked = sorted(combined.items(), key=lambda x: -x[1])[:10]
實測:Hybrid 提升命中率多少?
測試:1,000 篇技術文件 + 200 個問題
- 只用 Vector:Top-3 命中率 62%
- 只用 BM25:Top-3 命中率 71%
- Hybrid(RRF):Top-3 命中率 84%
- Hybrid + Reranker:Top-3 命中率 92%
Reranker 是什麼?
Reranker 是專門訓練來「給 (query, doc) 對打相關度分數」的小模型。比 Embedding 慢但準很多。
流程:
- 用 Hybrid Search 取 Top-20
- Reranker 對這 20 筆重新打分
- 取 Top-3–5 給 LLM
常用 Reranker
| 模型 | 類型 | 價格 |
|---|---|---|
| Cohere Rerank 3 | API | $2/1K queries |
| BGE Reranker v2 | 開源、自架 | 免費 |
| jina-reranker-v2 | API / 自架 | $0.05/M tokens |
| Voyage rerank-2 | API | $0.05/M tokens |
實作範例
from cohere import Client
co = Client('YOUR_KEY')
# 取得 Top-20 後
candidates = ['切片1...', '切片2...', ...]
reranked = co.rerank(
model='rerank-multilingual-v3.0',
query=user_question,
documents=candidates,
top_n=5
)
# reranked.results 已按相關度排序
性能考量
- Reranker 慢:每個 (query, doc) 對需 50–200ms
- 建議只 rerank Top-20,不要 rerank 整個資料庫
- 有些 Reranker 支援批次(一次 100 個更快)
什麼時候不用 Reranker?
- 資料量 < 1,000 筆(用 Long Context 算了)
- 延遲要求極嚴(< 200ms 全程)
- Vector Search 命中率已經 > 85%
進階:Metadata 過濾
在 Hybrid Search 之前先用 metadata 過濾:
# Qdrant 範例
results = client.search(
collection_name='docs',
query_vector=embed(query),
query_filter=Filter(must=[
FieldCondition(key='department', match=MatchValue(value='HR')),
FieldCondition(key='year', range=Range(gte=2024))
]),
limit=20
)
這個技巧能再提升命中率 5–15%,特別是企業多部門情境。