G7 效果评估
系列定位:G4 讲了切分参数要「用自己的文档试出来」,但没讲怎么试才算试过了。 G7 就是那个「试」的方法论 —— 把「感觉还行」变成「有数字」。 版本基准:MindSDK 26.1.0(RAG SDK,官方接口参考模块名
evaluation_module)
第一段 章前定位
这课不教你什么:
- 不教检索调优(查询改写 / 近似检索 / reranker)—— 那是 G5 的事,本课只负责把调优效果量出来。
- 不教问答编排(Chain / 缓存 / Prompt 压缩)—— 那是 G6。
- 不给你「合格分数线」 —— ⚠️ 官方没有给出任何「多少分算合格」的阈值, 官方只给了每个指标的取值范围和方向(越大越好 / 越低越好)。 本课给的是怎么自己建一条基线,以及怎么把「官方指标」和「你自己的基线」分清楚。
- 不教评估数据集的造法 —— 官方在《评估模块》里只规定数据集的格式与长度上限, 不提供数据集内容;官方另有一个生成工具,但它在另一个模块(见 4.2 的说明)。
这课要教你什么:
客户不会问「你用了什么模型」,客户会问「你这套答得对不对、怎么证明」。 这个问题不能用「演示一下」回答 —— 演示是你挑的问题,证明要用别人定的题。 官方为此提供了一个评估模块:12 个指标、一个
RAGEvaluator类、一个evaluate接口。 本课的难点不在调接口,在分清「哪一半是官方给的、哪一半是你自己扛的」。
第二段 学习目标
- 官方评估模块基于什么做的?Ascend 在上面加了什么?
RAGEvaluator与evaluate的函数原型、参数、返回值分别是什么?- 官方支持的12 个指标分别衡量什么?各自需要哪几个数据字段?
- 评估数据集(
dataset)四个键是什么?各自的长度上限是多少? - ⚠️ 哪些结论是官方定义的,哪些是你自己建的基线?(这条不通,报告就会被质疑)
- 评估出问题(导入失败 / 返回
None/ 分数全是 0)时,按什么顺序查?
第三段 全景:为什么「感觉还行」不算数
3.1 客户的三句追问,对应三种证据
| 客户的追问 | 你要拿出的东西 | 这课哪里讲 |
|---|---|---|
| 「答得对不对?」 | 一套别人挑的题 + 题的标准答案 | 4.2 数据集 |
| 「好在哪、差在哪?」 | 分开的分数 —— 是检索没找着,还是模型答歪了 | 4.3 指标选择 |
| 「比我原来那套强吗?」 | 同一套题、两个版本的分数 | 4.6 自建基线 |
⭐ 关键是第三句:单跑一次得到的分数证明不了任何事 —— 它只能说明「这次是这么多分」。要证明改进,必须同一套题跑两遍。
3.2 官方评估模块建立在什么之上
官方《评估模块 · 总体说明》原文:
目前,RAG 评测领域主流采用 RAGAS 模块。RAGAS 具备完善的评估指标体系,应用广泛, 并随着 RAG 技术的发展持续迭代更新。因此,基于 RAGAS 进行 Ascend 适配, 可以提升该模块的灵活性和易用性,并且同时增强了对中文的适配能力。
翻译成三句人话:
| 官方的意思 | 对你意味着什么 |
|---|---|
| 不是自研指标,是 RAGAS 的指标体系 | 指标名和含义能对到 ragas 官方文档(官方给了链接,见附录 A) |
| 做了 Ascend 适配 | 底层能跑在昇腾上,不用自己接 |
| 增强了中文适配 | 中文知识库里有个开关 language="chinese"(见 5.2) |
3.3 评测这条链路长什么样
① 手工准备评估数据集 dataset = {user_input, response, reference, retrieved_contexts}
│
▼
② 构造评估器 RAGEvaluator(llm, embeddings)
│
▼
③ 指定指标集合并评测 evaluate(metrics, dataset, language, prompts_path, show_progress)
│
▼
④ 拿到分数字典 Dict[str, List[float]] —— 每个指标一个列表,每条样本一个分数
│
▼
⑤ 分析(本课的重点) 哪些指标低 → 回哪一步改
⚠️ 诚实标注:官方《评估模块》的评测流程图是一张图片(mermaid 导出图), 正文里没有文字版的步骤说明。上面这张图是我按接口结构(类 → 方法 → 返回值) 归纳出来的,不是官方图的逐字转写,请按接口说明为准。
⭐ 链路里最费劲的是第 ① 步,最没人做的是第 ⑤ 步:
- ① 手工造数据集没有捷径 —— 官方也只给格式,不给内容;
- ⑤ 拿到一堆
[0.71, 0.83, ...]不知道怎么读 —— 本课第四段整段在教这个。
3.4 ⭐⭐ 本课最重要的一张区分表:官方指标 vs 自建基线
这张表是 G7 与市面上「讲 RAG 评测」的文章最大的区别 —— 大部分文章只列指标,不区分「哪些是标准、哪些是你自己定的」, 结果报告里混着写,客户一质疑就全线崩。
| 项 | 谁给的 | 具体情况 |
|---|---|---|
指标名(如 faithfulness) |
官方 | 官方表 1 列了 12 个,写死 |
| 指标含义(衡量什么) | 官方 | 官方给了每个指标的一句话说明 |
| 所需参数(要哪几个字段) | 官方 | 官方给了每个指标的 [user_input, response, ...] |
| 取值范围(0 到 1) | 官方 | 12 个指标全部是 [0, 1] |
| 方向(越大越好 / 越低越好) | 官方 | 只有 noise_sensitivity 是越低越好,其余越大越好 |
| 合格线(多少分算过) | ⚠️ 你自己 | 官方未给出任何阈值,需现场确认 |
| 评估数据集(问什么、标准答案是什么) | ⚠️ 你自己 | 官方只给格式与长度上限,不给内容 |
| 对比基准(改之前的分数) | ⚠️ 你自己 | 官方不提供,只能自己先跑一遍 |
⭐ 一句话记法:
官方给你「尺子的刻度」,不给你「及格线」,更不给你「考题」。 刻度是官方的,考题和及格线是你的 —— 报告里两类东西坚决不能混着写。
第四段 【如果我来做】从接到「证明一下」到交出评估报告
4.0 我会按这个顺序走(顺序错了白干)
① 先问清楚:要证明的是哪一段(检索?生成?还是整条链路?)
⚠️ 不先定这个,指标选不对,跑完一堆数字没人看
② 造数据集(最难的一步,手工活)
每个问题配四样:问题 · 标准答案 · 系统回答 · 检索到的片段
⚠️ 不先做这一步,后面全是空跑
③ 定指标(按 ① 要证明的东西选,不是全都要)
官方 12 个指标,最多一次用 14 个(官方约束)
④ 先跑一次「改之前」的分(这一版就是你的基线)
⚠️ 这步最容易被跳过 —— 没有它,后面的分数没有参照
⑤ 改一个变量(只改一个!),再跑同一套题
改了切分参数就只改切分参数,别顺手把 reranker 也开了
⑥ 两个版本对比着读(看哪个指标动了、动了多少)
⚠️ 看单项,不要看总分 —— 官方不给总分,也不给权重
⑦ 出报告:分成「官方指标」和「自建基线」两栏写
⚠️ 混着写 = 把官方结论和你的判断说成一回事
⑧ 诚实(合格线是你定的;数据集是你编的;这两句话必须写在报告里)
⭐ 这个顺序里最容易被跳过的是 ④ 和 ⑧:
- ④:只跑「改之后」的分数,客户问「那原来是多少」答不上来;
- ⑧:把「我自己定的 0.8 合格线」说得像「官方的标准」,一被追问就崩。
4.1 第 ① 步:先分清楚要证明哪一段
RAG 出错有两类,症状很像,原因完全不同:
| 症状 | 出问题的环节 | 该看哪一类指标 |
|---|---|---|
| 答案里没有正确内容 | 检索没找着(G4 的切分、G5 的检索) | context_ 开头的那几个 |
| 检索找着了,答案还是不对 | 生成环节(prompt 组装、模型) | answer_ / faithfulness 那类 |
| 答案对,但掺了一堆没依据的话 | 生成环节(管不住模型) | faithfulness / noise_sensitivity |
⭐ 这一步不做的后果:你会把「检索的问题」当成「模型的问题」去调, 调半天没效果,还以为是模型不行。
4.2 第 ② 步:造数据集(官方只给格式,不给内容)
官方的 dataset 参数说明(原文要点):
dataset:Dict[str, Any],必选。用户评估数据集,字典长度范围 [1, 4],字典格式如下: -user_input:List[str],列表长度范围 [0, 128],字符范围 [1, 1000000] -response:List[str],列表长度范围 [0, 128],字符范围 [1, 1000000] -retrieved_contexts:List[List[str]],外层列表长度范围 [1, 128], 内层列表长度范围 [0, 128],字符范围 [1, 1000000] -reference:List[str],列表长度范围 [0, 128],字符范围 [1, 1000000]其中
user_input、response和reference的列表长度 以及retrieved_contexts的外层列表长度要保持一致。
⭐ 翻译成一张「一行长什么样」的表:
| 键 | 是什么 | 官方长度约束 | 谁产出 |
|---|---|---|---|
user_input |
问题 | 列表 ≤128 条,每条 1–100 万字符 | 你手写 |
reference |
标准答案 | 同上 | 你手写(这栏最值钱) |
response |
你的系统给的答案 | 同上 | 跑一遍系统收集 |
retrieved_contexts |
系统检索到的片段(问题对应一组) | 外层 ≤128,内层 ≤128 | 跑一遍系统收集 |
⚠️ 三条必须记住的约束:
- 四条列表的长度要一一对齐 —— 问题几条、标准答案几条、系统回答几条、检索结果几组, 长度必须相等(官方原文明确要求),错位了分数就是乱的;
retrieved_contexts是"列表的列表" —— 一个问题对应多个检索片段 (内层可以 0 条,即检索啥也没返回 —— 这本身就是一个要记录的情况);- 上限是 128 条(四类都是)—— 不是建议值,是硬上限。
⭐ 一条很实用的说明:前两类你写,后两类机器生
user_input+reference是人工造的(问题的标准答案只能人来定);response+retrieved_contexts是拿你的系统跑出来的(把问题逐条喂进去,把输出存下来)。
⚠️ 关于「造数据集」的一个诚实说明:
官方的《评估模块》里没有数据集生成接口,只规定格式。 官方另有一个辅助生成工具
EvalDataGenerator(用法:EvalDataGenerator(llm, dataset_path)→generate_evaluate_data(split_doc_list)), 但它属于另一个模块《embedding 模型微调》的「评估数据辅助生成方法」, 且官方明确要求「用户需对生成的评估集进行人工筛选,挑选出符合该领域特征的问答对」。 它不解决你的领域问题,只帮你起个草。这部分本课不展开(属计划中的 H 层)。
⭐ 数据集规模怎么定:官方未给出「多少条算够」,需现场确认。 官方只给了 128 这个上限。实操上的做法是:同一条基线,两次测量样本数必须一样, 否则分数不可比 —— 这是本课归纳,不是官方口径。
4.3 第 ③ 步:从 12 个指标里挑(按 4.1 要证明的东西挑)
官方表 1 的 12 个指标(完整表在第五段,这里只给"怎么挑"):
| 你要证明的 | 挑这些指标 | 为什么 |
|---|---|---|
| 检索找得准不准 | context_precision · context_recall |
一个管"捞回来的有多少相关",一个管"相关的有没有漏" |
| 检索回来的东西跟问题搭不搭 | nv_context_relevance |
独立判官打分,不依赖标准答案 |
| 答案贴不贴题 | answer_relevancy |
答非所问、话多、漏点都会扣分 |
| 答案有没有依据(不是编的) | faithfulness · nv_response_groundedness |
回答与检索到的上下文对不对得上 |
| 答案对不对 | answer_correctness · nv_accuracy |
需要标准答案 reference |
| 会不会被无关文档带偏 | noise_sensitivity |
⭐ 越低越好,方向相反,别读反 |
| 答案像不像标准答案(语义) | answer_similarity |
⚠️ 返回的 key 是 semantic_similarity,不是 answer_similarity |
⭐ 官方对 metrics 的四条硬约束(来自 evaluate 参数说明):
集合中指标个数限制为 (0, 14];并且每个 metrics 的名字字符数范围在 [1, 50]; metrics 参数不能重复。当指标为
answer_similarity时, 返回的得分中其 key 为semantic_similarity。
翻译:最多一次塞 14 个(官方表里只有 12 个,所以事实上是全选也放得下);
名字不能重复;answer_similarity 的坑要记住 ——
你传进去叫 answer_similarity,返回的键叫 semantic_similarity,
按原名字取分数会 KeyError。
⭐ 挑指标的一条经验(本课归纳,非官方):
第一次跑,挑 4 个就够:
faithfulness+answer_relevancy+context_precision+context_recall。 理由不是我拍的 —— 官方调用示例里用的正是这四个。 先跑通这组,再按 4.1 的结论加指标。
4.4 第 ④ 步:先跑「改之前」的分数(这就是基线)
⭐ 这一步没有捷径,也最容易被跳过:
改之前的版本 → 跑评估 → 记下分数 ← 这就是你的基线(自建,官方不提供)
改之后的版本 → 跑评估 → 记下分数
↓
两个分数比 → 才是"改进"
⚠️ 两条纪律:
- 两次必须用同一套数据集(同一个
dataset字典,一条都不能改); - 两次必须用同一组指标(同一个
metrics列表)。
理由:分数是「题 × 指标 × 系统」三个变量的结果,只让系统变,另两个必须锁死。
4.5 第 ⑤ ⑥ 步:跑评估、读结果
官方 RAGEvaluator 的构造(函数原型,原文):
from mx_rag.evaluate import RAGEvaluator
RAGEvaluator(llm: LLM, embeddings: Embeddings)
| 参数 | 类型 | 可选/必选 | 官方说明 |
|---|---|---|---|
llm |
LLM |
必选 | 用于和大模型对话。需继承自 langchain.llms.base.LLM,参考 Text2TextLLM |
embeddings |
Embeddings |
必选 | 评估时需要对用户问题向量化,必须是 TextEmbedding 或 TEIEmbedding 的实例之一 |
⚠️ 这里有个很容易卡住的点:评估本身也要占卡 ——
它要 llm(当判官)和 embeddings(把问题向量化),
所以评估不是一个"纯算分"的离线脚本,它是一条要调模型的链路。
官方完整调用示例(原文照录):
from datasets import Dataset
from mx_rag.embedding.service import TEIEmbedding
from mx_rag.llm import Text2TextLLM, LLMParameterConfig
from mx_rag.utils import ClientParam
from mx_rag.evaluate import RAGEvaluator
llm = Text2TextLLM(
base_url="https://ip:port/v1/chat/completions",
model_name="model name",
llm_config=LLMParameterConfig(temperature=0.1, top_p=0.8),
client_param=ClientParam(ca_file="/path/to/ca.crt"),
)
embeddings = TEIEmbedding(url="https://ip:port/embed", client_param=ClientParam(ca_file="/path/to/ca.crt"),)
sample_queries = [
"谁提出了相对论?",
"谁因对放射性的研究而两次获得诺贝尔奖?",
"艾萨克·牛顿对科学有什么贡献?",
]
expected_responses = [
"阿尔伯特·爱因斯坦提出了相对论,这一理论改变了我们对时间、空间和引力的理解。",
"玛丽·居里是一位物理学家和化学家,她进行了关于放射性的开创性研究,并两次获得诺贝尔奖。",
"艾萨克·牛顿阐述了运动定律和万有引力定律,为经典力学奠定了基础。",
]
retrieved_contexts = [["阿尔伯特·爱因斯坦的相对论彻底改变了我们对时间、空间和引力的认知。",
"相对论由阿尔伯特·爱因斯坦提出,这一理论革新了我们对时间、空间和引力的理解。",
"阿尔伯特·爱因斯坦通过提出相对论,重新定义了我们对时间、空间和引力的看法"],
["玛丽·居里是一位杰出的物理学家和化学家,她在放射性研究方面做出了开创性贡献,并两次荣获诺贝尔奖。"
"作为物理学家和化学家,玛丽·居里在放射性领域的研究具有开创性意义,并因此两次获得诺贝尔奖。"
"玛丽·居里是一位著名的物理学家和化学家,她因在放射性研究中的开创性工作而两次获得诺贝尔奖"],
["艾萨克·牛顿提出了运动定律和万有引力定律,为经典力学的发展奠定了基础。"
"艾萨克·牛顿通过阐述运动定律和万有引力定律,为经典力学体系的建立做出了奠基性贡献。"
"艾萨克·牛顿的运动定律和万有引力定律为经典力学的形成奠定了基石。"],
]
# 大模型回答结果
responses = ["阿尔伯特·爱因斯坦提出了相对论",
"玛丽·居里",
"阐述了运动定律和万有引力定律,为经典力学奠定了基础。"]
dataset = []
for query, contexts, response, reference in zip(sample_queries, retrieved_contexts, responses, expected_responses):
dataset.append(
{
'user_input': query,
'response': response,
'retrieved_contexts': contexts,
'reference': reference
}
)
evaluation_dataset = Dataset.from_list(dataset)
evaluator = RAGEvaluator(llm=llm, embeddings=embeddings)
metrics = ["faithfulness", "answer_relevancy", "context_precision", "context_recall"]
result = evaluator.evaluate(
metrics=metrics,
dataset=evaluation_dataset.to_dict(),
language="chinese"
)
print(result)
⭐ 这段官方示例里,有三处「照抄会踩到」的地方(都是官方文档写法本身造成的):
| 现象 | 说明 |
|---|---|
第 2、3 组的 retrieved_contexts 里字符串之间没有逗号 |
Python 里相邻字符串会隐式拼接成一条 —— 官方示例本意应该是 3 条片段,照抄会变成 1 条很长的片段 |
zip(...) 静默截断 |
四组数据靠 zip 配对,只要有哪一组短了,zip 会悄悄丢掉多余项、不报错 —— 与官方"长度要保持一致"的要求相呼应,但示例本身没做校验 |
| 示例用的是通用知识(相对论、居里夫人) | 示例能跑通,但它证明不了任何知识库的效果 —— 上了你自己的项目,sample_queries 必须换成只有你那批文档能答的问题 |
官方 evaluate 的五个参数(原文):
| 参数 | 类型 | 可选/必选 | 官方说明 |
|---|---|---|---|
metrics |
list[str] |
必选 | 指标集合,个数 (0, 14];名字长度 [1, 50];不能重复 |
dataset |
Dict[str, Any] |
必选 | 评估数据集,字典长度 [1, 4],四个键见 4.2 |
language |
str |
可选 | 本地化语言。默认 None,不设置则用 ragas 自带的默认提示词;取值 "chinese" 和 "english" |
prompts_path |
str |
可选 | 本地化提示词路径;与 language 结合在 prompt_dir 目录找对应提示词文件,找到可以加速评估过程;长度限制 [1, 255] |
show_progress |
bool |
可选 | 是否显示进度条,默认不显示 |
⭐ language="chinese" 这条一定要设 ——
官方明说它是「增强了对中文的适配能力」的开关;
不设就是走 ragas 的默认(英文)提示词,中文知识库的分数会偏低且不好解释。
⭐ show_progress 是"要不要看进度"的开关:
官方说默认不显示 —— 而评估是很慢的(每条问题都要调一次大模型当判官),
128 条数据跑起来,看不到进度会以为它挂了。 建议评估时显式打开。
官方返回值的说明(原文):
返回类型:
Optional[Dict[str, List[float]]]。 - 键(Keys):指标名称(字符串),例如"answer_correctness"、"context_precision"等; - 值(Values):每个键对应一个浮点数列表,列表中每个元素代表该指标在数据集各条样本上的评估得分; - 如果评估过程中发生异常(如报错),函数会返回None。
⚠️ 这里有两个必记的坑:
- 返回的是"每条样本一个分",不是一个平均分 —— 想看总体,要自己对一列数字求平均(官方不给平均);
- 出异常时返回
None,不是抛异常 —— 所以不能靠 try/except 发现评估失败,必须显式判if result is None。
⭐ 读结果的三条纪律(本课归纳,非官方口径):
| 纪律 | 理由 |
|---|---|
| 看单项,不看"总分" | 官方不给总分、不给权重 —— 自己加权算出来的"综合分"是你的判断,不是官方结论 |
先看有没有 None |
返回 None 说明整次评估失败了,此时任何"分数"都是假的 |
| 看分布,不只看平均 | 128 条里 120 条满分 + 8 条 0 分,平均 0.94 —— 那 8 条才是问题所在 |
4.6 第 ⑦ ⑧ 步:出报告(分两栏写,这是本课的分界线)
⭐ 报告必须把两类东西分栏写:
| 栏 | 内容 | 谁给的 |
|---|---|---|
| 第一栏 · 官方指标实测值 | 指标名 + 官方定义 + 实测分数 | 指标是官方的,分数是你的 |
| 第二栏 · 自建基线与判断 | 合格线怎么定的 + 改前改后对比 + 结论 | 全是你自己的,必须标明 |
报告里必须写进去的三句话(本课归纳):
- 「本报告使用的指标定义与取值范围来自 MindSDK 26.1.0《RAG SDK · 评估模块》」 —— 交代尺子的来源;
- 「合格线 X 为本项目自定,官方未给出阈值」 —— ⭐ 这句是保险,它把"标准"和"判断"分开;
- 「评估数据集共 N 条,由本方人工编写,非官方提供」 —— 交代考题的来源。
⚠️ 一条最容易被忽略的诚实说明:
评估数据集是你自己编的,所以它只能证明「在你的题上表现如何」,不能证明「在客户的问题上表现如何」。 把这一点主动写进报告,比等客户问出来强得多 —— 这是「标注后跳过」的思路, 说清楚"证明了什么、没证明什么",本身就是交付能力。
第五段 逐件拆开:指标表、评估器、评测接口
5.1 官方表 1:支持的 12 个评测指标(原文照录,仅压缩表述)
| # | 指标名 | 衡量什么 | 需要哪些字段 | 分数方向与范围 |
|---|---|---|---|---|
| 1 | answer_correctness |
结合事实准确性和语义相似度,衡量答案与标准答案之间的正确性 | user_input, response, reference |
[0,1] 越大越正确 |
| 2 | answer_relevancy |
根据给定问题评估答案的相关性;不完整、有多余信息会扣分 | user_input, response |
[0,1] 1 为最佳 |
| 3 | answer_similarity |
生成答案与标准答案在语义上的接近程度(用 cross encoder 分数量化) | reference, response |
[0,1] 越高越一致 |⚠️ 返回 key 为 semantic_similarity |
| 4 | context_precision |
检索到的上下文中相关片段所占比例(对每个片段的 precision@k 求平均) |
user_input, reference, retrieved_contexts |
[0,1] 越大越相关 |
| 5 | context_recall |
系统成功检索出多少相关文档,重点在不遗漏 | user_input, reference, retrieved_contexts |
[0,1] 越大越相关 |
| 6 | context_entity_recall |
按参考答案与检索上下文中的实体数量衡量召回 | reference, retrieved_contexts |
[0,1] 越大越相关 |
| 7 | context_utilization |
answer 和 contexts 的相关性 | user_input, response, retrieved_contexts |
[0,1] 越大越相关 |
| 8 | faithfulness |
回答(response)与检索上下文(retrieved_contexts)在事实层面的一致程度 |
user_input, response, retrieved_contexts |
[0,1] 越高越好 |
| 9 | noise_sensitivity |
使用相关或不相关的检索文档时,因给出错误回答而出错的频率 | user_input, reference, response, retrieved_contexts |
[0,1] ⭐ 数值越低越好 |
| 10 | nv_accuracy |
回答与标准答案的一致程度:两条「大模型判官」提示各打分(0、2 或 4),转 [0,1] 后取平均 |
user_input, response, reference |
[0,1] 越高越接近 |
| 11 | nv_context_relevance |
检索到的上下文是否与用户问题相关:两条独立判官提示各评分(0、1 或 2),转 [0,1] 取平均 |
user_input, retrieved_contexts |
[0,1] 越高关联越强 |
| 12 | nv_response_groundedness |
回答在多大程度上得到检索上下文的支持(每条论断是否都能找到依据) | response, retrieved_contexts |
[0,1] 越高支持越多 |
⭐ 这张表里藏着三个「方向反了就被误读」的点:
noise_sensitivity是唯一的"越低越好" —— 报告里必须注明方向, 否则客户看到0.2会以为很差(其实很好);answer_similarity返回的 key 是semantic_similarity—— 官方明写,取错键KeyError;nv_开头的是"大模型判官"型指标(官方明说是两条独立提示分别打分再平均)—— 判官自己是大模型,所以它也有波动;两次跑同一套数据可能分数不同, 这不是代码 bug(见第八段)。
⭐ nv_ 这个前缀代表什么:官方没有专门解释这个命名。
但官方给出了它们的共同机制:「采用两条不同的'大模型判官'提示,分别打分,再转换取平均」——
用两个判官互相校对,比一个判官稳,这是这类指标的共同做法。
5.2 RAGEvaluator 与 evaluate 的完整规格(可直接照抄的部分)
评估器(官方):
from mx_rag.evaluate import RAGEvaluator
RAGEvaluator(llm: LLM, embeddings: Embeddings)
评测方法(官方函数原型):
def evaluate(metrics, dataset, language, prompts_path, show_progress)
返回值(官方):Optional[Dict[str, List[float]]] —— 异常时返回 None。
一条官方提示(藏在 evaluate 的功能描述里,很容易漏):
如果要显示 ragas 打印的日志,请设置环境变量
DISABLE_RAGAS_LOGGING为 0。
⭐ 这条值得单独拎出来:评估出问题时,它是你唯一的过程日志来源 ——
默认状态下 ragas 不打日志,你会看到「什么都没发生,然后返回一个字典或 None」。
排查评估问题前,先把这条打开。
5.3 可直接照抄的五件东西(交付时数一下够不够)
| # | 照抄什么 | 在哪 |
|---|---|---|
| ① | 评估器构造:RAGEvaluator(llm, embeddings) + 两个参数的类型要求 |
4.5 / 5.2 |
| ② | 评测调用:evaluator.evaluate(metrics=…, dataset=…, language="chinese") 与完整官方示例 |
4.5 |
| ③ | 数据集格式:四个键 + 官方长度约束 + 长度必须对齐 | 4.2 |
| ④ | 指标清单:12 个指标名 + 含义 + 所需字段 + 分数方向 | 5.1 |
| ⑤ | 环境变量:DISABLE_RAGAS_LOGGING=0 |
4.5 / 附录 B |
第六段 判据 / 验收
⚠️ 本段是本课与别处最大的不同:每条判据都注明「谁定义的」。 这一栏不写清楚,报告就经不起追问。
6.1 分栏验收(官方定义 vs 自建基线)
第一栏 · 官方定义的(这些是硬标准,不能改、不能自己解释):
| # | 判据 | 官方依据 | 怎么验 |
|---|---|---|---|
| ① | 指标名对得上 | 表 1 的 12 个名称 | 用官方原名,不改写、不缩写 |
| ② | 所需字段给齐 | 每个指标的"所需参数"列 | 缺哪个字段,哪个指标算不了 |
| ③ | 分数落在 [0, 1] |
12 个指标的取值范围 | 出现负数或大于 1 → 结果不可信 |
| ④ | 方向没读反 | noise_sensitivity 越低越好,其余越大越好 |
报告里逐条标方向 |
| ⑤ | 数据集长度对齐 | 「user_input、response、reference 的列表长度以及 retrieved_contexts 的外层列表长度要保持一致」 |
四条长度逐个核 |
| ⑥ | metrics 不重复、≤14 个、名字 ≤50 字符 |
evaluate 参数说明 |
提交前数一遍 |
第二栏 · 你自己建的基线(这些是你自己的判断,必须标明):
| # | 项 | ⚠️ 官方情况 | 你要做的 |
|---|---|---|---|
| ⑦ | 合格线(多少分算过) | 官方未给出任何阈值,需现场确认 | 自己定,并在报告里写明"本项为自定" |
| ⑧ | 评估数据集内容 | 官方只给格式与长度上限,不给内容 | 自己编题 + 自己写标准答案 |
| ⑨ | 对比基准(改之前的分数) | 官方不提供 | 先跑一遍"改之前"的版本存下来 |
| ⑩ | 数据集规模 | 官方只给上限 128,未给建议值,需现场确认 | 自己定,且两次测量必须同规模 |
| ⑪ | 综合结论 | 官方不给总分、不给权重 | 自己判断,并说明判断依据 |
⭐ 这一段的用法:交付前逐行过一遍 —— 第一栏有一条不过,这份评估就不能用; 第二栏每一条都要能在报告里找到"这是自定的"这句话。
6.2 一份合格的评估报告长什么样
| # | 项 | 判据 |
|---|---|---|
| ① | 指标定义有出处 | 标明来自 MindSDK 26.1.0《RAG SDK · 评估模块》 |
| ② | 分数是逐条样本的完整列表,不是一个平均值 | 官方返回的就是列表,别过早坍缩成平均数 |
| ③ | None 被显式排除 |
报告里说明"本次评估返回非 None" |
| ④ | 改前 / 改后两个版本都有 | 否则证明不了改进 |
| ⑤ | 两次用同一套数据集、同一组指标 | 变量只有一个 |
| ⑥ | 指明了哪些是自定项 | 合格线 / 数据集 / 规模,逐项注明 |
| ⑦ | 写清了"没证明什么" | 数据集是自编的、不能代表客户真实问题分布 |
第七段 出问题怎么查
排查顺序:先确认「评估跑没跑完」,再看「分数可不可信」,最后才分析「分数为什么低」。
| 你看到的现象 | 先归到哪一步 | 具体动作 |
|---|---|---|
返回 None |
评估没跑完 | 官方明确「评估过程中发生异常会返回 None」→ 先开 DISABLE_RAGAS_LOGGING=0 看日志;再确认 llm / embeddings 两个服务是通的 |
报 ModuleNotFoundError: mx_rag |
环境 | RAG SDK 没装(回 G3)或环境变量没生效(重开终端) |
报 datasets 找不到 |
依赖 | 官方示例用到 from datasets import Dataset,装它 |
分数全是 0 或全是 1 |
数据 | 数据集长度没对齐(四条列表长度不一致)→ 逐条核长度 |
取 answer_similarity 报 KeyError |
指标名 | 官方明确:返回的 key 是 semantic_similarity → 用返回的键名取 |
| 提交时被拒:指标个数 / 名字问题 | 参数 | 官方约束:个数 (0, 14]、名字长度 [1, 50]、不能重复 |
| 中文场景分数普遍偏低 | 语言 | language 没设 → 会走 ragas 英文默认提示词,设成 "chinese" |
| 评估慢到以为卡死了 | 进程 | show_progress 默认不显示,显式打开;评估每条都要调大模型,本来就慢 |
| 两次跑同一套数据分数不一样 | 指标类型 | ⭐ nv_ 开头的指标用"大模型判官"打分(官方:两条独立提示分别打分再平均)→ 本身有波动,不是 bug |
找不到 prompts_path 对应文件 |
提示词 | 官方说它与 language 结合在 prompt_dir 目录找;目录约束见附表;找不到就退回默认提示词 |
| 评估本身把卡占满了 | 资源 | 评估要同时跑 llm(判官)+ embeddings(向量化)→ 先 npu-smi info 看显存,别和线上服务抢 |
| 分数看着正常但结论说不出口 | 分析 | 回 4.1:先分清是检索的指标低还是生成的指标低,别笼统说"效果不好" |
⭐ 排查表里最该先做的一件事:先判「是不是 None」 ——
因为 None 之后的任何分析都是在分析空气。
第八段 常见报错清单
⚠️ 官方 RAG SDK 文档没有单独的报错码表 —— 本表按现象组织。查其他报错用官方案例库按稳定特征词检索:
https://www.hiascend.com/document/caselibrary—— 不要按「评估」这类业务词检索(那不是官方案例分类词)。
| 现象 | 属于 | 先查什么 |
|---|---|---|
import mx_rag.evaluate 失败 |
环境 | RAG SDK 是否安装 / 环境变量是否生效 |
ImportError 指向 ragas |
依赖 | 评估模块基于 RAGAS 适配,评估相关依赖要齐 |
evaluate 返回 None |
运行 | 官方:异常时返回 None → 开 DISABLE_RAGAS_LOGGING=0 看日志 |
| 抛参数校验类错误 | 参数 | metrics 个数 (0,14] / 名字长度 [1,50] / 不能重复;dataset 字典长度 [1,4] |
| 分数与预期完全不符 | 数据 | 四条列表长度是否一致(官方硬要求);retrieved_contexts 内层是否为空 |
KeyError: 'answer_similarity' |
命名 | 官方:该指标返回的 key 为 semantic_similarity |
| 中文效果明显偏差 | 语言 | language 设成 "chinese"(官方支持的取值之一) |
| 看不到任何过程输出 | 日志 | 官方:DISABLE_RAGAS_LOGGING 设为 0 才显示 ragas 日志 |
| 提示词文件找不到 / 不生效 | 提示词 | prompts_path 与 language 结合、在 prompt_dir 下找;长度限制 [1,255] |
| 大模型调用报证书类错误 | 对接 | ClientParam 的 ca_file(G4 讲过:HTTPS 下必传) |
| 评估跑到一半卡住 | 资源 | npu-smi info 看卡;评估同时占 llm 与 embeddings |
⚠️ 一条要主动跟客户说明的:
nv_系列指标用大模型当判官(官方机制),因此两次跑的分数会有少量波动。 这不是系统不稳定,是这类指标的固有特性 —— 报告里建议同时给「两次测量的差值」,而不是只给一个小数点后很多位的"精确值"。
第九段 小结 + 钩子 + 自测
三句话记住本课
- 官方评估模块是 RAGAS 的 Ascend 适配,给的是「尺子的刻度」 ——
12 个指标、
RAGEvaluator(llm, embeddings)、evaluate(metrics, dataset, language, prompts_path, show_progress), 返回Dict[str, List[float]](异常时返回None)。 - 官方给刻度,不给你及格线和考题 —— 指标名 / 含义 / 取值范围 / 方向是官方的;合格线 / 数据集 / 基准是你自己建的, 报告里这两栏坚决分开写。
- 单跑一次证明不了任何事 —— 同一套数据集、同一组指标,跑「改之前」和「改之后」两个版本,才叫证明。
自测(不看上文)
- 官方评估模块建立在什么之上?Ascend 适配加了什么好处?
RAGEvaluator的两个必选参数分别是什么?各自有什么硬要求?dataset有哪四个键?哪一个把"检索"和"生成"区分开了?- 12 个指标里,哪一个的方向是"越低越好"?哪一个返回的键名和指标名不一样?
- 哪些是官方定义的、哪些是你要自己建的?(提示:尺子的刻度 / 及格线 / 考题)
- 客户问「比我原来那套强多少」,你在跑评估前必须先做哪一件事?
钩子:下一课
现在你能证明效果了,但客户会接着问第二个问题:
「这套东西,我要买几张卡?一天能接多少问题?成本是多少?」
效果评估回答的是「对不对」,G8「容量与成本规划」回答的是「够不够、贵不贵」—— 官方对应物是模型推理加速与 MindIE 的性能 / 精度测试工具。
附录 A 官方出处
| # | 内容 | 官方出处 |
|---|---|---|
| 1 | 官方模块名 evaluation_module;「RAG 评测领域主流采用 RAGAS 模块……基于 RAGAS 进行 Ascend 适配……同时增强了对中文的适配能力」 |
MindSDK 26.1.0《RAG SDK · 接口参考 · 评估模块》→ zh/mindsdk/2610/rag/ragug/docs/zh/api/evaluation_module.md |
| 2 | 表 1 支持的 12 个评测指标(指标名 / 作用说明 / 所需参数 / 评测分数说明) | 同上(表 1,在线锚点 …mxragug_0272.html#…table1226085519551) |
| 3 | RAGEvaluator 类功能:「为 RAG 系统评测提供了统一接口,支持自定义评估指标,并可根据不同语言对评测提示词进行适配」;原型 RAGEvaluator(llm: LLM, embeddings: Embeddings);llm 需继承自 langchain.llms.base.LLM;embeddings 必须是 TextEmbedding 或 TEIEmbedding 实例之一 |
同上(在线页 …mxragug_0280.html / …mxragug_0281.html) |
| 4 | evaluate 函数原型与参数:def evaluate(metrics, dataset, language, prompts_path, show_progress);metrics 个数 (0,14]、名字长度 [1,50]、不可重复;dataset 字典长度 [1,4];language 默认 None、取值 chinese/english;prompts_path 与 language 结合、长度 [1,255];show_progress 默认不显示 |
同上(在线页 …mxragug_0275.html) |
| 5 | dataset 四个键与长度约束:user_input/response/reference 为 List[str],长度 [0,128];retrieved_contexts 为 List[List[str]],外层 [1,128]、内层 [0,128];字符范围 [1,1000000];四条列表长度要保持一致 |
同上 |
| 6 | 返回值:Optional[Dict[str, List[float]]];键为指标名,值为各条样本得分的浮点列表;异常时返回 None |
同上 |
| 7 | 环境变量提示:「如果要显示 ragas 打印的日志,请设置环境变量 DISABLE_RAGAS_LOGGING 为 0」 |
同上(evaluate 功能描述) |
| 8 | answer_similarity 返回 key 为 semantic_similarity |
同上(evaluate 的 metrics 参数说明) |
| 9 | nv_ 系列指标的机制:采用两条不同的「大模型判官」提示分别打分(nv_accuracy 打 0/2/4;nv_context_relevance 打 0/1/2),转换到 [0,1] 后取平均 |
同上(表 1) |
| 10 | 详细指标说明参见 ragas 官网(官方给的链接) | https://github.com/explodinggradients/ragas/tree/v0.1.9/docs/concepts/metrics |
| 11 | 评估数据辅助生成(属另一模块,非评估模块):EvalDataGenerator(llm, dataset_path, encrypt_fn, decrypt_fn) → generate_origin_document(...) → generate_evaluate_data(split_doc_list);官方要求「用户需对生成的评估集进行人工筛选」 |
MindSDK 26.1.0《RAG SDK · 接口参考 · embedding 模型微调 → 评估数据辅助生成方法》→ …/docs/zh/api/embedding_model_fine_tuning.md |
| 12 | 两条主线与在线问答流程(本课 3.3 的背景) | MindSDK 26.1.0《RAG SDK · 开发流程》→ …/docs/zh/user_guide.md(另见 G2 第 4.1 节) |
| 13 | ClientParam 的 ca_file / HTTPS 约定(本课第八段引用) |
见 G4 第五段 5.6(《RAG SDK · 通用 · 接口参考》→ …/docs/zh/api/universal_api.md) |
| 14 | 设备与驱动核查命令 npu-smi |
见 A1 / A3(CANN 侧官方设备管理工具) |
⚠️ 属于本文「归纳 / 实践」而非官方原文的部分,已明确标注:
- 3.3 的评测链路图 —— 官方该处的流程图是一张图片,正文没有文字版步骤, 本文按接口结构归纳,非官方图逐字转写;
- 4.0 的执行顺序、4.1 的症状归因表、4.3 的「先跑四个指标」建议、4.5 的读结果三条纪律 —— 均为实践归纳;其中「先跑四个指标」的依据是官方调用示例里用的正是这四个,非官方推荐清单;
- 4.2 的「前两类人工写、后两类机器生」 —— 用法归纳;
- 4.6 报告三句话模板、6.1 第二栏、6.2、第七段与第八段的表 —— 实践归纳;
- 第七段中「评估要同时占
llm与embeddings,因此会占用算力」 —— 由官方参数说明(两个必选参数分别是 LLM 与 Embeddings)推出,官方未把评估与算力占用直接联系起来; - ⚠️ 官方示例代码本身的写法异同(第 2、3 组
retrieved_contexts里字符串间无逗号、zip静默截断未做校验)—— 属对官方示例的观察,不是官方说明。
⚠️ 官方未给出、本文因此没有写的内容(诚实清单):
| # | 官方没给什么 | 本文怎么处理 |
|---|---|---|
| ① | 各指标的合格分数线 / 推荐阈值 | 正文只写"取值范围与方向是官方的",合格线一律标为「官方未给出,需现场确认」 |
| ② | 评估数据集的规模建议值 | 只引官方上限 128,未编造"建议 N 条" |
| ③ | 评估耗时 / 成本估算 | 正文不写任何数字;提示"评估每条都要调大模型,本来就慢" |
| ④ | 评测流程的文字版步骤 | 官方只有一张图;本文按接口结构归纳并明确标注为归纳 |
| ⑤ | prompt_dir 下提示词文件的内容 / 示例 |
只写路径参数与约束,不编造提示词内容 |
| ⑥ | RAG SDK 单独的报错码表 | 第八段按现象组织,并指向官方案例库 |
| ⑦ | 评估模块内的数据集生成接口 | 官方生成工具在另一模块,本文只做交叉引用并说明分工 |
| ⑧ | 跨版本差异说明(如 nv_ 前缀的命名解释) |
正文写明"官方没有专门解释这个命名",只讲官方给出的共同机制 |
| ⑨ | 评估相关的官方案例编号 | 未查到对应官方案例,第八段不填案例编号(不编) |
附录 B 命令详解
G2 / G3 / G4 已解释过的命令(
pip3 install、source、ls、find、du等)此处不重复。
命令 export DISABLE_RAGAS_LOGGING=0
含义:打开 ragas 的日志输出 —— 官方原文「如果要显示 ragas 打印的日志,请设置环境变量
DISABLE_RAGAS_LOGGING为 0」 拆解:export(在当前窗口定义环境变量,并传给子进程)+DISABLE_RAGAS_LOGGING(变量名)+=0(0 表示不关闭日志) 用法:export DISABLE_RAGAS_LOGGING=0(评估之前执行一次) 期望:命令本身没有输出(Linux 惯例:成功即静默);随后跑evaluate时终端会打印 ragas 的过程日志 不过会怎样:评估照常出分但过程日志不显示 → 返回None时你无从下手; 另:变量名拼错export不会报错(它不校验名字),只会静默无效
命令 echo $DISABLE_RAGAS_LOGGING
含义:确认这个环境变量在当前窗口是否真的生效 —— 环境变量"设了没设"光看是看不出来的 拆解:
echo(把值打印到屏幕)+$DISABLE_RAGAS_LOGGING($= 取这个变量的值) 用法:echo $DISABLE_RAGAS_LOGGING期望:打印0不过会怎样:打印空行 → 变量没设上,或换了终端窗口 / 重开了 shell(export只对当前窗口有效); 此时评估不会有过程日志
命令 python3 -c "from mx_rag.evaluate import RAGEvaluator; print('RAGEvaluator import: OK')"
含义:验证评估模块能被导入 —— 跑评估代码前的第一道门 拆解:
python3 -c(不写文件,直接执行后面这串代码)+from mx_rag.evaluate import RAGEvaluator(官方给的那条 import 语句)+print(...)用法:直接执行(环境与 G3 一致) 期望:打印RAGEvaluator import: OK不过会怎样:报ModuleNotFoundError: No module named 'mx_rag'→ RAG SDK 没装(回 G3)或环境变量没生效(重开终端 /source ~/.bashrc); 报ImportError且指向 ragas → 评估依赖没装齐
命令 python3 -c "import datasets; print('datasets:', datasets.__version__)"
含义:确认
datasets库在不在 —— 官方评估示例里用from datasets import Dataset构造数据集,缺它示例代码第一步就断 拆解:import datasets(导入该库)+datasets.__version__(打印版本号) 用法:直接执行 期望:打印形如datasets: 2.x.x不过会怎样:报ModuleNotFoundError: No module named 'datasets'→pip3 install datasets; 另:不装它也能跑 —— 但那样就不能用Dataset.from_list(...).to_dict(), 得自己按官方要求的四个键直接构造字典(官方evaluate收的就是Dict[str, Any])
命令 npu-smi info
含义:看卡在不在、显存被谁占了 —— 评估要同时跑
llm和embeddings,跑之前先确认底座 拆解:npu-smi(昇腾设备管理工具)+info(子命令:查设备信息) 用法:npu-smi info(⚠️ 官方:不支持多线程并发使用) 期望:一张表,列出每张卡的型号、温度、显存、进程 不过会怎样:报命令不存在 → 驱动没装(回 A1); 有输出但看不到卡 → 容器/虚拟机场景要装两层驱动(见 B5); 显存已被占满 → 评估会失败(回None),先停掉别的服务再跑 ⚠️ 容器/租用环境里设备号可能不是 0(实测是 5),别按物理机教程硬写-i 0