RAGAS五个指标全解读
RAGAS 跑通了,终端里出现了 5 个 0~1 的浮点数。faithfulness 0.85、answer_correctness 0.69——好还是不好?0.69 比上次的 0.72 低了 3 个点,是真退化还是随机波动?
要回答这些问题,得先搞清楚这些数字是怎么算出来的。
这篇把 5 个指标的算法拆透。每个指标讲清楚算法步骤,配一个比特严选的手算例子,让数字有体感。最后用三组配对读法告诉 你怎么根据指标组合定位问题——单看某个指标的高低只有一半信息,组合起来看才能精准归因。
总览:5 个指标的坐标系
先建一个全局认知,后面每一节展开一行:
| 指标 | 层 | 比较对象 | 算法核心 | 不达标第一反应 |
|---|---|---|---|---|
faithfulness | 生成 | response vs contexts | 拆 response 的 claims → judge 判能否由 contexts 推出 | prompt 没限定知识来源 / 模型用预训练知识补了 contexts 里没有的内容 |
answer_relevancy | 生成 | response vs user_input | 从 response 反向生成问题 → 与原问题算余弦相似度 | 回答跑题 / 啰嗦 / 答非所问 |
answer_correctness | 生成 | response vs reference | 0.75 × claim F1 + 0.25 × embedding similarity | 端到端答案差,综合性信号 |
context_precision | 检索 | contexts + user_input vs reference | judge 逐个 chunk 判有用没用 + Average Precision 排序得分 | rerank 没生效 / 过滤太宽 / 噪声 chunk 靠前 |
context_recall | 检索 | contexts vs reference | 拆 reference 的 statements → judge 判能否由 contexts 覆盖 | chunk 切太细 / 检索策略漏 / 知识库缺内容 |
版本说明:以下算法描述适用于 RAGAS 0.1.x ~ 0.4.x,核心计算逻辑跨版本未变。版本间的差异主要在 API 层面:0.2+ 将字段名从
question/answer/contexts/ground_truth改为user_input/response/retrieved_contexts/reference;对 context_precision 和 context_recall 新增了 NonLLM、ID-based 等变体(本文描述的是默认的 LLM-based 版本)。
五个指标的算法详解
1. faithfulness:回答里的话有据可查吗
faithfulness 是 5 个指标里最核心的一个——它检测幻觉。算法分两步。
1.1 Step 1:拆 claims
RAGAS 调 judge 模型,把 response 拆成一组原子级事实声明(atomic claims)。每个 claim 是一条独立的、可验证的事实陈述。
什么叫原子级:拆到不能再拆、只包含一个可验证事实的粒度。一个好的 claim 应该可以独立判定真假,不依赖其他 claim 的上下文。
用一个例子感受粒度:
| 原始句子 | 拆出的原子级 claims |
|---|---|
| AirPods Pro 2 标准保修 1 年,自购买之日起算 | ① AirPods Pro 2 标准保修期为 1 年 ② 保修自购买之日起算 |
| 推荐购买 AppleCare+,延保至 3 年 | ③ AppleCare+ 可将保修延 长至 3 年 |
注意第二句中推荐购买是主观建议,不是事实声明,不会成为 claim;但句子里蕴含的客观事实(AppleCare+ 的延保时长)仍然会被拆出。只有可以判定对还是错的陈述才算 claim。
拿比特严选的完整例子。response = AirPods Pro 2 标准保修 1 年,自购买之日起算。如果购买 AppleCare+ 可延保至 3 年。
judge 拆出三个 claims:
- claim 1:AirPods Pro 2 标准保修期为 1 年
- claim 2:保修自购买之日起算
- claim 3:购买 AppleCare+ 可延保至 3 年
1.2 Step 2:逐个判 supportable
对每个 claim,judge 判断它能否从 retrieved_contexts 推导出来。结果是二值的:supported 或 not supported。
假设 contexts 里只有一段话:“标准保修期:自购买之日起 1 年。保修范围包括非人为损坏的硬件故障。”
- claim 1:supported(上下文明确写了保修 1 年)
- claim 2:supported(上下文写了自购买之日起)
- claim 3:not supported(上下文没提 AppleCare+ 延保——这是模型从预训练知识里补的)
计算:
faithfulness = supported / total = 2 / 3 ≈ 0.667
0.667 意味着回答里 1/3 的事实声明在上下文中找不到依据。claim 3 就是幻觉——模型编了一个 contexts 里没有的信息。
不达标怎么办:faithfulness 低 → 看 response 里哪些 claims 是 not supported → 如果是模型补了预训练知识 → 改 prompt 加强“只基于给定上下文回答”的约束、加兜底指令。如果 claim 本身应该被支持但 contexts 里漏了 → 问题出在检索阶段,转查 context_recall。
2. answer_relevancy:回答切题吗
answer_relevancy 衡量的是回答有没有跑偏。算法的思路很巧——反向推导。
为什么不直接比 response 和 user_input 的相似度?
直觉上会觉得:直接把 response 和 user_input 都做 embedding,算余弦相似度不就行了?问题是,一个好的回答跟原始问题在词汇和句式上往往差异很大。
比如用户问“退货怎么寄回去”,好的回答是“请在订单页点击申请退货,选择上门取件或到付寄回,地址是 xxx”。这段回答跟问题的文本相似度并不高——因为回答是信息展开,不是重复问题。直接比两者的 embedding 会得到偏低的分数。
RAGAS 的思路是:如果这个回答是切题的,那从回答反推出的问题应该跟原始问题很像。这比直接比 response 和 user_input 更能捕捉语义切题——回答的信息指向了正确的问题方向。