RAG 全链路 · 基础¶
RAG 定义、标准链路、Embedding、BM25 vs 向量、Rerank、分块策略的基础问答。每题含参考答案 + 面试官追问/红旗。
Q1: 什么是 RAG,它解决了 LLM 的什么问题?¶
基础 | RAG | 📖 相关讲解
考察点:是否理解 RAG 的本质动机(外部知识 + 时效 + 可溯源),而非把它当成"调个框架"。
参考答案
RAG(Retrieval-Augmented Generation,检索增强生成)= 先检索外部知识,再把检索到的内容作为上下文喂给 LLM 生成答案。它解决 LLM 的三大固有缺陷:
| LLM 缺陷 | RAG 如何解决 |
|---|---|
| 知识截止/时效差:模型参数知识停在训练时 | 检索最新文档,答案基于实时外部知识 |
| 易幻觉:凭参数续写、无依据 | 答案基于检索到的真实文档,可引用溯源 |
| 私有/领域知识缺失:通用模型不懂企业内部知识 | 检索企业知识库,注入私有数据 |
标准链路:文档解析 → 分块 → Embedding → 向量库 → 检索 → 拼 Prompt → LLM 生成。
关键区别:微调是把知识"写进"参数(重、难更新、不可溯源);RAG 是把知识"检索出来"放上下文(轻、实时更新、可引用)。企业知识频繁变动的场景,RAG 是首选。
面试官追问 / 红旗
- 追问:RAG 和微调各自适合什么场景?什么情况下要结合?
- 追问:RAG 真的不幻觉了吗?(否,幻觉治理一节)
- 红旗:只会说"RAG 就是检索+生成",讲不清它具体解决哪三个问题、和微调的本质区别——停留在概念复读。
Q2: 请描述 RAG 的标准链路步骤。¶
基础 | RAG | 📖 相关讲解
考察点:能否完整、有序地讲清从文档到答案的全链路,而不是漏环节。
参考答案
RAG 分离线入库和在线检索生成两条链路:
离线(数据准备):
- 文档解析:PDF/Word/Excel 等转结构化文本,表格行级语义化。
- 分块(Chunking):递归/语义切成 chunk,加 Overlap,带 metadata。
- Embedding:每块经 bi-encoder 编码成稠密向量。
- 入向量库:向量 + payload 存入 Qdrant/Milvus/ES,建 HNSW 索引。
在线(查询响应):
- (可选)Query Rewriting:LLM 改写 query,术语标准化/补全。
- 检索:query Embedding → 向量 ANN 检索(生产级加 BM25 混合检索 + RRF 融合)。
- (可选)Rerank:cross-encoder 对召回候选精排。
- 拼 Prompt:Top-K 文档塞进上下文 + 系统指令。
- LLM 生成:基于上下文生成带引用的答案。
生产级还会叠加:置信度阈值、引用回溯、护栏 Prompt 等幻觉治理。
面试官追问 / 红旗
- 追问:哪些环节是可选的、哪些是必须的?(解析/分块/Embedding/检索/生成是必须;混合检索/Rerank/Query 改写是优化)
- 追问:离线和在线链路为什么分开?
- 红旗:只讲在线检索生成,漏掉离线的解析分块——说明没真正做过入库工程。
Q3: 什么是 Embedding?常用的相似度度量有哪些?¶
基础 | RAG | 📖 相关讲解
考察点:是否理解 Embedding 是"把语义映射到向量空间",以及三种相似度度量的差异。
参考答案
Embedding 是用一个模型把文本映射成固定维度的稠密向量(如 768 维),使语义相近的文本在向量空间中距离也近。它是稠密向量检索的基础——检索本质就是"找向量空间里离 query 最近的文档向量"。中文常用:bge、m3e、GTE、E5。
三种常用相似度度量:
| 度量 | 计算 | 特点 | 用法 |
|---|---|---|---|
| 余弦相似度 | 两向量夹角余弦(归一化后点积) | 只看方向、对模长不敏感 | 文本 RAG 默认首选 |
| 点积(Dot) | 向量内积 | 归一化向量下等价余弦;否则受模长影响 | 部分模型(如 OpenAI)训练时用 |
| 欧氏距离(L2) | 几何距离,越小越相似 | 对绝对位置敏感 | 图像/聚类更多,文本少用 |
要点:① 文本 RAG 默认用余弦;② Embedding 模型选定后,全库向量维度必须统一,换模型要全量重 Embedding;③ 度量方式要和模型训练时的对齐(模型用点积训练就用点积检索)。
面试官追问 / 红旗
- 追问:为什么文本检索默认余弦而不是欧氏距离?(语义方向相似即可,不应被文档向量模长干扰)
- 追问:换 Embedding 模型会怎样?(全库维度可能变,必须全量重 Embedding,是昂贵返工)
- 红旗:把 Embedding 和 Rerank 混为一谈,或答不出"维度必须全局统一"——说明没踩过工程坑。
Q4: BM25 和向量检索各擅长什么?为什么要混合?¶
基础 | RAG | 📖 相关讲解
考察点:是否理解稀疏与稠密检索的互补性——这是"合格 RAG"的门槛认知。
参考答案
两者互补,盲区几乎不重叠:
| 维度 | BM25(稀疏) | 向量检索(稠密) |
|---|---|---|
| 原理 | 改进的 TF-IDF,基于词项精确匹配 | 把语义压成向量,按语义相似度 |
| 擅长 | 专有名词、编号、人名、型号等精确符号 | 同义词、改写、口语化表达的语义匹配 |
| 弱点 | 不懂同义词("熔断"≠"限流降级") | 精确符号易失真("SLA-2024-001"语义糊化) |
为什么要混合:单一检索有盲区天花板。用户问"怎么配置熔断",向量能召回写"限流降级"的文档(语义改写),BM25 能召回含精确配置编号的文档(关键词)。两路召回互补,能显著拉高召回上限。许峰百万级文档案例就是"余弦(向量)+ BM25 → ReRank"的混合范式。
面试官追问 / 红旗
- 追问:两路结果怎么融合?(RRF,见进阶题)
- 追问:BM25 在中文场景要注意什么?(必须装 IK/jieba 分词器,否则退化为单字匹配)
- 红旗:只说"向量检索最先进、用向量就够了"——这正是报告 §5.4 列的"已落后"特征,生产级必须混合检索。
Q5: 什么是 Rerank?它和检索阶段是什么关系?¶
基础 | RAG | 📖 相关讲解
考察点:是否理解 Rerank 是检索之后的"二次精排",以及它为何放在检索之后。
参考答案
Rerank(重排序) 是在检索召回的候选结果之上,用更精确的模型(cross-encoder)二次精排,把真正最相关的顶到前面。
和检索阶段的关系是串联的"先粗排后精排":
| 阶段 | 模型 | 机制 | 速度 | 作用 |
|---|---|---|---|---|
| 检索(召回) | bi-encoder(双塔) | query 和文档各自编码成向量再算相似度 | 极快(文档向量可离线预计算) | 从百万文档召回 Top-N 候选 |
| Rerank(精排) | cross-encoder | query 和文档拼接一起送模型,token 级深度交互 | 慢(每候选都要跑一次) | 对召回候选精排到 Top-5 |
为什么放在检索之后:cross-encoder 精度高但慢、无法预计算,不能对全库做。所以先用快的 bi-encoder 召回几十个候选,再用慢的 cross-encoder 精排——把高精度用在小批量上。Rerank 不替代检索,是检索结果的二次排序去噪。常用模型:bge-reranker、Cohere Rerank。
面试官追问 / 红旗
- 追问:cross-encoder 为什么不能对全库做?(慢、无法预计算)
- 追问:Rerank 模型和 Embedding 模型是同一个吗?(否,是两个不同模型,召回用 bi-encoder,精排用 cross-encoder)
- 红旗:以为 Rerank 就是换一个检索模型重查一遍——没理解"精排是排序而非重召回"。
Q6: 常见的文档分块策略有哪些?各自适用什么场景?¶
基础 | RAG | 📖 相关讲解
考察点:是否掌握分块策略的取舍,知道递归分块是工程默认首选。
参考答案
四种主流策略:
| 策略 | 做法 | 适用 | 缺点 |
|---|---|---|---|
| 固定长度 | 按字符/token 硬切(如 500 token) | 最简单、可控 | 易切断句子,语义割裂 |
| 语义分块 | 按句子/段落边界,或 Embedding 相似度找话题转折点切 | 语义完整 | 实现复杂、块大小不均 |
| 递归分块 | 按 [\n\n, \n, 。, 空格] 分隔符层级递归切 |
工程默认首选,平衡语义与长度 | 需调分隔符顺序 |
| 结构化分块 | 按 Markdown 标题/文档章节/知识点切 | 文档结构质量好时,边界最清晰 | 依赖文档结构 |
工程实践:递归分块(Recursive Character Splitter)是默认主力——先按段落 \n\n 切,超长再按换行/句号兜底,既尊重语义边界又保证块大小可控。经验参数:chunk 384~512 token、Overlap 取 chunk 的 10%~20%(如 512 配 64)。
还有个进阶做法"小块检索 + 大块返回":用小 chunk 做向量匹配精准定位,命中后向上下文扩展(取父段落/相邻块)拼成完整上下文喂 LLM。
面试官追问 / 红旗
- 追问:Overlap 的作用是什么、太大太小各有什么问题?(防边界信息丢失;太大冗余稀释排序,太小语义残缺)
- 追问:表格怎么分块?(行级语义化,转成"字段是X"的自然语言,别整表一块)
- 红旗:只说"按固定大小切",不知道递归分块和语义分块——停留在最原始的实现,对应报告"只会调框架默认"的红旗。