Hybrid Search
Hybrid Search 是同时使用语义搜索和关键词搜索,然后合并排序的检索策略。它结合了语义理解和精确匹配的优势。
#type / concept
#status / evergreen
#tech / ai
[!info] related notes
- 所属 MOC: RAG Engineering MOC
- 相关: Semantic Search, Keyword Search
Hybrid Search
一句话定义
Hybrid Search 是同时使用语义搜索和关键词搜索,然后合并排序的检索策略。语义搜索理解”膝盖疼”和”膝关节不适”的关系,关键词搜索确保”ERROR_001”精确匹配。
核心原理
混合检索流程
用户查询
│
├─→ 语义搜索 → 结果 A (带相似度分数)
│
└─→ 关键词搜索 → 结果 B (带 BM25 分数)
│
▼
合并排序 (加权融合)
│
▼
最终结果
Python 实现
class HybridSearch:
def __init__(self, semantic_search, keyword_search, alpha=0.7):
self.semantic = semantic_search
self.keyword = keyword_search
self.alpha = alpha # 语义搜索权重
async def search(self, query: str, top_k: int = 10) -> list[Chunk]:
# 1. 两种搜索并行
semantic_results, keyword_results = await asyncio.gather(
self.semantic.search(query, top_k=top_k * 2),
self.keyword.search(query, top_k=top_k * 2),
)
# 2. 归一化分数
semantic_scores = self.normalize_scores(semantic_results)
keyword_scores = self.normalize_scores(keyword_results)
# 3. 加权融合
combined = {}
for chunk, score in semantic_scores:
combined[chunk.id] = {"chunk": chunk, "score": self.alpha * score}
for chunk, score in keyword_scores:
if chunk.id in combined:
combined[chunk.id]["score"] += (1 - self.alpha) * score
else:
combined[chunk.id] = {"chunk": chunk, "score": (1 - self.alpha) * score}
# 4. 排序
sorted_results = sorted(combined.values(), key=lambda x: x["score"], reverse=True)
return [item["chunk"] for item in sorted_results[:top_k]]
PostgreSQL 混合搜索
SELECT *,
(1 - (embedding <=> ?::vector)) * 0.7 + ts_rank(tsv, query) * 0.3 AS score
FROM documents, to_tsquery('chinese', ?) query
WHERE tsv @@ query
ORDER BY score DESC
LIMIT 10;
常见坑
- 只用一种搜索: 丢失了另一种的优势
- 权重不调整: alpha=0.7 不一定适合所有场景
- 分数不可比: 两种搜索的分数范围不同,需要归一化