> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/context_engineering_guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/context_engineering_guide/di-si-bu-fen-gong-cheng-shi-zhan-yu-wei-lai-yan-jin/14_practice/14.3_retrieval_implementation.md).

# 14.3 检索系统实现

单纯的向量检索（Dense Retrieval）往往无法应对精确匹配的需求（如人名、产品型号）。本节我们将实现混合检索系统。

## 14.3.1 混合检索

### 稀疏检索

利用关键词匹配能力，弥补语义检索在专有名词上的劣势。

* 使用 `Elasticsearch` 或 `Rank_BM25` 库。
* 对查询词进行分词处理（中文使用 Jieba 或 HanLP）。

### 稠密检索

利用 Embedding 捕捉语义相似度。

* 使用余弦相似度（Cosine Similarity）度量距离。

### 再加权融合

将两路检索的结果进行融合：

$Score = \frac{1}{k + rank\_{vec}} + \frac{1}{k + rank\_{bm25}}$

通常 k 取 60。此方法无需归一化分数，鲁棒性较强。

## 14.3.2 重排序

Retrieve 阶段追求召回率（Recall），Rerank 阶段追求准确率（Precision）。

我们引入 Cross-Encoder 类重排序模型对 Top-K（如 50 个）结果进行精细打分（具体模型与 K 值需通过评测与延迟预算确定）。

```mermaid
graph LR
    Q[Query] --> R["Retrieval (Top-50)"]
    R --> RK[Reranker]
    RK --> F["Filter (Top-10)"]
    F --> C[Context]
```

图 14-2：重排序流程图

**注意**：Reranker 计算量大，延迟高，只应对少量的初筛结果进行重排。

## 14.3.3 查询预处理

用户的提问往往是不完整的，直接检索效果不佳。

* **指代消解**：将“它主要讲了什么？”改写为“员工手册主要讲了什么？”
* **问题扩展**：生成相似问题，多路检索以提高覆盖面。

通过这些优化，我们可以构建一个高查准率、高查全率的检索系统。

## 14.3.4 本地混合检索实验

第 14 章配套实验用标准库实现了一个可检查的混合检索器：BM25 负责关键词召回，本地向量相似度近似负责语义补充，并在检索前按部门权限过滤文档。

```bash
python3 examples/enterprise_know/enterprise_know.py \
  --department engineering \
  --query "生产数据库访问需要什么审批？"
```

输出会同时包含 `bm25_score`、`dense_score`、最终 `score`、组装后的上下文和带来源标注的答案。生产系统可以把这两个检索分支替换为 Elasticsearch / OpenSearch、向量数据库和重排序模型，但仍应保留可解释分数、权限过滤和来源追踪。
