混合檢索:向量搜尋補不上的那一塊
產品型號、錯誤代碼、人名這類字串,向量搜尋常常查不到。關鍵字檢索仍然不可取代。
純向量檢索有個明顯弱點:對精確字串不敏感。使用者查「ERR_2043」時,向量模型看到的是一串沒什麼語意的字元,相似度未必比一段講錯誤處理的散文高。
兩種檢索的互補性
- 向量檢索:擅長同義、換句話說、跨語言;不擅長精確字串與罕見詞。
- 關鍵字檢索(BM25):擅長精確比對與稀有詞;不擅長同義改寫。
用 RRF 合併排名
最省事的合併方式是倒數排名融合(Reciprocal Rank Fusion),不需要調整兩邊分數的量綱,只看名次。
def rrf(rank_lists, k=60):
scores = {}
for lst in rank_lists:
for rank, doc_id in enumerate(lst, start=1):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank)
return sorted(scores, key=scores.get, reverse=True)
final = rrf([vector_hits, bm25_hits])[:10]k 控制高名次的權重,預設 60 是常見值,通常不需要動。這段程式碼十行不到,卻往往是命中率提升最有感的一次改動。
上線後記得分別記錄「只有向量找到」「只有關鍵字找到」的比例。如果後者接近零,就可以考慮省掉 BM25 那一路的成本。