同一条回答为什么会得到 0.5 的忠实性分数?如果只调用一个库并打印数字,我们很难判断是回答真的一半错误,还是裁判漏拆了一条事实。读 Ragas 时,可以从这个问题进入:一条样本怎样变成一组可检查的判断。
本文固定 Ragas 源码提交 298b68274234c060deacab3cf5fb52aa3a20e885,以 collections API 的 Faithfulness 为主线。配套在线适配示例按该实现编写;本轮未调用收费模型,文中数值案例均为人工构造。
先把输入的含义分清
用户问题是“签收十天发现质量问题,运费谁承担”。检索证据是“经核实属于质量问题的退货,运费由商家承担”。候选回答是“商家承担运费,并在一小时内完成退款”。后一半超出了给定证据。
在这个实验中,评分器读取的是已经生成的候选和已经选好的上下文。它没有替我们运行检索,也没有查询真正的退款账本。因此 Faithfulness 不能独立证明检索完整、政策最新或任务已执行。
原理篇解释过忠实性与正确性的区别。这里要进一步看,这个区别怎样体现在函数参数和实现中:user_input、response、retrieved_contexts 是这条调用的主要输入,没有一个参数天然代表现实世界的全部事实。
从 ascore 跟到两个模型调用
在固定版本的 src/ragas/metrics/collections/faithfulness/metric.py 中,ascore 先检查三个输入是否存在,然后调用 _create_statements,把回答转换成事实列表;随后把上下文合并,调用 _create_verdicts,逐条判断事实能否被上下文支持。最后 _compute_score 汇总判定。Faithfulness 实现
这两步的目的不同。第一步负责拆解候选,第二步负责证据蕴含。util.py 中定义相应的输入、结构化输出和 Prompt,模型返回要符合这些结构。评分输入与 Prompt
用教学数据理解这条链:如果拆出“商家承担运费”和“一小时内完成退款”,裁判将前者判断为支持、后者判断为不支持,汇总为 1/2。这里还存在另一问题:前者是否保留“经核实”的条件?若事实拆分先把条件丢掉,后面的比例即使算对,语义判定仍可能失真。
因此阅读源码最重要的收获不是记住类名,而是找到可观察的误差来源:拆分遗漏、条件丢失、证据判断错误、输出解析失败和聚合失真。
为什么 NaN 必须显式处理
该实现遇到空回答、空问题或空上下文会抛出输入错误;如果模型没有生成事实,或者裁判结果没有可计数事实,则可能返回 NaN。它不是零分,也不是满分,而是这次指标没有给出有效测量。输入检查与聚合分支
如果直接对含 NaN 的结果求平均,整份报告可能变成 NaN;如果简单删除它们,评分覆盖率又消失了。正确的报告要保留原始失败,显示有效评分数,并根据发布策略决定重评还是人工复核。
from math import isfinite
# 教学结果:第二条没有有效评分,不代表候选答案已经被判错。
values = [1.0, float("nan"), 0.5]
valid = [value for value in values if isfinite(value)]
summary = {
"coverage": len(valid) / len(values),
"mean_on_scored": sum(valid) / len(valid) if valid else None,
}
print(summary) # coverage 约 0.667,已评分均值 0.75。
有些输入本来就没有事实,例如礼貌问候。这类样本可能不适用忠实性指标,需要在数据契约中明确适用范围,而不是强迫所有文本都产生可比数字。
把中文售后案例接进来
配套 ragas_example.py下载 使用 ragas.metrics.collections.Faithfulness、llm_factory 和 ascore,参数对应已核对的调用链。模型名称通过环境变量提供,不将某个模型名称写成永久可用的前提。它会发送教学政策与候选回答到配置的服务,需要读者自行提供可用凭据。
工程把库源码固定到提交,但模型服务依赖仍应在实际部署时生成自己的锁文件。固定 Python 包不能固定服务端模型行为。运行报告应保存裁判模型标识、Prompt 版本、请求配置和时间。
处理中文不只是把英文示例翻译过来。条件、否定、时间和主体关系必须出现在人工校准样本中,例如“质量问题未核实”和“非质量问题”不能被当成同一个状态。分数高低仍需人工对照验证。
自定义业务指标怎样与语义指标组合
对退款任务,除了忠实性,我们需要检查订单一致、金额一致、审批先于执行、是否重复副作用。这些最好从受信任观测直接计算,保留在外部评分器中,而不是全部改写成让 LLM 判断的自然语言问题。
可以把规则结果与 Ragas 分数放在同一条实验记录里,但不要机械平均。比如 amount_correct=False 时,回答忠实性 1.0 不能挽救错误退款。Ragas 提供评分机制,业务成功定义仍由应用负责。
对检索指标也要检查具体实现要求的字段与定义。同名的 context precision 在不同设置下可能依赖参考答案或模型判断,不能把它直接等同于前文手算的文档集合 Precision@k。库名和指标名不能代替指标契约。
两次调用背后的成本与复核
一条 Faithfulness 样本通常需要事实生成和证据判断两个阶段,结构化解析与重试可能增加实际调用次数。回答越长、事实越多,上下文与裁判成本也可能上升。评测预算要包含评分器本身,而不只计算被测助手的费用。
保存可用的中间证据时,注意公开返回对象未必暴露全部内部过程;需要结合受控日志或适配层采集,不能凭一个 MetricResult 假设已经取得所有事实与判定。日志同样应脱敏,并禁止泄露服务凭据。
这个项目适合学习“语义要求怎样变成可执行步骤”。理解调用链以后,面对一个高分,我们能够继续追问:输入是什么、事实如何拆分、证据是否可靠、哪些条目没有评分。只有这些问题能回答,数字才真正有解释力。
继续阅读与配套材料
上一篇:多模态 Agent 怎样评测:文档、图片与实时语音。
下一篇:读懂 Promptfoo:怎样把案例、模型和断言组织成回归实验。
完整示例、运行方式和验证边界见评测实验指南下载。本系列的订单、政策、金额和实验数据均为教学示例。