首页/实战案例/混合检索:向量 + 关键词
实战案例 已验证可复现

混合检索:向量 + 关键词

纯向量检索有个致命弱点:搜不准专有名词。这节记录我们怎么用混合检索补上这个洞。

可复现前提: 同一份 150 条标注集,其中 42 条含精确关键词(错误码、产品名、API 名)。

问题长什么样

用户搜 ERR_TIMEOUT_5031,向量检索返回的是一堆"关于超时的一般性描述",偏偏没有那篇专门讲 5031 的文档。因为在向量空间里,ERR_TIMEOUT_5031ERR_TIMEOUT_5044 几乎一样近。

解法:BM25 + 向量,加权融合

hybrid.pypython
def hybrid_search(query, k=5, alpha=0.5):
    vec_hits = vector_search(query, k=30)     # 语义
    kw_hits = bm25_search(query, k=30)        # 关键词
    return rrf_fuse(vec_hits, kw_hits, k=k, alpha=alpha)

def rrf_fuse(a, b, k, alpha, c=60):
    """Reciprocal Rank Fusion:按排名倒数加权,不需要归一化两边分数。"""
    scores = {}
    for rank, hit in enumerate(a):
        scores[hit.id] = scores.get(hit.id, 0) + alpha / (c + rank)
    for rank, hit in enumerate(b):
        scores[hit.id] = scores.get(hit.id, 0) + (1 - alpha) / (c + rank)
    return sorted(scores.items(), key=lambda x: -x[1])[:k]

用 RRF 而不是直接加权分数,是因为两边的分数量纲完全不同,归一化很难调稳。RRF 只看排名,省心。

效果

方案 整体 recall@5 含关键词的 42 条
纯向量 0.86 0.62
纯 BM25 0.71 0.93
混合(α=0.5) 0.95 0.91

整体提升 9 个点,关键词场景提升 29 个点。

α 怎么调

我们扫了 0.1 到 0.9,发现 0.4~0.6 之间基本是平的,不用精调。如果你的场景专有名词特别多,往 0.3 调(更偏关键词)。

4.7/ 5
3 位同事评分
这篇实践你能照着复现吗?给它打个分:
每人一次,可随时修改

评论与复现反馈 1

登录 后可以评论、评分,并把复现结果反馈给作者。
评审员 已复现2 天前

RRF 那段代码直接抄走了,α 用 0.45。我们的错误码类查询提升更明显,42 条那种场景我们有 60 多条。

相关实践

全部 →
已验证实战案例

检索质量的离线评测

把「感觉变好了」变成 recall@k 和 MRR:标注集怎么建、指标怎么选、回归怎么跑。

·
5.0(3)1 讨论2 分钟