单纯的向量检索(Dense Retrieval)往往无法应对精确匹配的需求(如人名、产品型号)。本节我们将实现混合检索系统。
利用关键词匹配能力,弥补语义检索在专有名词上的劣势。
- 使用
Elasticsearch或Rank_BM25库。 - 对查询词进行分词处理(中文使用 Jieba 或 HanLP)。
利用 Embedding 捕捉语义相似度。
- 使用余弦相似度(Cosine Similarity)度量距离。
将两路检索的结果进行融合:
通常 k 取 60。此方法无需归一化分数,鲁棒性较强。
Retrieve 阶段追求召回率(Recall),Rerank 阶段追求准确率(Precision)。
我们引入 Cross-Encoder 类重排序模型对 Top-K(如 50 个)结果进行精细打分(具体模型与 K 值需通过评测与延迟预算确定)。
graph LR
Q[Query] --> R["Retrieval (Top-50)"]
R --> RK[Reranker]
RK --> F["Filter (Top-10)"]
F --> C[Context]
图 14-2:重排序流程图
注意:Reranker 计算量大,延迟高,只应对少量的初筛结果进行重排。
用户的提问往往是不完整的,直接检索效果不佳。
- 指代消解:将“它主要讲了什么?”改写为“员工手册主要讲了什么?”
- 问题扩展:生成相似问题,多路检索以提高覆盖面。
通过这些优化,我们可以构建一个高查准率、高查全率的检索系统。
第 14 章配套实验用标准库实现了一个可检查的混合检索器:BM25 负责关键词召回,本地向量相似度近似负责语义补充,并在检索前按部门权限过滤文档。
python3 examples/enterprise_know/enterprise_know.py \
--department engineering \
--query "生产数据库访问需要什么审批?"输出会同时包含 bm25_score、dense_score、最终 score、组装后的上下文和带来源标注的答案。生产系统可以把这两个检索分支替换为 Elasticsearch / OpenSearch、向量数据库和重排序模型,但仍应保留可解释分数、权限过滤和来源追踪。