# FDE W3D2 评测题 · 混合检索与 Rerank（BM25 + 向量 + RRF + BGE Reranker）

> 配套手册：《FDE-W3D2-混合检索与Rerank-学习手册.html》
> 定位：W3 Day2 · A 级（必须掌握，面试核心）
> 场景背景：医疗保险 / 特药理赔 / 保险知识库（候选人 36 岁，Java + 大数据 + 医疗，有 ETL / 数据治理经验）

## 评测说明

- 共 **13 题**，按难度分 4 级：**L1 基础（3 题）/ L2 进阶（4 题）/ L3 深度（3 题）/ L4 场景（3 题）**。
- 每题含：**考察点**、**评分维度**、**参考答案（`<details>` 折叠，点击展开）**。
- 评分采用 5 分制（0=不会 / 1=方向错 / 2=关键点缺 / 3=基本正确 / 4=完整 / 5=完整且有工程洞察）。
- 达标线见文末「评分汇总表 + 达标线」。

---

## L1 基础（概念与定义）

### Q1（L1 基础）为什么企业 RAG 几乎都用混合检索，而不是纯向量检索？

**考察点**：理解单路向量检索的短板与混合检索的动机。
**评分维度**：
- 能否指出向量在精确匹配、稀有实体、标识符上弱；
- 能否指出 BM25 在同义/口语化上弱，二者互补；
- 是否点出"召回宽 + 精排窄"的整体思路。

<details>
<summary>参考答案</summary>

纯向量检索基于语义相似，有三个天生短板：① 精确匹配弱（保单号、药名查不准）；② 稀有词/专有名词语义漂移；③ 高频词主导时语义被稀释。BM25 基于词频/IDF 擅长字面精确匹配，恰好补足。企业知识库（尤其医疗理赔）既要语义召回又要精确命中，所以采用 BM25+向量并行召回、RRF 融合、Reranker 精排的混合架构。核心思路是"召回阶段宁错勿漏（高召回），精排阶段压噪声（高精确）"。

</details>

### Q2（L1 基础）一句话解释 BM25 和向量检索分别擅长什么。

**考察点**：区分关键词召回与语义召回的边界。
**评分维度**：
- BM25：字面/关键词精确匹配，擅长确定性字符串；
- 向量：语义相似召回，擅长同义/口语化表述；
- 是否用医疗示例说明（如 ICD/药名 vs 口语描述）。

<details>
<summary>参考答案</summary>

BM25 擅长"字面精确命中"——用户问 ICD 编码 C34 或保单号，它能精准命中含该字符串的 chunk；向量检索擅长"语义召回"——用户口语问"肺癌靶向药报销"，即便 chunk 写的是"NSCLC 用药补偿"也能召回。医疗场景里 BM25 管标识符和专名，向量管描述性语义，二者混合互补。

</details>

### Q3（L1 基础）什么是 RRF？它解决什么问题？

**考察点**：理解倒数排名融合及其动机（量纲问题）。
**评分维度**：
- 能否写出 RRF = Σ 1/(k + rank) 的核心形式；
- 能否说明"BM25 与向量分数量纲不同，不能直接相加"；
- 是否提到 k（通常 60）的作用。

<details>
<summary>参考答案</summary>

RRF（Reciprocal Rank Fusion）用"排名"而非"原始分数"融合多路召回结果：每个文档得分 = Σ 各路 1/(k + rank)，k 通常取 60。它解决的核心问题是 BM25 分数（可能 0~20）与向量余弦分数（-1~1）量纲不同、无法直接相加。RRF 只看排名规避了归一化，且比手动调 α 权重更鲁棒——两路都靠前的 chunk 总分最高。它是混合检索最常用的"胶水"融合算法。

</details>

---

## L2 进阶（设计与机制）

### Q4（L2 进阶）画出混合检索的完整链路，并说明每一层的职责边界。

**考察点**：能把"召回→过滤→融合→精排"串成工程链路。
**评分维度**：
- 是否包含：实体抽取 → 并行 BM25+向量 → Metadata 过滤 → RRF → Reranker → LLM；
- 每层目标是否讲清（召回高召回 / 过滤范围权限 / 融合公平 / 精排高精确）；
- 是否提到"召回是地基，漏召精排救不回"。

<details>
<summary>参考答案</summary>

链路：用户 Query → 实体抽取（ICD/保单号/药名）→ 并行 BM25(keyword+text) 召回 Top-50 与 向量 kNN 召回 Top-50 → Metadata Filter 预过滤（active/版本/权限）→ RRF 融合成 Top-50 候选 → BGE Reranker 逐对精排取 Top-8 → 送 LLM（附 chunk_id 引用）。职责边界：BM25+向量负责"高召回（宁错勿漏）"，Metadata Filter 负责范围/权限正确，RRF 负责两路公平融合，Reranker 负责"高精确（压噪声）"。关键认知：召回是地基，若前层就漏了正确答案，精排再强也救不回。

</details>

### Q5（L2 进阶）BGE Reranker 是 cross-encoder，它和向量检索（bi-encoder）有什么本质区别？为什么必须接在召回之后？

**考察点**：理解精排模型原理与性能权衡。
**评分维度**：
- 能否区分 cross-encoder（query+doc 拼接打分）vs bi-encoder（各自编码再算相似）；
- 是否说明 cross-encoder 更准但因逐对推理而慢；
- 是否点出"Reranker 只排序不检索，必须作用于召回 Top-N"。

<details>
<summary>参考答案</summary>

向量检索是 bi-encoder：query 和 doc 各自编码成向量，再算余弦相似，快但 query 与 doc 没有双向交互，精度有限。BGE Reranker 是 cross-encoder：把 (query, doc) 拼接输入同一 Transformer，能看到两者细粒度交互，输出 0~1 相关性分，更准。但 cross-encoder 要对每个候选逐对推理，复杂度 O(N) 且慢，所以不能用于全库检索，只能作用在召回的 Top-50 候选上做精排。本质：召回要快且宽，精排要准且窄——Reranker 是"精确率放大器"。

</details>

### Q6（L2 进阶）Metadata Filter 的预过滤和后过滤有什么区别？权限场景该用哪个？

**考察点**：理解过滤时机与权限强约束的取舍。
**评分维度**：
- 能否区分"先筛再检索"vs"先召回再筛"；
- 权限/范围强约束用预过滤；
- 是否提到后过滤可能召回不足 K 的问题。

<details>
<summary>参考答案</summary>

预过滤（pre-filter）：先按 metadata 筛候选集，再在子集里算相似度/BM25，结果是"符合条件内的 Top-K"。后过滤（post-filter）：先召回再过滤，可能把结果过滤到不足 K 个，导致答案缺失。权限/范围这类强约束（如用户只能看自己部门/保单）必须用预过滤，既保证不越权又保证候选充足；软偏好（如优先新版本）可用后过滤。医疗权限过滤必须预过滤，否则有合规风险。

</details>

### Q7（L2 进阶）Elasticsearch 怎么在一个引擎里支持混合检索？

**考察点**：理解 ES dense_vector + bool/rrf 的工程落地。
**评分维度**：
- 能否说明一个索引同时存 keyword/text/dense_vector；
- 是否提到 bool+knn 或 ES 8.9+ 的 rank.rrf；
- 是否提到 HNSW 近似 kNN 及参数（ef/m）。

<details>
<summary>参考答案</summary>

ES 8.x 原生支持 dense_vector 字段 + HNSW 近似 kNN。一个索引可同时定义：keyword（保单号/ICD 精确）、text（ik 分词做 BM25）、dense_vector（语义）、以及 bool 过滤字段（status/version）。混合检索两种写法：① bool 查询里 must/should 放 BM25，knn 子句放向量，ES 内部线性融合（可设 boost）；② ES 8.9+ 用 `rank` 块的 `rrf` 显式融合多路（推荐，可控）。HNSW 的 ef_construction/m 影响召回率与内存，要按数据量调。一个引擎管全部，运维简单。

</details>

---

## L3 深度（原理与权衡）

### Q8（L3 深度）为什么保单号、ICD 编码、药品名编码必须用 keyword 字段而不是向量字段？

**考察点**：深刻理解"标识符无语义近义"这一关键判据。
**评分维度**：
- 能否说明标识符无"近义"概念，邻居不该是相似串；
- 能否说明向量会把 PICC-...098 与 PICC-...099 当相似召回，但业务上是两个不同保单；
- 是否给出正确做法（metadata 冗余 keyword + 实体抽取 term 过滤）。

<details>
<summary>参考答案</summary>

保单号、ICD 码、药品编码是"确定性标识符"，语义上无近义概念——它们的邻居不该是别的相似字符串。向量检索会把"PICC-2025-0098"与"PICC-2025-0099"当成相似（共享前缀 token），但业务上这是两个完全不同的保单，召回隔壁保单内容是严重合规事故；ICD 的 C34 与 C34.1 是不同细分，向量相似度会模糊这种区分。正确做法：在 chunk metadata 里冗余存 keyword 类型字段，查询时先抽实体→用 term 精确过滤，语义部分才走 BM25+向量。这是"精确 + 语义"双轨。

</details>

### Q9（L3 深度）RRF 的 k 参数如何影响结果？如果某一路召回质量很差会怎样？

**考察点**：理解融合算法的鲁棒性与参数敏感性。
**评分维度**：
- 能否说明 k 控制排名靠后项的衰减（k 越大越看重头部）；
- 能否说明 RRF 对"某路分数极自信"的拉平效应；
- 是否点出某路全错会拖累但不淹没另一路（鲁棒性）。

<details>
<summary>参考答案</summary>

RRF 中 k（通常 60）控制排名靠后项的衰减速度：k 越大，1/(k+rank) 随排名下降越快，越看重头部排名；k 越小，后段排名权重相对更高。RRF 只看排名不看原始分数，所以某路"极度自信的高分"和"微弱高分"被拉平，避免了单路分数主导。若某一路召回质量很差（如全错），它在该路上的排名普遍靠后，对总分的贡献小，会拖累但不至于淹没另一路——这正是 RRF 比手动 α 加权更鲁棒的原因。但也要注意：若两路都差，融合也无济于事。

</details>

### Q10（L3 深度）如何评测混合检索的效果？RAGAS 在这里扮演什么角色？

**考察点**：理解检索层指标与端到端评测的分工。
**评分维度**：
- 能否列出 Recall@K（漏召致命）、Precision@K、NDCG@K；
- 能否说明 RAGAS 的 context_precision/recall + faithfulness + answer_relevancy；
- 是否提到"每个旋钮在固定评测集版本上量化对比"。

<details>
<summary>参考答案</summary>

检索层用：Recall@K（衡量漏召，致命）、Precision@K（精排效果）、NDCG@K（排名质量，检验 Reranker 是否把对的顶上去）。用 W3D1 Golden Case 的 expected_chunks 算 Recall@K。端到端用 RAGAS：context_precision/context_recall 评检索，faithfulness 评答案是否忠于上下文（防幻觉），answer_relevancy 评切题。关键：每个旋钮（BM25 boost、RRF 的 k、Reranker 候选数、阈值）都要在固定版本的评测集上量化对比，前后分数才可比较；RAGAS 的 faithfulness 依赖 LLM 评判有偏差，重要结论要人工抽查。

</details>

---

## L4 场景（医疗保险实战）

### Q11（L4 场景）用户问"我母亲肺腺癌 EGFR 突变，医生开奥希替尼，保单 PICC-2025-0098 能报多少？"请设计检索方案。

**考察点**：综合应用"精确标识符 + 语义"混合实战。
**评分维度**：
- 能否抽实体（药名/ICD/保单号）并归一（泰瑞沙→奥希替尼）；
- 标识符走 keyword term 精确过滤，描述走 BM25+向量；
- 是否叠加 metadata 过滤（版本/状态/权限）与 RRF+Rerank；
- 是否要求返回带 chunk_id 引用（合规溯源）。

<details>
<summary>参考答案</summary>

方案：① 实体抽取：药名=奥希替尼（归一"泰瑞沙"→"奥希替尼"），ICD≈C34，保单号=PICC-2025-0098。② BM25：用 `term: {policy_no: PICC-2025-0098}` + `icd_code: C34` 精确命中该保单适用条款；text 部分匹配"奥希替尼/靶向药报销"。③ 向量：语义召回"EGFR 突变 NSCLC 用药补偿"等描述性 chunk。④ Metadata Filter：`status=active, doc_version=v2025Q2` 并叠加 ACL（仅该用户可见）。⑤ RRF 融合 + BGE Reranker 精排取 Top-8 送 LLM，返回答案必须带 chunk_id 引用（医疗合规要溯源）。标识符走 keyword、语义走 BM25+向量，最后汇合——单一向量检索处理这种 query 必然顾此失彼。

</details>

### Q12（L4 场景）运营发现"用户搜保单号经常召回隔壁保单的内容"，请定位原因并给修复。

**考察点**：诊断"标识符误用向量检索"的典型故障。
**评分维度**：
- 能否定位根因：保单号被存为 text 或被向量检索，导致近义串味；
- 能否给出修复：改为 keyword 字段 + term 精确查询；
- 是否提到实体抽取与归一化（大小写/连字符）。

<details>
<summary>参考答案</summary>

根因：保单号被当成语义内容处理——要么存成了 text 字段（被分词破坏精确性），要么被纳入向量检索，使"PICC-2025-0098"与相邻保单号因共享前缀被向量当成相似召回，但业务上是不同保单。修复：① 在 chunk metadata 中冗余存独立的 keyword 类型字段 `policy_no`；② 查询时对保单号走 `term` 精确匹配而非向量/全文；③ 入库与查询保持大小写、连字符归一化一致；④ 实体抽取要准，抽错则过滤失效。本质是"标识符必须 keyword 精确，绝不进向量"。

</details>

### Q13（L4 场景）你要为特药理赔知识库选型 Reranker，给出考量与落地要点（含延迟/成本）。

**考察点**：工程落地 Reranker 的权衡能力。
**评分维度**：
- 能否选 cross-encoder（如 BAAI/bge-reranker-large 或 v2-m3 多语言）；
- 是否限制作用条数（Top-50 量级）控延迟；
- 是否提到批处理、更小模型降本、分数阈值按评测定；
- 是否强调"Reranker 只排序不检索"。

<details>
<summary>参考答案</summary>

选型与落地：① 选 cross-encoder Reranker，中文医疗建议 bge-reranker-v2-m3（多语言/领域适配优于纯 large）。② 必须限制作用条数——作用在召回 Top-50 量级，逐对推理慢，全库跑延迟爆炸；批处理提升吞吐。③ 成本敏感可用更小模型或蒸馏版；延迟敏感可异步/缓存常见 query 的重排结果。④ Reranker 分数和生产阈值要按评测集定，别拍脑袋。⑤ 铁律：Reranker 只排序已有候选，前面必须有 BM25+向量召回——不能当检索用。整条链路延迟要把 Reranker 的 100~300ms 算进 SLA。

</details>

---

## 评分汇总表

| 题号 | 等级 | 考察点 | 满分 |
|------|------|--------|------|
| Q1 | L1 基础 | 为什么混合检索 | 5 |
| Q2 | L1 基础 | BM25 vs 向量边界 | 5 |
| Q3 | L1 基础 | RRF 原理与量纲 | 5 |
| Q4 | L2 进阶 | 完整检索链路 | 5 |
| Q5 | L2 进阶 | cross-encoder vs bi-encoder | 5 |
| Q6 | L2 进阶 | 预过滤 vs 后过滤 | 5 |
| Q7 | L2 进阶 | ES 混合检索落地 | 5 |
| Q8 | L3 深度 | keyword 而非向量的判据 | 5 |
| Q9 | L3 深度 | RRF 的 k 与鲁棒性 | 5 |
| Q10 | L3 深度 | 检索评测与 RAGAS | 5 |
| Q11 | L4 场景 | 理赔 query 检索方案 | 5 |
| Q12 | L4 场景 | 保单号误召回故障 | 5 |
| Q13 | L4 场景 | Reranker 选型与落地 | 5 |
| **合计** | — | — | **65** |

### 达标线

- **合格线（L1+L2 全对 + L3 基本正确）**：总分 ≥ 45，且 L1/L2 不得有 0~1 分题。能讲清 BM25+向量+RRF 怎么融合、为什么需要 Rerank（达标线①）。
- **优秀线（面试通过）**：总分 ≥ 55，L3/L4 能完整回答并展现工程洞察（如标识符误用向量的根因、Reranker 延迟权衡）。能讲清药品名/ICD/保单号精确匹配为什么用 keyword 字段（达标线②）。
- **一票否决**：认为"纯向量检索足够、不需要 BM25/keyword"或"保单号也可以用向量检索"——基础认知错误，直接判不合格。

> 自评方法：先口头作答，再展开 `<details>` 对照；L3/L4 答不全的回到手册对应章节（s1/s4/s6/s7/s12/s13）重读「🎤面试话术」「⚠易错点」。
