LLM 面试备考
首页/RAG

RAG 全流程与失败模式 RAG Pipeline & Failure Modes

所属:01-fundamentals / 03-rag
面试权重:★★★
来源:通用领域知识(B站「RAG 面试」合集高频);未做一手考证

一句话#

RAG 把「先检索、再生成」拆成离线索引与在线查询两条链路;它的工程难点不在于把链路搭起来,而在于出了问题知道该怪哪一环 —— 一份可执行的失败分类法 + 调试决策树,比背架构图值钱得多。

为什么重要(面试角度)#

RAG 是 LLM 应用层最普遍的落地形态,几乎每场面试都会问。面试官的杀手锏是同一个:

「你的 RAG 答错了一个问题,你怎么查?」

这题的区分度极高。答「我会调整 prompt」或「我会加大 top-k」的人立刻出局;能沿着链路逐段定位、说清每一步的观测量和反事实实验的人,说明真的在生产里调过。面试官想听的是:

  • 你能不能把「答错」拆成检索没召回 / 召回了但排序差 / 排序对了但模型没用 / 模型用了但引错源这几种互斥情况
  • 你有没有 oracle 实验的意识(喂入正确答案的 chunk,看模型能不能答对)
  • 你知不知道每一步的评测指标是什么,以及它们各自能证伪什么

这道题也是 RAG 各细分考点(chunking / hybrid / rerank / query rewriting)的总纲:所有细节都是为修复某一类失败而存在。

核心内容#

两条链路#

──────── 离线:索引(Indexing)────────
原始文档 → 解析(parse) → 清洗 → 分块(chunking) → 向量化(embedding) → 建索引(ANN)
                                              ↘ 同时建 BM25 稀疏索引(若用混合检索)
                                              ↘ 抽实体关系构图(若用 GraphRAG)

──────── 在线:查询(Serving)────────
用户问题
  → 查询改写 / 多轮指代消解(query rewriting)
  → 检索(retrieval):稠密 + 稀疏,各取 top-k
  → 融合(fusion, 如 RRF)→ 重排(rerank, cross-encoder)→ 取 top-n
  → 组装上下文(augment):拼进 prompt、排序、去重、压缩
  → 生成(generate):LLM 带引用作答
  → 后处理:引用校验、拒答判定

「retrieve → augment → generate」是在线三段;但绝大多数线上事故的根因其实埋在离线那一段(chunk 切坏了、embedding 模型不适配语料)。这个「故障常出现在离线、症状出现在在线」的错位,正是这题的设计意图。

失败分类法(Failure Taxonomy)#

把「答错」按互斥且可观测的顺序拆开。每一条都有对应的观测手段:

# 失败模式 症状 观测手段 典型根因
1 知识缺失(corpus gap) 语料里压根没有答案 人工核查 / 语料标注 解析丢内容(PDF 表格、扫描件)、文档没入库
2 检索未召回(retrieval miss) 正确答案的 chunk 不在 top-k 里 Recall@k(人工标注 gold chunk) chunking 粒度、embedding 域不匹配、纯稠密丢失关键词、查询用词与文档用词不一致
3 排序不佳(ranking) 召回进了 top-k,但被噪声挤出 top-n 检索前后 top-n 的 gold 排名 缺 reranker、融合权重不合理
4 chunk 边界切断答案 分两半的答案各自都不完整,各自都召不回 看命中 chunk 的原文上下文 固定长度切分切断了表格行 / 条件句 / 步骤列表
5 上下文被忽略(context ignored) 正确 chunk 就在 prompt 里,模型仍按参数记忆答 把 gold chunk 单独喂入对比;看答案是否与 chunk 矛盾 lost-in-the-middle、噪声过多、冲突 chunk、指令不明确
6 引用错误(hallucinated citation) 答案对但标注的来源编号/文件错;或来源对但内容是编的 逐句比对引用与原文(citation faithfulness) 模型看到多段来源后乱编号、prompt 未约束引用格式
7 过度拒答 / 冗余 有答案却拒答,或堆砌所有 chunk 拒答率、答案长度分布 拒答指令过强、阈值过严、无去重/压缩

排序很重要:1→7 的观测成本递增(1 最贵),所以调试时先证伪便宜的。而且分类必须是互斥的,否则「既有检索问题又有生成问题」的结论无法指导动作。

调试决策树(核心)#

Q1. 语料里到底有没有答案?(人工 / 标注 gold)
    └─ 没有 → 不是 RAG 的锅,是数据覆盖问题。回到数据源与解析。
    └─ 有 → 继续

Q2. 正确答案的 chunk,在检索 top-k 里吗?(人工标注后算 Recall@k)
    └─ 不在 → 检索问题(模式 2 / 4)
         ├─ 抽查命中 chunk 的切法:是不是被切断了?(模式 4)
         ├─ 换个 embedding 模型/加 BM25,能召回吗?(模式 2)
         ├─ 同义词查询能召回吗?不能 → embedding 未适配领域 → 微调 embedding 或加 hybrid
         └─ 换 better query(把口语改成关键词)能召回吗?能 → query rewriting 缺失
    └─ 在 → 继续

Q3. 在 top-k 里,但 rerank 后掉出 top-n 了吗?
    └─ 掉出了 → 排序问题(模式 3):加 cross-encoder reranker / 调融合权重
    └─ 还在 → 继续

Q4. 把 gold chunk 单独喂给 LLM(oracle context,去掉所有其他 chunk),答对吗?
    └─ 答错 → 生成问题(模式 5):换 prompt 模板、强化"只依据上下文"指令、换更强的模型
    └─ 答对 → 是**上下文组织**问题:
         ├─ 是否 top-n 太大多噪声/有冲突 chunk?→ 减少 top-n、去重、冲突检测
         ├─ gold 是否落在 prompt 中间(lost-in-the-middle)?→ 重排让关键 chunk 靠前/靠后
         └─ 是否格式/指令问题?→ 明确要求逐句引用 + 无据则拒答

Q5. 答案正确但引用编号错了?
    └─ 引用层问题(模式 6):让模型逐段抄出原文片段,或后处理做句级归因

oracle context 这一步是整个决策树的枢纽:它把「检索质量」和「生成质量」这两个耦合的系统切成两半,一次实验就能定位问题在哪一侧 —— 这也是面试官最想听到的答案(用反事实实验代替猜)。

关键指标(用于把「感觉不对」变成「数值不对」)#

RAG 评测常用的一套指标(RAGAS 等框架的命名,实现细节随框架版本变化,面试里点到即止):

指标 回答的问题 归属
Context Recall 应该被召回的 chunk,召回了没有 检索
Context Precision 召回的 chunk 里多少是相关的、排得靠前吗 检索 / 排序
Faithfulness 答案的每一句都能在给定上下文里找到依据吗 生成
Answer Relevancy 答案切不切题 生成

工程上还必须单独维护检索层指标(Recall@k / MRR / NDCG)和端到端指标分开看,否则无法归因。前三个层级(检索、排序、生成)各自的可观测点不同,别用一个大模型评分掩盖分层。

缓解手段对照表#

失败模式 首选手段
检索未召回 hybrid 检索、query rewriting、embedding 微调、调整 chunk size
排序不佳 cross-encoder reranker
chunk 切断答案 递归/结构感知分块、父子分块、overlap
上下文被忽略 减少 top-n、重排、清晰的引用指令、更强的模型
引用错误 逐句引用约束、后处理归因、引用校验

常见面试问法#

Q:搭一个 RAG 系统,最主要的几个模块是什么? A:离线:解析、分块、embedding、建索引(稠密 ANN + 可选稀疏)。在线:query rewriting → 检索 → 融合/重排 → 组装上下文 → 生成 → 引用校验。关键认知是故障根因常在离线、症状暴露在在线。

Q:RAG 回答不对,你怎么系统性排查? A:走决策树。①先确认语料有没有答案;②用 gold chunk 算 Recall@k 判断是不是检索问题(再看是不是 chunk 边界切断);③在 top-k 但掉出 top-n 就是排序问题,上 reranker;④用 oracle context 单独喂 LLM —— 答错是生成问题,答对就是上下文组织问题(噪声/位置/指令)。核心是用反事实实验隔离检索与生成。

Q:RAG 和微调,什么时候用哪个? A:RAG 解决知识时效性与私有性(数据常变、需要引用、要能改),微调解决行为与格式(语气、领域术语的用法、结构化输出、指令遵循)。二者不互斥:RAG 供知识、SFT/偏好对齐塑行为,是常见组合。

Q:为什么不能直接把文档全文塞进长上下文模型? A:三点:成本(每轮都付全量 token)、延迟、注意力稀释(长上下文里中段内容容易被忽略,即 lost-in-the-middle)。RAG 本质是用一次检索换掉全量注入,是精度与成本之间的取舍。长上下文不会让 RAG 消失,但会抬高 chunk size 的经济性上界 —— 两件事在相互影响。

Q:RAG 的幻觉和纯 LLM 的幻觉有什么不同? A:纯 LLM 幻觉来自参数记忆不足;RAG 的幻觉更隐蔽,是在给了正确证据的情况下仍编造或误引(模式 5/6)。后者反而更难治,因为「有证据」会让人误以为不会出错,所以要看 Faithfulness 而不是只看答案对不对。

易错点#

  • ❌ 把 RAG 当成「加个向量库就完事」—— 不区分离线/在线、不谈失败分类,深度不够。
  • ❌ 排查时第一反应是「加大 top-k」—— 这会同时引入噪声,且没定位到根因。
  • ❌ 只评测端到端答案,不测检索层指标,导致无法归因。
  • ❌ 忽略 chunk 边界切断答案这一类失败(它同时表现为「检索不到」和「检索到但不完整」)。
  • ❌ 把「答案对但引用错」当成小问题 —— 在需要审计的场景里这是致命缺陷。
  • ❌ 断言某个指标/框架的数值是行业标准,而它其实是框架实现细节(应说「随框架版本变化」)。

自测#

1. 面试官说「你的 RAG 答错了一个问题」,请给出你的前三个动作,并说明每一步能排除什么。

答案

①人工确认语料里是否有答案 —— 排除「知识缺失」,否则后面都是白费;②用 gold chunk 算 Recall@k / 人工看命中的 chunk 切法 —— 判断是检索未召回还是 chunk 边界切断;③若检索命中,用 oracle context(只把 gold chunk 喂给 LLM)复现 —— 答错说明是生成侧问题(上下文被忽略/指令不清),答对说明是上下文组织问题(噪声、位置、冲突)。核心是用反事实实验把检索与生成解耦。

2. 「检索召回了正确的 chunk,但模型还是答错」——列出至少三种具体原因和对策。

答案

①噪声过多 / top-n 太大,模型被无关 chunk 带偏 → 减少 top-n、加 reranker、去重;②lost-in-the-middle,gold chunk 落在长 prompt 中段被忽略 → 重排让关键内容靠前靠后、压缩上下文;③chunk 之间信息冲突(不同版本的文档)→ 做时间/版本优先级或冲突检测;④prompt 没有强制「只依据上下文」,模型退回参数记忆 → 强化指令与拒答规则;⑤模型能力不足或格式约束冲突 → 换更强模型 / 简化输出格式。

3. 为什么说 RAG 的故障根因常在离线索引阶段?举例说明。

答案

因为离线产出的 chunk 与向量是检索的物理边界:切坏了就永远召不回,embedding 不适配领域就语义对不上。例如一份 PDF 表格被按字符数切开,每半张表都不含完整行 —— 在线无论怎么调 top-k、怎么加 reranker 都救不回来,只能改分块。症状出现在在线(答错),根因在离线(chunk 质量),这就是「调试决策树必须能回溯到离线」的原因。

4. RAG 里检索层指标与生成层指标为什么必须分开看?合成一个大分有什么问题?

答案

两者优化方向不同甚至相反:加大 top-k 提升 Context Recall 但降低 Context Precision、增加噪声反而拉低 Faithfulness。合成一个分数时,检索改善与生成退化的效果相互抵消,你既看不到是哪一环在动,也无法归因、无法决定该改哪个模块。分开看(Recall@k 单独测,Faithfulness 单独测)才能定位到具体模块。

5. 长上下文模型(能塞几十万 token)会让 RAG 过时吗?

答案

不会(但二者的边界在移动)。长上下文解决「装得下」,RAG 解决「找得准、付得起」:全量注入的成本与延迟随长度增长,且中段信息易被忽略(lost-in-the-middle)。不过更长的上下文确实抬高了 chunk 的可用粒度上界,让「大 chunk + 少检索」变得可行 —— 所以更准确的说法是两者互补,RAG 的粒度与 top-k 选择要跟着模型的上下文能力一起调,而不是二选一。