RAG 效果评估
召回率、准确率、忠实度与答案相关性。
一句话理解:RAG 评估要分两段看——检索段看“该找的找到没有、找来的有没有用”,生成段看“答案是否忠于资料、是否回答了问题、是否正确”;分开度量,才能知道该改检索还是改生成。
“知识库 Agent 效果怎么样?”如果团队的回答是“试了几个问题,感觉还不错”,那么下一次调整切块大小、换 Embedding 模型或者改提示词时,就没人能说清效果是变好还是变坏了。更糟的是,改好了三个问题、改坏了另外五个,上线后才被用户发现。
RAG 评估的目标,是把“感觉还不错”变成一组可以重复运行、可以对比的数字,并且在答错时能 指出是哪一段出了问题。通用的评估方法论在 Evals 评估体系 模块中系统讲解,这一课聚焦 RAG 特有的指标与评测集设计。
先分段:检索问题还是生成问题
在 RAG 全流程 一课中,我们用一个判断树区分了检索问题与生成问题。评估体系就是把这个判断树变成可度量的指标:
把两段的结果组合起来,每一个失败案例都能落进下面四个格子之一:
| 答案正确 | 答案错误 | |
|---|---|---|
| 检索到了正确片段 | 正常 | 生成问题:干扰太多、读错原文、推理出错、没按片段作答 |
| 没检索到正确片段 | 侥幸或模型自带知识:需警惕,换个问法可能就错 | 检索问题:解析、切块、元数据、查询改写、Top K、权限过滤 |
左下角那一格最容易被忽视:答案碰巧对了,但并非基于知识库。对企业规则类问题,这往往意味着模型在用自己训练时见过的通用知识“猜”,一旦公司规则与通用做法不同,就会出错。
指标:每个指标回答一个具体问题
检索段指标
| 指标 | 回答的问题 | 直觉解释 | 需要的标注 |
|---|---|---|---|
| 命中率 / Recall@K | 正确片段在前 K 个结果里吗? | 30 个问题中,有 27 个的正确片段出现在前 5 名 → 90% | 每个问题的正确片段 ID |
| 排名质量(如 MRR) | 正确片段排得靠不靠前? | 排第 1 比排第 5 好 | 同上 |
| 上下文精确度 | 放进上下文的片段里,有多少是真的有用的? | 放了 5 段,只有 1 段有用 → 干扰多 | 片段相关性判断 |
| 上下文召回 | 回答所需的信息点,是否都被检索到了? | 答案需要 3 个事实,只检索到 2 个 | 参考答案拆分成信息点 |
常用的开源评估框架 Ragas 就提供了上下文精确度(Context Precision)、上下文召回(Context Recall)、噪声敏感度等指标,可以作为实现参考。
生成段指标
| 指标 | 回答的问题 | 知识库场景的反例 |
|---|---|---|
| 忠实度(Faithfulness) | 答案中的每个陈述,都能在检索到的片段中找到依据吗? | 片段说“须先作废发票再退款”,答案说“可直接发起退款” |
| 答案相关性 | 答案是否回答了用户问的问题? | 问“怎么处理”,答了一大段“为什么会发生” |
| 正确性 | 与参考答案相比,答案对不对? | 时限说成 5 个工作日,参考答案是 7 个 |
| 引用准确性 | 引用存在吗?引用的片段支持对应结论吗? | 引用了 v2 版本,或引用的条款与结论无关 |
| 拒答正确性 | 知识库里没有答案时,是否如实说明? | 问一个不存在的政策,Agent 编了一个 |
忠实度与正确性的区别值得强调:忠实度衡量“是否基于资料”,正确性衡量“是否符合事实”。 片段本身是过期的 v2 规则时,答案可能忠实度很高、正确性却很低,这时问题出在 知识保鲜,而不是生成。
构建评测集:30 个问题怎么选
贯穿项目 02 要求为知识库建立 30 条问题的评测集。30 条不多,关键在于 覆盖不同的失败模式,而不是 30 个相似的简单问题。一个参考配比:
| 类型 | 数量 | 例子 | 主要检验 |
|---|---|---|---|
| 单点事实 | 8 | “退款审核的处理时限是几个工作日?” | 基础检索与生成 |
| 口语化 / 换说法 | 4 | “下单后多久能开发票?” | 语义检索 |
| 精确编号 | 3 | “E-4031 是什么错误?” | 关键词检索 |
| 多文档综合 | 4 | “订单已开票时,退款和发票分别怎么处理?” | 上下文召回、综合能力 |
| 版本陷阱 | 3 | 同一问题在 v2 与 v3 中答案不同 | 保鲜与元数据过滤 |
| 权限陷阱 | 3 | 华南区用户询问华东区客户合同价 | 权限过滤 |
| 无答案 | 3 | 询问知识库中不存在的政策 | 拒答正确性 |
| 表格类 | 2 | “企业版 51–200 席位年付的单价是多少?” | 解析与切块 |
每条评测数据至少包含:
{
"id": "q-017",
"type": "version_trap",
"user": {"region": "east", "role": "support"},
"question": "订单已经开了发票,还能退款吗?",
"gold_chunk_ids": ["refund-policy-v3-4.2-01", "invoice-mgmt-7-01"],
"must_not_cite": ["refund-policy-v2-*"],
"reference_answer": "可以退款,但须先完成发票作废再发起退款;发票已交付客户的,须由客户确认作废。",
"key_points": ["先作废发票再退款", "已交付发票需客户确认作废"],
"expect_refusal": false
}
问题最好来自真实用户的提问记录,而不是团队自己编写。团队编的问题往往“太像文档”,会高估语义检索的效果。评测集的更多构建方法见 构建评测集。
评分方式与使用节奏
不同指标适合不同的评分方式:
| 指标 | 推荐评分方式 | 说明 |
|---|---|---|
| Recall@K、MRR | 代码计算 | 有标注的正确片段 ID 即可,快速、确定 |
引用存在性、must_not_cite |
代码断言 | 检查引用 ID 与原文摘录 |
| 拒答正确性 | 代码 + 模型判断 | 判断回复是否表达了“未找到依据” |
| 忠实度、答案相关性 | LLM-as-Judge | 让评审模型逐条核对陈述与片段 |
| 正确性 | LLM-as-Judge + 人工抽检 | 对照 key_points 逐项检查 |
使用 LLM 评审时,要先用 20 到 30 条人工评分的样本校准:评审模型与人工判断的一致率够高,才能放心用于大规模评测。评分方式的组合见 评分方式。
什么时候跑评测:
- 每次改动检索链路之后:切块策略、Embedding 模型、Top K、重排序、查询改写、提示词,任何一项改动都跑一遍完整评测,对比前后数字。
- 知识库大批量更新之后:新文档可能挤占旧问题的检索排名。
- 定期从线上补充:用户点“没帮助”的问题、人工客服接手的问题,经过标注后加入评测集。
把评测嵌进日常迭代,就形成一个闭环:
一份评测报告的核心不是一个总分,而是一张分类型的表格:
命中率@5 忠实度 正确性 拒答正确
单点事实 (8) 100% 100% 88% -
口语化 (4) 75% 100% 75% -
精确编号 (3) 33% 100% 33% - ← 关键词检索缺失?
多文档综合 (4) 75% 75% 50% -
版本陷阱 (3) 100% 100% 33% - ← 检索到了但引用了旧版:元数据过滤未生效?
权限陷阱 (3) - - 67% -
无答案 (3) - - - 33% ← 找不到时仍然编造
表格类 (2) 50% 50% 0% - ← 解析问题?
这样的表格直接指向下一步该改什么,这就是 错误归因 的起点。
常见误区
- “只看最终答案对不对。” 不区分检索与生成,就无法定位问题,只能盲目调参或换模型。
- “评测集用团队自己写的问题就行。” 自编问题往往贴近文档措辞,会高估效果。优先使用真实用户问题。
- “LLM 评审给的分数就是事实。” 评审模型本身也会出错,需要人工样本校准,并对关键类型保留人工抽检。
产品经理检查清单
- 评测集是否覆盖单点事实、换说法、精确编号、多文档、版本、权限、无答案、表格等类型?
- 每条评测数据是否标注了正确片段、参考答案要点与期望行为?
- 检索指标与生成指标是否分开计算、分开汇报?
- LLM 评审是否经过人工样本校准?
- 每次修改检索链路或提示词后,是否强制运行评测并对比结果?
- 线上的失败案例是否有流程进入评测集?
练习
为公司知识库 Agent(贯穿项目 02)完成评测集的第一版:
- 按上文的类型配比,写出 30 个问题。尽量从真实工作中收集,至少 10 个来自同事的真实提问。
- 为其中 10 个问题完整标注:正确片段、参考答案要点、是否应拒答、不应引用的内容。
- 运行一次(手工运行也可以),为每个问题填写“是否检索到正确片段”和“答案是否正确”,把结果放进本课的四格表。
- 写一段 200 字的结论:当前最大的问题在检索段还是生成段?下一步先改什么?
延伸阅读
- Ragas 文档:Available Metrics
- Anthropic:Introducing Contextual Retrieval(以检索失败率衡量改进的实例)
下一步
RAG 与知识模块到这里结束。Agent 已经能看到正确的信息、用上企业的知识,下一个模块从「Function Calling 原理」开始,讲它如何通过工具真正作用于外部世界。