主题
第 6 章 · RAG 评估与优化:用数据说话,告别"拍脑袋"
🎯 本章目标:建立 RAG 评估的方法论,能针对"答非所问"、"漏答"、"幻觉"等问题做精准定位和优化。
💡 业内黄金法则:没有评估的 RAG 优化等于盲人摸象。所有线上 RAG 系统的迭代都必须建立在指标驱动的基础上。
目录
1. 为什么评估比想象中难
1.1 一个真实的痛苦故事
某公司搭了一个客服 RAG 系统:
- 开发:「我感觉效果挺好啊」
- 产品:「我试了 5 个问题都答对了」
- 上线一周后...
- 用户投诉飞起:「问退款流程,答的是售后政策」
「问产品 A 价格,答的是产品 B」
「明明文档里有答案,机器人说不知道」
老板灵魂拷问:
- 当前系统的准确率到底是多少?
- 跟两个月前对比,是变好还是变差?
- 这次优化到底有没有效果?
开发哑口无言。1.2 RAG 评估的三大难题
| 难题 | 解释 |
|---|---|
| 没有标准答案 | 同一个问题可能有多种合理回答 |
| 多环节耦合 | 不知道是检索的问题还是生成的问题 |
| 主观性强 | "好"的定义因人而异(用户更看重准确还是流畅?) |
2. RAG 评估的两个阶段
2.1 评估总览图
2.2 两个阶段必须分开评估
为什么?
情况 A: 检索找到正确文档,但 LLM 没用好 → 检索 OK, 生成差
情况 B: 检索没找到, LLM 凭印象瞎答 → 检索差, 生成自由发挥
情况 C: 都很差 → 全链路问题
只看最终答案,分不清是哪个环节的锅。2.3 评估的两类方法
| 类别 | 方法 | 特点 |
|---|---|---|
| 传统指标 | Precision/Recall/F1 | 客观但需要标注数据 |
| LLM-as-a-Judge | 用 GPT-4 给答案打分 | 主观但灵活 |
3. 检索阶段核心指标
🎯 目的:评估"检索到的 Top-K 片段,是不是真的和问题相关"。
3.1 三个核心指标
| 指标 | 含义 | 类比 |
|---|---|---|
| Context Precision | 召回的 K 个里,有多少是真相关 | 你撒网捞鱼,捞上来 10 条里有几条是你要的 |
| Context Recall | 应该被召回的相关内容,是不是都召回了 | 海里有 5 条目标鱼,你网住了几条 |
| Context Relevance | 召回内容和问题的整体相关性 | 你捞上来的东西总体上和"鱼"有多接近 |
3.2 Precision 和 Recall 的直观理解
评估问题:「猫咪发烧怎么处理?」
知识库中真正相关的 Chunk: [C1, C2, C3] (3 个)
系统召回 Top-5: [C1, C2, X1, X2, X3]
↑ ↑ ↑ ↑ ↑
相关 相关 无关 无关 无关
Precision = 召回的相关 / 召回总数 = 2/5 = 40%
Recall = 召回的相关 / 应有的相关 = 2/3 = 66.7%取舍
| 指标 | 高的代价 |
|---|---|
| Precision 高 | 可能漏掉一些相关的(Recall 低) |
| Recall 高 | 可能掺杂很多无关的(Precision 低) |
3.3 实际工程中的指标
3.3.1 Hit Rate@K(命中率)
召回的 Top-K 中,至少有一个是相关的,就算命中。
Hit Rate@K = 命中的查询数 / 总查询数简单直接,适合快速验证。
3.3.2 MRR(Mean Reciprocal Rank)
关注第一个相关结果的排名,越靠前越好。
公式(不用记):
MRR = mean(1 / 相关结果在 Top-K 中的位置)
例子:
查询 1:相关结果在第 1 位 → 1/1 = 1.0
查询 2:相关结果在第 3 位 → 1/3 = 0.33
查询 3:相关结果不在 Top-K → 0
MRR = (1.0 + 0.33 + 0) / 3 = 0.443.3.3 NDCG@K
考虑相关性等级(不只是 "相关/不相关",还分 "强相关/弱相关")和排名位置。
适合多档相关性的场景。普通 RAG 用 Hit Rate 和 MRR 就够了。
3.4 评估检索的简化流程
4. 生成阶段核心指标
🎯 目的:评估"LLM 基于 Context 生成的答案,质量好不好"。
4.1 四个核心指标
| 指标 | 中文 | 含义 |
|---|---|---|
| Faithfulness | 忠实度 | 答案是否基于 Context(无幻觉) |
| Answer Relevance | 答案相关性 | 答案是否真的回答了问题 |
| Answer Correctness | 答案正确性 | 答案是否与标准答案一致 |
| Answer Completeness | 答案完整性 | 是否答全了问题的所有方面 |
4.2 Faithfulness(忠实度):反幻觉指标
问题:「猫咪发烧 39 度怎么办?」
Context:
- "猫咪正常体温 38-39.2 度"
- "39 度属于轻度发烧,建议物理降温"
答案 A:「39 度是轻度发烧,建议物理降温」
→ Faithfulness 高(每句话都能在 Context 找到依据)
答案 B:「39 度需要立即送医,可能是猫瘟」
→ Faithfulness 低("送医" "猫瘟" Context 没说,幻觉)自动评估方法
用 LLM 把答案拆成原子事实,逐条验证每个事实能否从 Context 推出。
答案:"39 度是轻度发烧,建议物理降温,可以用酒精擦拭"
拆解:
事实 1:39 度是轻度发烧 → Context 支持 ✓
事实 2:建议物理降温 → Context 支持 ✓
事实 3:可以用酒精擦拭 → Context 未提 ✗
Faithfulness = 支持数 / 总事实数 = 2/3 = 66.7%4.3 Answer Relevance(答案相关性)
答案是否真的回答了问题(vs 答非所问)。
问题:「产品 A 多少钱?」
答案 A:「产品 A 售价 199 元」
→ 高相关性
答案 B:「产品 A 是我们的主打产品,深受用户喜爱,已经卖出 10 万件」
→ 低相关性(没回答价格)自动评估方法
让 LLM 反向操作:根据答案,反推可能的原始问题
生成的反问题 1: "产品 A 多少钱?"
生成的反问题 2: "产品 A 的价格是?"
→ 计算反问题和原问题的相似度,越高越相关4.4 Answer Correctness(正确性)
答案是否和标准答案一致。
需要预先准备 Ground Truth:
问题:「猫咪正常体温范围是?」
标准答案:「38-39.2 度」
答案 A:「38-39.2 度」 → Correctness = 1.0
答案 B:「38-39 度左右」 → Correctness = 0.8 (近似正确)
答案 C:「37 度」 → Correctness = 0.0 (错误)4.5 Answer Completeness(完整性)
是否覆盖了问题的所有方面。
问题:「介绍下 RAG 的工作流程,以及和 Fine-tuning 的区别」
答案 A:详细讲了 RAG 流程 → 完整性 50%(少了对比)
答案 B:讲了流程 + 简单提了区别 → 完整性 80%
答案 C:流程详细 + 对比详细 → 完整性 100%5. RAGAS:业界主流评估框架
5.1 RAGAS 是什么
RAGAS(Retrieval-Augmented Generation Assessment) 是开源的 RAG 评估框架,基于 LLM-as-a-Judge 思想,自动化计算上面所有指标。
5.2 RAGAS 的核心指标
5.3 RAGAS 评估示意代码
python
from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_precision,
context_recall,
)
from datasets import Dataset
eval_data = {
"question": ["猫咪发烧怎么办?", "产品 A 价格?"],
"answer": ["建议物理降温", "199 元"],
"contexts": [
["猫咪发烧的处理...", "物理降温方法..."],
["产品 A 售价 199 元"]
],
"ground_truth": ["保持凉爽并送医", "199 元"]
}
dataset = Dataset.from_dict(eval_data)
result = evaluate(
dataset,
metrics=[faithfulness, answer_relevancy, context_precision, context_recall]
)
print(result)5.4 RAGAS 的优势
| 优势 | 解释 |
|---|---|
| ✅ 自动化 | 不需要人工逐个标注 |
| ✅ 多指标 | 覆盖检索和生成全链路 |
| ✅ 开源 | 免费 |
| ✅ 可配置 | 可换不同的评判 LLM |
| ✅ 集成方便 | 支持 LangChain、LlamaIndex |
5.5 RAGAS 的局限
⚠️ RAGAS 不是绝对真理:
| 局限 | 应对 |
|---|---|
| LLM 评判本身有偏差 | 多次评估取平均;用强模型(GPT-4)做评判 |
| 评估慢 | 抽样评估;缓存评估结果 |
| 评估贵 | 用 GPT-4o-mini 评估 |
| 中文支持需调整 Prompt | 自定义中文 Prompt 模板 |
5.6 同类工具
| 工具 | 特点 |
|---|---|
| RAGAS | 最流行,框架无关 |
| TruLens | 可视化好 |
| DeepEval | Pytest 风格 |
| Phoenix (Arize) | 可观测性强 |
| Langfuse | 追踪 + 评估一体 |
6. 构建评估数据集
6.1 评估数据集的核心要素
{
"question": "猫咪发烧 39 度怎么办?",
"ground_truth": "39 度属于轻度发烧,建议物理降温并观察",
"relevant_contexts": ["chunk_15", "chunk_03"], // 标注哪些 Chunk 应该被召回
"metadata": {
"category": "宠物医疗",
"difficulty": "easy",
"intent": "处理建议"
}
}6.2 怎么构建评估集?
方法 1:人工标注(金标准但成本高)
| 步骤 | 工作 |
|---|---|
| 1. 收集真实用户问题 | 从产品日志、客服记录采集 |
| 2. 领域专家撰写标准答案 | 慢但权威 |
| 3. 标注相关 Chunk | 找出知识库中相关片段 |
| 4. 交叉验证 | 多个标注员对齐 |
规模建议:50-200 个问题即可起步。
方法 2:合成评估集(LLM 自动生成)
Step 1: 从知识库随机抽 Chunk
Step 2: 让 LLM 基于 Chunk 生成"问题 + 答案对"
Step 3: 这个 Chunk 就是 ground_truth 的相关 Chunk
例如:
Chunk: "RAG 是检索增强生成的缩写,通过检索外部知识来增强 LLM..."
LLM 生成: {
question: "什么是 RAG?",
answer: "RAG 是检索增强生成,通过检索外部知识增强 LLM",
relevant_chunk: chunk_id
}方法 3:基于用户反馈迭代
线上系统加 "👍 / 👎" 按钮
→ 👎 的案例进入待审核队列
→ 人工标注后纳入评估集
→ 评估集持续增长6.3 评估集的常见陷阱
| 陷阱 | 后果 |
|---|---|
| 问题分布不均 | 评估偏向某类问题 |
| 全是简单问题 | 评估虚高 |
| 标准答案不严谨 | 误判 LLM 答案 |
| 缺少负面样本 | 没法测"应该回答不知道"的能力 |
💡 最佳实践:评估集应包括:
- 正面问题(应该答出来的)70%
- 拒答问题(知识库没有的)20%
- 边界问题(模棱两可的)10%
7. 问题诊断流程
7.1 经典坏案例诊断决策树
7.2 五种典型坏案例
案例 1:召回不准(漏召)
症状:答案是 "我不知道",但知识库明明有。
诊断:
- 打印召回 Top-K,肉眼检查
- 如果根本没召回到相关 Chunk → 检索问题
优化:
- 切分太大 → 调小 chunk_size
- Embedding 不行 → 换 BGE-M3 / Cohere v3
- 关键词类查询 → 加 BM25 混合检索
- 召回后排序差 → 加 Rerank
案例 2:召回有但 LLM 没用上
症状:Context 里有正确答案,LLM 却答错或瞎答。
诊断:
- 检查 Prompt 模板,是否强调"必须基于 Context"
- 检查 Context 长度,是否过长导致 "Lost in the Middle"
优化:
- Prompt 加强约束:「严格根据以下资料回答,不要使用外部知识」
- Context 压缩:去掉无关 Chunk
- 关键 Chunk 放在 Context 开头或结尾(中间易被忽略)
- 加引用要求:「回答末尾标注引用编号」
案例 3:召回正确但答案不完整
症状:用户问 "退货流程和退款流程",只答了退货。
诊断:
- 问题包含多个子问题,但只召回到其中一个
优化:
- Multi-Query:把问题分解成多个子查询,分别检索
- 增大 Top-K
- 用 RAG-Fusion
案例 4:幻觉(编造)
症状:答案看似合理,但事实错误。
诊断:
- 比对答案的每个事实和 Context
优化:
- 降低 temperature 到 0
- Prompt 加 "如不确定请回答不知道"
- 上 Self-RAG 风格反思(生成后让 LLM 自检)
- 加引用追溯,每个事实必须能定位到 Context
案例 5:答案不一致
症状:同一问题,不同时间答案不同。
诊断:
- temperature 是否为 0?
- 检索结果是否稳定?
优化:
- 固定 temperature=0、seed
- 检索结果缓存
- 升级 LLM API 时做 A/B 回归
7.3 诊断工具
| 工具 | 用途 |
|---|---|
| LangSmith | 全链路追踪、可视化 |
| Langfuse | 开源追踪 + 评估 |
| Phoenix | Arize 出品,可视化分析 |
| TruLens | 评估 + 可视化 |
8. 实战优化路径
8.1 RAG 优化的"PDCA 循环"
8.2 一个真实的优化案例
公司 A 的客服 RAG,初始指标:
- Context Recall: 55%
- Faithfulness: 70%
- Answer Correctness: 60%
迭代 1:加 Rerank
→ Context Recall: 75% (+20)
→ Answer Correctness: 72% (+12)
迭代 2:切分优化(按 Markdown 标题)
→ Context Recall: 82% (+7)
→ Answer Correctness: 78% (+6)
迭代 3:Prompt 加强约束 + 引用要求
→ Faithfulness: 88% (+18)
→ 用户满意度从 3.2 → 4.1
迭代 4:加混合检索(BM25 + 向量)
→ Context Recall: 90% (+8)
→ Answer Correctness: 85% (+7)
迭代 5:构建坏案例集,针对性 Prompt 调优
→ 用户满意度 → 4.58.3 优化的优先级排序
8.4 性价比优化清单
| 优化 | 难度 | 收益 | 性价比 |
|---|---|---|---|
| 调 Prompt 模板 | ⭐ | 中 | ⭐⭐⭐⭐⭐ |
| 加 Rerank | ⭐⭐ | 高 | ⭐⭐⭐⭐⭐ |
| Chunk 大小调优 | ⭐⭐ | 中 | ⭐⭐⭐⭐ |
| 加 BM25 混合检索 | ⭐⭐⭐ | 高 | ⭐⭐⭐⭐ |
| 加元数据过滤 | ⭐⭐⭐ | 中-高 | ⭐⭐⭐⭐ |
| 查询改写 | ⭐⭐⭐ | 中 | ⭐⭐⭐ |
| 换更强 Embedding | ⭐ | 中 | ⭐⭐⭐ |
| 构建评估集 + 迭代 | ⭐⭐⭐⭐ | 极高 | ⭐⭐⭐⭐⭐ |
| 微调 Embedding | ⭐⭐⭐⭐⭐ | 中 | ⭐⭐ |
| 训练 Self-RAG | ⭐⭐⭐⭐⭐ | 高 | ⭐⭐ |
💡 结论:最高性价比 = 评估集 + Rerank + Prompt + 混合检索。
9. 思考题
为什么 Context Recall 高了,Answer Correctness 不一定也高?
参考答案
- Recall 高只代表 "正确的 Chunk 被召回了"
- 但召回的 Chunk 可能 混着大量无关 Chunk(Precision 低),稀释了关键信息
- LLM 可能在长 Context 中 "Lost in the Middle",忽略了关键 Chunk
- LLM 可能 歪曲理解 Context
- Prompt 不严,LLM 用了 Context 外的知识
解决:Recall 上去后,要进一步关注 Precision(Rerank 精排)+ Prompt 工程。
RAGAS 用 LLM-as-a-Judge,如果评判的 LLM 本身有偏见怎么办?
参考答案
缓解方案:
- 用更强的 LLM 评判(GPT-4 比 GPT-3.5 偏见小)
- 多模型投票(GPT-4 + Claude + Gemini 各打一次分取平均)
- 关键案例人工抽检(验证 LLM 评分和人工评分的相关性)
- 小规模人工评估集 + LLM 评估集结合(小规模严格金标准)
- 关注趋势而非绝对分数(同样的评估方法,看分数随版本的相对变化)
公司 RAG 上线后,用户反馈"经常答不出来",可能是哪些原因?怎么排查?
参考答案
可能原因和排查:
- 知识库覆盖不够:抽 100 个 "答不出来" 的问题,看知识库里到底有没有相关内容
- 召回失败:打印 Top-K 看是否召回到相关 Chunk
- 阈值过严:相似度阈值设得太高,本来能召回的被过滤了
- Prompt 过于保守:「不知道就说不知道」让 LLM 不敢答
- Embedding 对领域不友好:垂直领域换更适合的模型
- 查询表达问题:用户用口语,文档用专业术语,加查询改写
方法论:
- 抽样 "答不出来" 的 case
- 用诊断决策树定位问题环节
- 针对性优化
评估集到底要多大才够?
参考答案
经验值:
- 初创/MVP:30-50 个,能覆盖核心场景就行
- 中期产品:100-300 个,每个意图类别 20+ 个
- 成熟系统:500-2000+,按用户分布构建
原则:
- 覆盖度比数量重要:宁可 50 个覆盖全场景,也别 500 个都是同质问题
- 要包含 "难例":边界、拒答、多意图
- 持续增长:从线上 bad case 持续补充
- 分组评估:按问题类型分组看指标,不要只看全局平均
📌 本章小结
| 你应该已经知道 | ✅ |
|---|---|
| 为什么不能"凭感觉"评估 RAG | □ |
| 检索阶段的核心指标(Precision/Recall/Hit Rate) | □ |
| 生成阶段的核心指标(Faithfulness/Relevance/Correctness) | □ |
| RAGAS 框架的用法和局限 | □ |
| 如何构建评估数据集 | □ |
| 坏案例诊断的决策树 | □ |
| 五类典型问题的优化方法 | □ |
| 优化优先级和性价比清单 | □ |
🚀 下一步
理论和工程都讲完了,最后一站冲刺:面试!