RAG 全链路 · 进阶¶
混合检索互补、RRF 公式与原理、cross-encoder vs bi-encoder、Query Rewriting、分块与 Overlap 取舍、ES kNN vs 专用向量库选型。每题含参考答案 + 面试官追问/红旗。
Q1: 为什么单一向量检索不够?混合检索的互补性体现在哪?¶
进阶 | RAG | 📖 相关讲解
考察点:能否讲清单一检索的召回天花板,以及稀疏/稠密互补的底层逻辑。
参考答案
单一向量检索有固有召回天花板,因为稠密向量的本质是"把语义压成向量",必然丢失一部分信息,主要盲区是精确符号匹配:
- 专有名词/编号/型号:如合同编号"SLA-2024-001"、人名、产品型号,这些在 Embedding 后语义被糊化,向量检索可能召不回或召回不准。
- 领域强信号词:某些 query 的关键就是某个精确词,向量相似度会把它和同义但错误的文档混在一起。
混合检索的互补性:BM25(稀疏)基于词项精确匹配,正好补上这个盲区——它能精准命中含"SLA-2024-001"的文档;而向量检索补上 BM25 的盲区——同义改写、口语化表达。
两者盲区几乎不重叠,所以"向量召回的漏网 + BM25 召回的漏网"取并集后,召回上限显著拉高。这正是许峰百万级文档"余弦 + BM25 → ReRank"的依据,也是报告 §5.4 把"无混合检索"列为已落后红旗的原因——只会单一向量检索的人,召回到不了生产合格线。
面试官追问 / 红旗
- 追问:除了 BM25 + 向量,还有别的混合方式吗?(bge-m3 的稠密+稀疏+多向量一体;ColBERT 多向量)
- 追问:两路结果如何融合、能否加权求和?(见 Q2 RRF,加权求和因尺度问题不可行)
- 红旗:说不出单一向量检索具体漏什么(精确符号)、只泛泛讲"更准"——没理解互补的本质。
Q2: RRF 的融合公式是什么?原理是什么?相比加权求和有什么优势?¶
进阶 | RAG | 📖 相关讲解
考察点:能否准确写出 RRF 公式 1/(k+rank)、讲清 k 的作用,以及为何不用加权求和。
参考答案
RRF(Reciprocal Rank Fusion,倒数排名融合)公式:score(d) = Σ_i 1 / (k + rank_i(d)),其中 i 遍历所有检索路数。
rank_i(d):文档 d 在第 i 路结果中的排名(第 1 名 rank=1,第 2 名 rank=2…)。k:平滑常数,通常取 60,作用是削弱头部排名的绝对优势,让"多路都靠前"的文档胜出,而非单路第一名垄断。- 文档在多路中排名越靠前、出现的路数越多,RRF 总分越高(多路共识优先)。
核心原理:不看分数,只看排名,从而天然消除两路分数的尺度差异。
相比加权求和的优势:
| 维度 | 加权求和 | RRF |
|---|---|---|
| 尺度 | BM25 分数和余弦分数尺度完全不同,必须先归一化,调参敏感 | 只看排名,天然消除尺度差异 |
| 权重 | α/β 需对每个数据集反复调,不同 query 最优权重不同 | k 近乎固定常量(60),几乎不用调 |
| 鲁棒性 | 某路分数分布异常会污染结果 | 排名受分数绝对值影响小,更稳 |
举例:文档 D 在 BM25 排第 2、向量路排第 1,k=60,则 RRF(D)=1/62+1/61≈0.0325;而只在 BM25 排第 1 的文档 E 是 1/61≈0.0164——D 因两路共识胜出。这就是混合检索的价值。
正因如此,RRF 是混合检索融合的事实标准(ES、Weaviate、Qdrant 内置都用 RRF)。
面试官追问 / 红旗
- 追问:k 为什么取 60?调它有意义吗?(社区默认值,对结果影响远小于 chunk_size/Embedding 选型,不值得花时间调)
- 追问:为什么不能直接把 BM25 分数和余弦分数加权求和?(尺度不同,且分布随 query 剧烈变化,权重调不准)
- 红旗:写错公式(如写成
1/rank不带 k)、或说"k 要精细调"——说明没真正实现过 RRF。
Q3: cross-encoder Rerank 为什么比 bi-encoder 更准但更慢?精度与延迟如何权衡?¶
进阶 | RAG | 📖 相关讲解
考察点:是否真正理解双塔与交叉两种编码机制的本质差异,以及"先粗排后精排"的工程权衡。
参考答案
更准的原因:cross-encoder 把 query 和文档拼接成一个序列 [CLS] query [SEP] doc [SEP] 一起送入模型,编码时 token 级深度交互(attention),能判断"是否真的相关";而 bi-encoder 是 query 和文档分别独立编码成向量,编码阶段无交互,只能靠事后点积粗略衡量相似度。深度交互带来更高的相关性判别精度。
更慢的原因:bi-encoder 的文档向量可离线预计算存入向量库,查询时只需算 query 向量 + ANN,O(logN) 极快;cross-encoder 必须把每个候选和 query 拼接送模型一次,无法预计算,且每个候选都是一次完整的前向推理。
精度与延迟的权衡(标准解法):
| 阶段 | 模型 | 候选规模 | 速度 |
|---|---|---|---|
| 召回 | bi-encoder | 百万 → 几十个 | 极快 |
| 精排 | cross-encoder | 几十个 → Top-5 | 慢但可接受 |
即先用快的 bi-encoder 从全库召回 Top-N(如 20~50),再用慢的 cross-encoder 只对这小批量精排。把 cross-encoder 的高精度限定在小批量上,规避它的慢——这是精度与延迟的最优分工。
面试官追问 / 红旗
- 追问:能不能用 cross-encoder 直接对全库检索?(不能,慢且无法预计算,百万级不可行)
- 追问:Rerank 的 Top-N 候选数怎么定?(召回宁多勿漏取 20~50,Rerank 收敛到 5;N 太大延迟高,太小漏召回)
- 红旗:说"cross-encoder 就是参数更多所以准"——没讲到 query-doc 深度交互这个本质;或答"Rerank 就是再检索一遍"——混淆了精排与召回。
Q4: Query Rewriting 有哪些策略?术语标准化和子查询分解的区别是什么?¶
进阶 | RAG | 📖 相关讲解
考察点:是否理解 Query Rewriting 是"检索前的输入优化",以及不同策略的适用场景。
参考答案
Query Rewriting(查询改写)用 LLM 在检索之前把用户原始 query 改写成检索友好的形式,从源头提升召回。四大策略:
| 策略 | 做什么 | 适用 |
|---|---|---|
| 术语标准化 | 口语/简称换成文档规范术语 | "续费怎么搞" → "会员套餐续费流程" |
| 意图补全 | 补上检索必需的关键词 | "那个报错了" → "支付接口报错 500 如何排查" |
| 指代消解 | 多轮对话代词还原 | "它的价格" → "Pro 版会员的价格" |
| 子查询分解 | 复杂问题拆成多个子查询分别召回再合并 | "对比 A 和 B" → "A 的优缺点"+"B 的优缺点" |
术语标准化 vs 子查询分解的区别:
- 术语标准化是单 query 内的优化——一个 query 改写成一个更精确的 query,改写前后是"一对一"。解决的是"问得口语化、缺规范词"。
- 子查询分解是一个 query 拆成多个子 query——改写前后是"一对多",每个子 query 独立召回再合并。解决的是"问题太复杂,单次检索覆盖不全"。
改写提升召回的原理:标准化后 BM25 能精确命中规范术语,补全后向量能召回更精准语义,分解后每个子问题都能检索到对应文档。
面试官追问 / 红旗
- 追问:Query Rewriting 加了一跳 LLM 调用,怎么控制延迟?(加缓存——相同 query 不重复改写;轻量模型做改写)
- 追问:指代消解在多轮对话里怎么实现?(带上历史消息做 query 改写,把"它"还原为具体实体)
- 红旗:把 Query Rewriting 说成"就是 prompt 优化"——没分清它是在检索前优化输入、而非生成时优化;或不知道子查询分解——只懂最浅的改写。
Q5: 分块大小和 Overlap 如何影响召回与噪声?¶
进阶 | RAG | 📖 相关讲解
考察点:能否讲清 chunk_size 与 Overlap 的权衡机制,以及它们对召回和噪声的双向影响。
参考答案
分块大小和 Overlap 是联动调参,对"召回"和"噪声"是双向影响:
chunk_size(块大小):
| chunk_size | 召回 | 噪声 |
|---|---|---|
| 过大 | 单块信息全,命中的块能自洽 | 噪声多——块里夹大量无关内容,向量被稀释,精度下降;总块数少,检索粒度粗 |
| 过小 | 检索粒度细、命中精准 | 单块语义可能不完整,需更大 top_k + Rerank 拼回;块数多,存储检索开销上升 |
Overlap(重叠区):
| Overlap | 效果 |
|---|---|
| 太小/为 0 | 关键信息若切在两块边界处,任一单块都不完整,召回的块语义残缺 |
| 太大 | 存储与检索冗余上升,相似块过多反而稀释 Rerank 排序 |
调参方法:固定一批问答评测集,扫一遍 chunk_size ∈ {256,384,512,768} × overlap ∈ {0,64,128},看 Hit Rate@5 拐点。经验:中文 chunk 384~512 是甜点区,Overlap 取 chunk 的 10%~20%(如 512 token 配 64 Overlap)。
进阶:"小块检索 + 大块返回"——用小 chunk 精准命中,命中的块再向上下文扩展(取父段落/相邻块)拼成完整上下文,兼顾检索精度和上下文完整性。
面试官追问 / 红旗
- 追问:chunk_size 怎么定?拍脑袋还是有方法?(用评测集扫参,看 Hit Rate@5 拐点,不能拍脑袋)
- 追问:为什么太大也不好?(块里夹噪声、检索粒度粗,精度反而下降)
- 红旗:只说"分块大点信息全"或"小点精确"——没讲到双向权衡和"扫参"方法;或 Overlap 设成 0 说明没考虑边界信息丢失。
Q6: ES 的 kNN 向量检索和专用向量库(Qdrant/Milvus)如何选型?¶
进阶 | RAG | 📖 相关讲解
考察点:能否基于"是否已有基础设施、规模、是否要混合检索"给出合理选型依据,而不是无脑选最新工具。
参考答案
选型核心看三件事:是否已有基础设施、数据规模、是否需要混合检索。
| 选项 | 定位 | 选它的理由 |
|---|---|---|
| ES kNN 向量字段 | 搜索引擎扩展向量能力 | 已有 ES 基础设施;天然支持 BM25 + 向量混合检索(RRF 内置),一套库搞定稀疏+稠密 |
| Qdrant | 专用向量库(Rust) | 中大型 RAG 首选;高性能、过滤强、Payload 元数据好用、部署简单 |
| Milvus | 专用向量库(分布式) | 十亿级以上规模、需要分布式集群 |
| FAISS | 库(非服务) | 纯单机原型/嵌入式;不是独立数据库,无 CRUD/持久化/过滤 |
| pgvector | 关系库扩展 | 向量与业务数据强关联、需事务一致 |
选型口诀:
- 百万级 + 要元数据过滤 → Qdrant(彭超企业级 Agent 平台就用 Qdrant)。
- 十亿级 + 要分布式 → Milvus。
- 已有 ES、想省一套基础设施 + 要混合检索 → ES kNN(许峰百万级文档"余弦+BM25"若基础设施是 ES,同库即可完成)。
- 纯单机原型 → FAISS。
- 向量和业务数据强一致 → pgvector。
关键判断:如果团队已有 ES 且规模在百万级,直接用 ES kNN 做混合检索是性价比最高的选择,不必为了"向量库"单独引入 Qdrant。专用向量库的优势在更大规模和更丰富的过滤/检索能力。
面试官追问 / 红旗
- 追问:FAISS 能不能当生产向量库用?(不能,它是库不是服务,无 CRUD/持久化/过滤/分布式,只适合原型或嵌入式)
- 追问:HNSW 索引内存怎么估算?(100 万条 1024 维 float ≈ 4GB 裸数据,加图索引翻倍)
- 红旗:无脑说"肯定用 Milvus/最新向量库",不考虑团队已有基础设施和混合检索需求——脱离工程的工具崇拜。