这篇学完你能回答什么
- 「RAG 的召回率怎么评估?测试集从哪来?」
- 「faithfulness 和 answer relevancy 有什么区别?」
- 「用户说答非所问,你怎么归因是检索的锅还是生成的锅?」——整个 RAG 章最能拉开差距的一题。
从一个真实故障讲起
一个法律检索 RAG 上线,离线评测 faithfulness 高达 0.91,团队很满意。三周后客户投诉:大约六分之一的回答漏掉了关键法条。
团队回去看仪表盘——faithfulness 还是 0.91,纹丝不动。再一查 context recall:只有 0.62。
真相是:检索器在多跳问题上漏掉了第二条法条,而生成器基于残缺的上下文一本正经地把答案编圆了。因为它说的每句话都能在(残缺的)上下文里找到依据,忠实度指标反而很高。
这个故障讲透了 RAG 评测的第一原则:只测生成,测不出检索的病。 一个指标高不代表系统好,你需要在正确的位置放正确的指标。
多跳法律问题
答案要串起两条法条才完整
检索器只召回一条断点
第二条法条压根没进候选
生成器把答案编圆
每句话都能在残缺材料里找到依据
faithfulness 0.91
仪表盘纹丝不动,三周没人怀疑
客户投诉漏法条
约六分之一的回答漏掉关键法条
核心概念:把评测切成两段
RAG 评测必须分离检索质量和生成质量,分别打分。因为这两段的失败模式完全不同,修复手段也完全不同。
这也直接回答了面试最爱问的归因题(Q2-17):
用户投诉「答非所问」 ↓ 把正确文档手工塞进 prompt,再问一次 ├── 这次答对了 → 检索的锅:查分块、embedding、混合检索、rerank └── 还是答错 → 生成的锅:查 prompt、上下文顺序、模型选型、材料太长
这一刀是排障的第一动作,成本极低、信息量极大。面试时能立刻说出这个动作,基本就赢了这题。
没进候选,后面全白搭
漏召回不可逆;排序错了还有 rerank 能救
有标注时最可靠
先保 Recall 别漏,再优化 NDCG/MRR 别排错
材料齐了照样能答歪
有材料还胡编、答非所问、噪音太多
核心用 LLM-as-Judge 打分
四个指标各盯一种失败模式
原理拆解:指标体系
| 指标 | 经验线 | 开头那个团队 | 读法 |
|---|---|---|---|
| faithfulness | > 0.8 | 0.91 | 达标,所以三周没人怀疑它 |
| context precision | > 0.75 | — | 噪音多不多,得另外算 |
| context recall | > 0.8 | 0.62 | 失守的就是它,仪表盘上却没有 |
为什么仪表盘上偏偏缺 context recall:faithfulness 和 answer relevancy 是 reference-free 的,不用人工写标准答案就能大规模跑;context recall 得有标准答案或标注好的 gold chunk 才算得准。
优先级别搞反:先保 Recall(别漏),再优化 NDCG/MRR(别排错)。漏召回是不可逆的,排序错还有 rerank 能救。
检索侧(有标注时最可靠)
| 指标 | 回答什么问题 | 什么时候看它 |
|---|---|---|
| Recall@k | 正确文档进候选了吗 | 最重要——没进候选,后面全白搭 |
| Precision@k | 候选里有多少是相关的 | 噪音多不多 |
| MRR | 第一个正确结果排第几 | 单答案场景 |
| NDCG@k | 整体排序质量(考虑位置权重) | 多个相关文档时 |
优先级:先保 Recall(别漏),再优化 NDCG/MRR(别排错)。漏召回是不可逆的,排序错还有 rerank 能救。
生成侧(RAGAS 四大件)
RAGAS 是最广泛采用的开源评测框架,核心用 LLM-as-Judge 打分。四个指标各盯一种失败模式:
| 指标 | 定义 | 对应的病 |
|---|---|---|
| Faithfulness(忠实度) | 答案里的每条声明能否由检索到的上下文推出 | 有材料还胡编 |
| Answer Relevancy(答案相关性) | 答案是否切中提问 | 答非所问、答一堆废话 |
| Context Precision(上下文精确度) | 检索内容里相关的比例、是否排在前面 | 噪音太多 |
| Context Recall(上下文召回率) | 该检索的信息是否都检索到了 | 开头故障里失守的那个 |
面试高频辨析(Q2-16):
Faithfulness 管「有没有编」,Answer Relevancy 管「有没有答到点上」。 两者正交:照抄材料但答非所问 → faithfulness 高、relevancy 低;答到点上但添油加醋 → relevancy 高、faithfulness 低。
另一个专业细节:faithfulness 和 answer relevancy 是 reference-free(免参考答案) 的,不需要人工写标准答案,所以能大规模跑;而 context recall 需要标准答案或标注的 gold chunk 才能算准——这也是为什么开头那个团队的仪表盘上没有它。能说出这个差别,说明真的用过。
阈值参考
社区常用的经验线:faithfulness > 0.8,context precision > 0.75,context recall > 0.8。低于线就知道该修哪一层。注意这是参考不是标准,你的业务容忍度自己定。
工程实践(截至 2026-08)
怎么建评测集(最关键的一步)
- 来源:优先真实用户提问日志。没上线就自己写 + 让 LLM 基于文档生成候选问题再人工筛。
- 规模:100–200 条起步就够用了。别因为「凑不齐一千条」而迟迟不建——没有评测集的优化全是玄学。
- 分桶:按问题类型标注(事实型 / 多跳型 / 专有名词型 / 口语型 / 知识库里没有的)。只看总平均会掩盖局部劣化——某个改动可能提升了总分却打坏了某一类。
- 标注:给每个问题标出正确的 chunk(用于算 recall)和参考答案(用于算 context recall)。
- 必须有一类:「知识库里没有答案」的问题,用来测系统会不会老老实实说不知道。这类样本几乎所有人都会漏掉。
badcase 驱动迭代(面试最想听的工作方法)
线上 badcase 收集(点踩、客服反馈、抽样人工审) ↓ 归因(先做上面那一刀:检索 or 生成?) ↓ 打标签分类:分块问题 / 召回问题 / 排序问题 / 生成问题 / 知识库缺失 ↓ 按类型量级排优先级 → 针对性改一个变量 ↓ 加进回归集 → 每次改动跑全量回归,防止修 A 打坏 B
核心纪律:一次只改一个变量。 同时换了 embedding 又改了 chunk 大小,效果变了你也不知道是谁的功劳。
引用溯源与「说不知道」
两个 toB 场景的硬需求,也常被追问(Q2-24):
- 引用溯源:让模型在答案里标出每句话来自哪个 chunk。实现上给每个 chunk 编号后要求模型输出引用编号,再在后处理做一次校验——模型标错引用是常见现象,校验不通过就降级为「无法确定出处」。
- 说不知道:prompt 里明确「材料中没有则回答不知道」只是第一步,更有效的是设检索分数阈值——最高分低于阈值直接走兜底话术,根本不进生成。评测集里那类「知识库没有答案」的问题就是用来调这个阈值的。
其他工具
RAGAS 之外还有 DeepEval、TruLens、Phoenix、LangSmith 等,能力大同小异。RAGAS 在 2026 年已不止评 RAG,也扩展到了 Agent 工具调用轨迹、text-to-SQL、多模态等场景(对应 T5-1)。
| 五件事 | 怎么做 | 一句话点评 |
|---|---|---|
| 来源 | 优先真实用户提问日志;没上线就自己写 + 让 LLM 基于文档生成候选问题再人工筛 | 真日志比编出来的问题值钱 |
| 规模 | 100–200 条起步就够用了 | 别因为凑不齐一千条而迟迟不建 —— 没有评测集的优化全是玄学 |
| 分桶 | 按问题类型标注:事实型 / 多跳型 / 专有名词型 / 口语型 / 知识库里没有的 | 只看总平均会掩盖局部劣化,某个改动可能提总分却打坏一类 |
| 标注 | 每题标出正确的 chunk(算 recall)和参考答案(算 context recall) | 没有标注,context recall 就算不准 |
| 必须有一类 | 「知识库里没有答案」的问题,测系统会不会老老实实说不知道 | 调兜底阈值靠的就是这一类样本 |
- badcase 闭环
- 收集(点踩 / 客服反馈 / 抽样人工审)→ 归因 → 打标签分类 → 按量级排优先级 → 进回归集
- 核心纪律
- 一次只改一个变量;同时换了 embedding 又改 chunk 大小,效果变了也不知道是谁的功劳
- 回归集
- 每次改动跑全量回归,防止修 A 打坏 B
- 引用溯源
- chunk 编号 + 要求模型输出引用编号,再在后处理校验;不通过就降级为「无法确定出处」
- 说不知道
- prompt 里写「材料中没有则回答不知道」只是第一步,更有效的是设检索分数阈值走兜底话术
- 工具现状
- RAGAS 之外有 DeepEval、TruLens、Phoenix、LangSmith,能力大同小异;它已扩到 Agent 轨迹、text-to-SQL
面试视角
- 开口就切两段检索侧 / 生成侧,各给 2–3 个指标
- 点出各指标盯的病faithfulness 管有没有编,relevancy 管答没答到点
- 主动抛归因动作「把正确文档手工塞进 prompt,再问一次」
- 讲评测集怎么建重点是分桶和「没答案」那一类样本
- 备好一个真实 badcase现象 → 归因 → 试过哪些无效 → 解法 → 进回归集
- 只报得出指标名,说不清每个指标盯的是哪一种失败
- 「faithfulness 高就说明系统好」—— 开头那个 0.91 就是反例
- 被问归因时第一反应是「换个更强的模型试试」
- 评测集停留在「我们有几百条用例」,说不出分桶和标注
- 讲 badcase 只讲最终解法,跳过试过哪些无效方案
- 说得出 faithfulness 与 answer relevancy 正交,并各举一个反例
- 知道 context recall 要标注 gold chunk 才算得准,所以常缺席仪表盘
- 第一反应是手工塞进正确文档,用一次实验把两口锅分开
- 主动提「知识库里没有答案」那一类,说它用来调兜底阈值
- 敢讲试过哪些无效方案 —— 这一段最能证明案例是真的
Q2-18「讲一个最难的 badcase」是简历深挖高频题,提前备好:现象 → 归因过程 → 试过哪些无效方案 → 最终解法 → 进回归集。「试过什么无效」最能证明真实性,很多人反而不敢讲。典型追问路径:怎么评测(Q2-15)→ 评测集哪来、多少条 → RAGAS 指标区别(Q2-16)→ 答非所问怎么归因(Q2-17) → 讲一个你处理过的最难 badcase(Q2-18)。
答题结构建议:开口就分「检索侧 / 生成侧」两段 → 各给 2–3 个指标并说明各盯什么病 → 主动抛出「手工塞正确文档」这个归因动作 → 讲评测集怎么建(重点说分桶和「没答案」样本)→ 落到 badcase 闭环和「一次只改一个变量」。
Q2-18(讲一个最难的 badcase)是简历深挖的高频题,提前准备一个真实案例:现象 → 归因过程 → 试过哪些无效方案 → 最终解法 → 加进回归集。「试过什么无效」这一段最能证明真实性,很多人反而不敢讲。
小结与延伸
一句话总结:RAG 评测的第一动作是把检索和生成分开,第二动作是建一个哪怕只有 100 条但分了桶的评测集。没有评测集的 RAG 优化,全是运气。 而面试官判断你有没有真做过,往往就看你会不会主动谈评测。
下一篇 T2-9:当固定管线不够用——GraphRAG、LightRAG 与 Agentic RAG。
继续深入
本篇归属第 2 章「RAG 工程化」,去做这一章的题。