LLM-Cookbook 学习——搭建基于 ChatGPT 的问答系统>第十章 评估(下)——当不存在一个简单的正确答案时
一、前言:如果没有唯一的标准答案,应该怎么评估?
上一节我们学习了:
当一个问题存在明确标准答案时,如何对 LLM 输出进行自动化评估。
例如用户问:
你们有哪些电脑?我们可以提前规定标准答案:
{ "电脑和笔记本": { "TechPro 超极本", "BlueWave 游戏本", "PowerLite Convertible", "TechPro Desktop", "BlueWave Chromebook" } }然后直接比较:
模型输出 VS 标准答案如果集合完全相同:
✅ 正确如果模型少返回了一些:
Subset 子集如果模型多返回了一些:
Superset 超集这种任务很好评估,因为:
正确答案是比较明确的。
但是现实中的 LLM 应用大量都是:
文本生成任务例如用户问:
请介绍一下 SmartX ProPhone。模型可能回答:
SmartX ProPhone 是一款支持 5G 的智能手机, 拥有 6.1 英寸显示屏、128GB 存储空间和 12MP 双摄像头。也可以回答:
SmartX ProPhone 配备 6.1 英寸屏幕, 内置 128GB 存储空间,并支持 5G 网络。 摄像头采用 12MP 双摄方案。甚至还可以:
如果您需要一款支持 5G 的手机, SmartX ProPhone 是一个选择。 它拥有 6.1 英寸屏幕、128GB 存储空间, 并配备 12MP 双摄像头。这三个答案:
文字不一样 句子顺序不一样 表达方式不一样但:
事实内容都可以是正确的因此我们不能再简单使用:
model_answer == ideal_answer判断。
这就是第十节研究的问题:
当不存在一个简单、唯一的正确答案时,如何评估 LLM 输出?
课程主要介绍了两种思路:
方法一: 根据 Context + Rubric 让另一个 LLM 判断回答质量 方法二: 提供 Expert / Ideal Answer 让另一个 LLM 比较生成回答与标准回答也就是说,第十节开始真正使用:
LLM-as-a-Judge
即:
让 LLM 充当评审模型,对另一个 LLM 生成的回答进行评价。
课程原文就是围绕“复杂自由文本回答”“基于上下文的 Rubric 评价”以及“生成答案与专家答案比较”展开。
三、首先运行完整问答系统
课程首先构造一个比较复杂的问题:
customer_msg = f""" 告诉我有关 the smartx pro phone 和 the fotosnap camera, the dslr one 的信息。 另外,你们这有什么 TVs? """这个问题实际上包含:
问题1: SmartX ProPhone 有什么信息? 问题2: FotoSnap DSLR Camera 有什么信息? 问题3: 你们有哪些电视?然后调用之前已经封装好的函数:
products_by_category = utils_zh.get_products_from_query( customer_msg )作用:
用户问题 ↓ 识别相关商品接着:
category_and_product_list = \ utils_zh.read_string_to_list( products_by_category )作用:
LLM 返回字符串 ↓ 转换为 Python 数据结构然后:
product_info = \ utils_zh.get_mentioned_product_info( category_and_product_list )作用:
商品名称 ↓ 查询商品数据库 ↓ 得到商品详细资料最后:
assistant_answer = utils_zh.answer_user_msg( user_msg=customer_msg, product_info=product_info )作用:
用户问题 + 检索到的商品信息 ↓ LLM ↓ 生成最终客服回答整个过程就是:
Customer Question ↓ 商品识别 ↓ 商品信息检索 ↓ LLM 生成回答 ↓ assistant_answer四、为什么这个回答不能像上一节那样直接比较?
假设生成答案:
SmartX ProPhone 拥有 6.1 英寸显示屏、 128GB 存储空间、12MP 双摄像头, 并支持 5G 网络。人工标准答案:
SmartX ProPhone 是一款支持 5G 的智能手机, 拥有 128GB 存储和 6.1 英寸屏幕, 同时配备 12MP 双摄像头。如果直接:
assistant_answer == ideal_answer结果一定:
False因为字符串不同。
但是实际上:
事实1:6.1 英寸 ✅ 事实2:128GB ✅ 事实3:12MP 双摄 ✅ 事实4:5G ✅所以语义上:
完全正确这就是自由文本评估最大的难点:
我们关心的是事实和含义,而不是具体用了哪些字。
五、传统相似度指标为什么不一定够用?
传统 NLP 中可以使用一些指标比较文本之间的相似程度,例如:
BLEU ROUGE它们可以根据:
词语重叠 n-gram 重叠等方式判断:
两个文本有多像但是:
文本“长得像”不一定等于内容正确。
例如标准答案:
SmartX ProPhone 支持 5G, 价格为 899.99 美元。模型回答:
SmartX ProPhone 支持 5G, 价格为 899.99 美元。当然非常相似。
但是另一个回答:
这款手机售价 899.99 美元, 同时能够连接 5G 网络。虽然:
文字重叠变少了但:
事实仍然完全正确再比如:
SmartX ProPhone 不支持 5G, 价格为 899.99 美元。它和标准答案文字非常相似。
但多了一个:
“不”整个事实意义却发生了变化。
所以:
文本相似度并不能完全等价于事实正确性。
因此,本节尝试让:
LLM利用自己的语义理解能力进行评价。
六、第一种方法:根据 Rubric 评价回答
课程首先建立:
cust_prod_info = { 'customer_msg': customer_msg, 'context': product_info }这里包含两个非常重要的信息。
customer_msg表示:
用户到底问了什么。
而:
context表示:
生成回答时提供给 LLM 的事实依据。
所以:
cust_prod_info可以理解成:
{ 用户问题, 参考资料 }七、这里的 context 是什么?
这个地方非常重要。
这里的:
context不是:
聊天历史 context而是:
模型生成答案时所依据的商品信息。
例如:
SmartX ProPhone: 屏幕:6.1英寸 存储:128GB 摄像头:12MP 网络:5G 价格:899.99美元这些资料就是:
context于是:
Context = 事实依据 / Reference Information我们希望检查:
assistant_answer是不是:
严格根据 context 回答而不是自己编造信息。
八、定义 eval_with_rubric()
课程定义:
def eval_with_rubric( test_set, assistant_answer ):这个函数的作用就是:
让另一个 LLM 按照一套评价标准,对客服回答进行检查。
其中:
test_set包含:
用户问题 + 参考上下文而:
assistant_answer表示:
要被评价的模型回答所以:
eval_with_rubric()可以理解成:
用户问题 + 参考资料 + 模型回答 + 评价标准 ↓ Evaluator LLM ↓ 评价结果九、Rubric 是什么意思?
这是这一节非常重要的一个单词:
Rubric
可以理解成:
评分标准 / 评价准则
例如老师批改作文时,不只是说:
感觉写得挺好。而是规定:
内容正确:30分 结构清晰:20分 语言表达:20分 论证完整:30分这就是一种:
RubricLLM Evaluation 中同样如此。
与其问:
这个答案好吗?不如明确告诉评审模型:
请检查以下几个方面: ① 是否只根据提供的资料回答? ② 有没有加入资料中不存在的信息? ③ 有没有和资料发生矛盾? ④ 用户提出了多少个问题? ⑤ 每个问题是否都有回答?这就是:
使用明确 Rubric 评价 LLM 输出。
十、为什么不能只问“这个答案好不好?”
假如 Prompt 是:
请评价这个答案好不好。这个问题太模糊。
模型可能从:
语法 文风 礼貌程度 长度 表达方式 事实准确性任何一个角度评价。
不同运行结果也可能侧重点不同。
所以:
Evaluation Prompt需要比普通 Prompt 更明确。
应该告诉模型:
评价什么 + 按照什么标准评价 + 输出什么格式这样评价结果才更加稳定。
十一、eval_with_rubric() 中的 system_message
课程中:
system_message = """ 你是一位助理, 通过查看客户服务代理使用的上下文 来评估客户服务代理回答用户问题的情况。 """这句话实际上完成了:
告诉 LLM:
你现在不是客服而是:
Evaluator 评审员所以同一个 LLM:
第一次调用 = Generator 答案生成器第二次调用:
Evaluator = 答案评审器这就是:
LLM-as-a-Judge
最基本的实现方式。
十二、Evaluator 到底拿到了哪些信息?
user_message中大概组织成:
[用户问题] ... [使用的上下文] ... [客户代理的回答] ...即:
Question + Context + Answer评审模型同时看到这三个东西。
因此可以判断:
用户问了什么? ↓ 资料实际上说了什么? ↓ 助手最终回答了什么?然后检查:
回答是否受到资料支持?十三、第一个评价标准:回答是否只基于 Context?
评价问题:
助手的回应是否只基于所提供的上下文?本质是在检查:
Groundedness
即:
回答是否有依据。
例如 Context:
价格:899.99美元 支持5G模型回答:
价格为899.99美元, 支持5G。那么:
✅ 有 Context 支持但是如果模型回答:
它还支持卫星通信。而 Context 完全没写:
卫星通信那么就说明:
回答不是完全基于 Context十四、第二个评价标准:是否包含 Context 中不存在的信息?
课程还问:
回答中是否包含上下文中未提供的信息?这个问题主要就是在检查:
Hallucination
即:
幻觉 / 无依据生成。
例如:
Context: SmartX ProPhone 价格:899.99美元模型回答:
价格为899.99美元, 目前购买还赠送免费耳机。但是:
免费耳机并不存在于 Context 中。
那么:
模型自己编造了额外事实这就是需要检测的问题。
十五、第三个评价标准:有没有和 Context 冲突?
课程还检查:
回应与上下文之间是否存在任何不一致之处?例如:
Context: 128GB 存储模型:
该手机拥有256GB存储空间。这里不是:
缺少信息而是:
直接和事实冲突所以这类错误属于:
Contradiction即:
事实矛盾。
十六、第四个评价标准:用户到底问了多少个问题?
课程还要求评审模型:
计算用户提出了多少个问题。例如:
告诉我 SmartX ProPhone 的信息。 FotoSnap DSLR Camera 怎么样? 你们有哪些电视?可以理解成:
问题1:手机 问题2:相机 问题3:电视然后模型应该判断:
三个问题是不是都回答了?这实际上是在检查:
Completeness
即:
回答完整性。
十七、正确但不完整,同样可能是质量问题
例如用户问:
介绍一下 SmartX ProPhone, FotoSnap DSLR Camera, 还有你们有哪些电视?模型只回答:
SmartX ProPhone 拥有6.1英寸显示屏、 128GB存储和5G功能。这一段:
本身没有任何事实错误但是:
相机没有回答 电视没有回答所以整个回答:
仍然不完整因此评价 LLM 输出不能只检查:
“说出来的内容有没有错?”还要检查:
“应该回答的内容有没有全部回答?”可以简单总结为:
Correctness + Completeness十八、第一次评估结果怎么看?
课程中的评价结果大致是:
回答只基于提供的上下文:是 是否包含上下文不存在的信息:否 是否和上下文存在冲突:否 用户问题都得到了回答:是因此可以认为:
assistant_answer从:
事实依据 完整程度 幻觉问题几个角度来看:
质量是合格的十九、第一种评估方法的完整逻辑
可以把:
eval_with_rubric()浓缩成:
用户问题 │ ↓ ┌─────────────────┐ │ Reference │ │ Context │ └────────┬────────┘ │ ↓ 模型生成回答 │ ↓ ┌─────────────────┐ │ Evaluator LLM │ └────────┬────────┘ │ ┌────────────┼────────────┐ ↓ ↓ ↓ 有依据吗? 有幻觉吗? 完整吗? │ │ │ └────────────┴────────────┘ ↓ 评价结果这里不需要:
唯一标准答案只需要:
可靠的参考资料 + 明确的评价标准就可以评价。
二十、第二种方法:与人工标准答案进行比较
接下来课程又介绍第二种方法。
虽然自由文本:
没有唯一正确表达但是我们仍然可以:
让领域专家写一个高质量答案作为:
Ideal Answer例如:
test_set_ideal = { "customer_msg": "...", "ideal_answer": """ SmartX ProPhone... FotoSnap DSLR Camera... CineView TV... """ }注意这里的:
ideal_answer和第九节有所不同。
二十一、第九节和第十节的 ideal_answer 有什么不同?
第九节的:
ideal_answer通常是:
{ "游戏机和配件": { "GameSphere X", "GameSphere Y" } }非常结构化。
可以直接:
==比较。
而第十节:
ideal_answer是一整段自然语言:
SmartX ProPhone 是一款…… FotoSnap DSLR Camera 是一款…… 我们有以下电视……我们不能要求:
assistant_answer == ideal_answer而是要判断:
两个回答在事实内容上是否基本一致。
二十二、定义 eval_vs_ideal()
课程定义:
def eval_vs_ideal( test_set, assistant_answer ):其中:
cust_msg = test_set['customer_msg']得到:
用户问题然后:
ideal = test_set['ideal_answer']得到:
专家答案 / 理想答案最后:
completion = assistant_answer得到:
模型实际生成的答案于是评审模型得到:
问题 + 专家答案 + 模型答案然后判断:
模型答案和专家答案在事实上有多一致?二十三、为什么这里还是要使用 LLM 比较?
因为:
专家答案可能写:
该手机售价899.99美元,并支持5G。而模型回答:
SmartX ProPhone 支持5G网络, 售价为899.99美元。字符串:
不一样但是:
语义一样因此需要:
Semantic Comparison即:
语义比较
而不是:
String Comparison字符串比较。
二十四、A~E 五级评价标准
这一节一个非常重要的地方是定义:
A B C D E五种评价结果。
A:模型答案是标准答案的子集,并且没有冲突
例如专家答案:
A B C D模型回答:
A B C模型:
少说了一部分但:
说出来的内容都是对的所以属于:
A可以理解成:
不完整,但是正确。
二十五、B:模型答案是标准答案的超集,而且额外内容也是正确的
专家答案:
A B C模型回答:
A B C D如果:
D虽然专家答案没写,但是:
D 也是正确事实那么就是:
Superset也就是:
B二十六、C:模型答案与专家答案内容一致
即:
模型包含的主要事实 ≈ 专家答案包含的主要事实可能:
语言不同 顺序不同 句式不同但是:
事实内容基本一致因此:
C可以理解成:
内容等价。
课程中的正常客服回答最终被评价为:
C也就是:
生成回答和专家答案事实内容一致二十七、D:模型答案和专家答案存在事实冲突
例如专家答案:
价格为899.99美元模型:
价格为499.99美元这种情况就是:
事实不一致因此:
D表示:
存在实质性的事实分歧。
二十八、E:存在差异,但差异在事实层面不重要
这是最容易理解错的一项。
例如专家答案:
SmartX ProPhone 是一款功能强大的智能手机。模型:
SmartX ProPhone 是一款智能手机。可能表达有所不同。
但是从真正需要评价的:
核心事实来看,差异可能:
并不重要这时可以:
E也就是:
文字存在差异,但不影响事实正确性。
二十九、为什么 Prompt 特别要求忽略风格和语法?
课程评价 Prompt 中特别强调:
关注事实内容 忽略: 样式 语法 标点这是很重要的。
因为 Evaluation 的目标是:
Content Quality而不是:
文字长得像不像专家答案例如:
专家: 价格为899.99美元。模型:
售价是899.99美元。不应该因为:
“价格为”变成:
“售价是”就判错。
所以评价模型必须区分:
Surface Form 表面表达和:
Semantic Content 实际语义三十、为什么要求 Evaluator 只输出 A~E?
system message 中要求:
只输出一个字母: A B C D E而不是让模型:
写一篇评价报告原因和前面课程完全一样:
程序需要稳定、容易解析的输出。
如果模型输出:
总体来说回答很好, 大部分信息与专家答案一致……程序后续不好处理。
但:
'C'就非常简单:
if score == "C":即可执行后续逻辑。
因此再次体现:
Structured Evaluation Output
即:
评价结果也应该尽量结构化。
三十一、正常回答为什么得到 C?
课程运行:
eval_vs_ideal( test_set_ideal, assistant_answer )得到:
'C'这表示:
生成答案和:
专家答案虽然:
表达方式存在一些差异但是:
核心事实内容一致因此评审模型认为:
C = 包含基本相同的事实细节三十二、用一个明显错误回答测试 Evaluator
课程又故意构造:
assistant_answer_2 = \ "life is like a box of chocolates"意思:
生活就像一盒巧克力。而用户明明问的是:
SmartX ProPhone FotoSnap DSLR Camera 电视显然:
完全答非所问然后运行:
eval_vs_ideal( test_set_ideal, assistant_answer_2 )Evaluator 得到:
'D'也就是:
模型答案与专家答案存在明显分歧课程正是通过这个极端例子验证评价函数能够识别明显异常答案。
三十三、为什么要故意构造一个特别错误的答案?
这其实也是一种测试思想。
我们写好了:
eval_vs_ideal()之后不能默认:
评价函数肯定没问题还应该测试:
Evaluator 本身能不能正常工作?所以可以分别构造:
一个明显正确答案 + 一个明显错误答案如果:
正确答案 → C 错误答案 → D说明:
Evaluator 至少具备基本区分能力这其实就是:
Evaluation 也需要被 Evaluation。
也就是说:
不是只测试 Generator还应该考虑:
Evaluator 本身可靠吗?三十四、Generator 和 Evaluator 的关系
到这一节以后,一个典型 LLM 系统可以变成:
用户问题 │ ↓ ┌────────────┐ │ Generator │ │ 生成模型 │ └─────┬──────┘ │ ↓ assistant_answer │ ┌────────┴────────┐ │ │ ↓ ↓ Context Ideal Answer │ │ └────────┬────────┘ ↓ ┌────────────┐ │ Evaluator │ │ 评审模型 │ └─────┬──────┘ │ ↓ Evaluation这就形成:
Generate ↓ Evaluate ↓ Improve三十五、Rubric Evaluation 和 Ideal Answer Evaluation 有什么区别?
本节介绍的两种方法需要区分清楚。
| 方法 | 给 Evaluator 什么信息 | 主要检查 |
|---|---|---|
eval_with_rubric() | 用户问题 + Context + 模型回答 | 是否有依据、是否幻觉、是否完整 |
eval_vs_ideal() | 用户问题 + 专家答案 + 模型回答 | 与专家答案是否一致 |
第一种:
Question + Context + Answer重点:
回答有没有忠实依据资料?第二种:
Question + Ideal Answer + Answer重点:
回答和专家答案相比质量如何?三十六、什么时候适合使用 Context + Rubric?
如果你有:
可靠资料但是没有:
人工写好的标准答案那么特别适合:
eval_with_rubric()例如 RAG 系统:
用户问题 ↓ 检索文档 ↓ LLM 回答你已经拥有:
Retrieved Context所以可以直接问 Evaluator:
回答是否受到检索文档支持? 有没有使用文档中不存在的信息? 有没有漏回答用户问题?三十七、什么时候适合使用 Ideal Answer?
如果任务比较重要,并且能够让:
专家提前写一些:
高质量标准回答就可以建立:
Question + Ideal Answer测试集。
以后每次修改:
Prompt 模型 RAG Agent都可以:
自动重新运行再让 Evaluator:
模型答案 VS 专家答案进行比较。
三十八、这和第九节的 Development Set 怎么连接起来?
第九节我们建立:
msg_ideal_pairs_set里面保存:
问题 + 明确标准答案到了第十节,可以建立类似:
test_set_ideal = { "customer_msg": "...", "ideal_answer": "..." }区别只是:
第九节 ideal_answer = 结构化答案第十节:
ideal_answer = 专家编写的自然语言回答但是核心思想仍然一样:
把重要测试问题保存下来,并给它配上评价依据。
三十九、为什么 LLM-as-a-Judge 很适合开放式任务?
因为开放式文本最困难的地方就是:
同一个意思 可以有无数种表达例如:
5G is supported.和:
The phone supports 5G connectivity.字符串完全不同。
但是 LLM 能理解:
语义基本一样所以它可以进行:
Semantic Evaluation而不是:
Exact Match这也是第十节相比第九节最大的升级。
四十、但是 LLM Evaluator 是不是绝对可靠?
不是。
这是实际使用中一定需要知道的。
如果:
Generator 是 LLM而:
Evaluator 也是 LLM那么 Evaluator 自己也可能:
理解错误 判断错误 受 Prompt 影响 输出不稳定所以:
LLM-as-a-Judge 是一种实用的自动化评估工具,但不能理解成绝对正确的“真理机器”。
对于:
高风险任务仍然可能需要:
人工评估 专家审核 多指标评估 抽样复查尤其在建立评估体系初期,最好:
人工评价 VS LLM评价抽取一些案例进行对比。
四十一、好的 Evaluation Prompt 应该包含什么?
根据这一节,可以总结一个比较通用的 Evaluation Prompt 结构:
① 定义 Evaluator 的角色 ② 给出用户问题 ③ 给出参考资料或者专家答案 ④ 给出模型生成答案 ⑤ 明确评价维度 ⑥ 明确忽略哪些因素 ⑦ 规定输出格式例如:
你是一名回答质量评审员。 用户问题: ... 参考资料: ... 模型回答: ... 请评价: 1. 是否回答了用户问题 2. 是否有事实错误 3. 是否包含资料之外的信息 4. 是否遗漏关键信息 请输出: PASS 或 FAIL这其实就是一个完整的:
Evaluation Prompt四十二、Evaluation Prompt 本身也需要迭代
这里还有一个很重要的工程思想。
可能最开始 Rubric:
只检查事实正确性后来发现系统经常:
回答正确 但是遗漏问题那么就增加:
Completeness如果后来又发现:
引用资料之外的信息那么增加:
Groundedness所以 Evaluator 的 Prompt 也会经历:
发现问题 ↓ 修改 Rubric ↓ 重新测试和 Generator Prompt 的优化方式非常类似。
四十三、可以把 Evaluation 拆成多个维度
相比只给:
总分:8分更加实用的方法可能是:
Correctness:1 Groundedness:1 Completeness:0 Relevance:1也就是:
事实正确性 依据充分性 回答完整性 问题相关性分别评价。
这样一旦系统效果不好,就容易知道:
到底哪里不好而不是只有一个:
最终得分四十四、结合 RAG 理解第十节
这一节对 RAG 特别重要。
典型 RAG:
用户问题 ↓ Retrieval ↓ 检索 Context ↓ LLM ↓ Answer这时候至少可以评估:
① Answer 是否根据 Context? ② Answer 是否包含 Context 不支持的信息? ③ Answer 有没有和 Context 冲突? ④ Answer 有没有回答完整?也就是说:
Question + Retrieved Context + Generated Answer恰好就是:
eval_with_rubric()所需要的数据。
因此第十节实际上已经开始接近:
RAG Evaluation
中的:
Faithfulness Groundedness Answer Relevance Completeness这些概念。
四十五、结合自己的项目理解
例如需要从芯片 Datasheet 中回答:
该芯片的 VDD 工作电压范围是多少?检索得到:
Recommended Operating Conditions VDD: Min = 3.0 V Typ = 3.3 V Max = 3.6 VLLM 回答:
该芯片推荐的 VDD 工作范围为 3.0V~3.6V,典型值为3.3V。这时候 Evaluator 可以检查:
是否根据 Datasheet? 3.0V 是否正确? 3.6V 是否正确? 3.3V 是否正确? 有没有额外编造参数?如果模型回答:
工作范围为3.0V~5.0VEvaluator 就应该发现:
5.0V和 Context:
Max = 3.6V发生冲突。
这就是:
Context-based Evaluation在实际技术文档问答中的应用。
四十六、如果是生成测试项,也可以怎么评价?
例如 Datasheet:
VDD Recommended Operating Range: 3.0V ~ 3.6VLLM 自动生成测试项:
Test Item: VDD Operating Voltage Test Conditions: 3.0V, 3.3V, 3.6V这时候可能没有:
唯一标准句子因为人工可以写:
Supply Voltage Range Test也可以写:
VDD Recommended Operating Condition Verification名字不同没有关系。
真正应该评价:
测试参数是否来自 Datasheet? 范围是否正确? 测试是否覆盖关键边界? 有没有编造测试条件?这就不能使用:
字符串完全一致而应该使用:
Rubric + LLM Evaluator进行语义级评价。
四十七、第九节和第十节可以组成一个完整 Evaluation 思路
现在把两章结合:
LLM Output │ ↓ 是否存在明确标准答案? ┌─────┴─────┐ │ │ 是 否 │ │ ↓ ↓ Exact / Set Rubric Comparison + │ LLM Judge │ │ ↓ ↓ 第九节 第十节例如:
分类任务 信息抽取 商品识别通常可以:
直接比较标准答案而:
问答 总结 解释 客服回复 RAG回答通常:
不存在唯一文字答案就更适合:
Rubric + LLM Evaluator四十八、本节几个重要变量总结
| 变量 / 函数 | 含义 |
|---|---|
customer_msg | 用户提出的问题 |
products_by_category | 从问题中识别出的商品 |
category_and_product_list | 转换后的商品列表 |
product_info | 检索得到的商品详细资料 |
assistant_answer | LLM 最终生成的回答 |
context | 回答所依据的参考信息 |
cust_prod_info | 用户问题 + Context |
eval_with_rubric() | 按评价标准检查模型回答 |
test_set_ideal | 用户问题 + 专家标准回答 |
ideal_answer | 专家编写的理想回答 |
eval_vs_ideal() | 比较模型答案与专家答案 |
completion | 当前需要评价的模型答案 |
assistant_answer_2 | 故意构造的错误回答 |
五十、这一节真正解决了什么问题?
第九节解决:
“模型输出是不是标准答案?”第十节进一步解决:
“虽然模型的文字和标准答案不一样, 但是它表达的内容到底对不对?”所以 Evaluation 开始从:
Exact Match升级到:
Semantic Evaluation也就是:
字符串级比较 ↓ 语义级评价这是一个非常重要的转变。
五十一、本节完整流程总结
这一节可以总结成下面的流程:
用户问题 │ ↓ 检索相关资料 │ ↓ LLM 生成答案 │ ↓ ┌─────────────────┐ │ Evaluation │ └────────┬────────┘ │ ┌───────────┴───────────┐ │ │ ↓ ↓ Context-based Ideal-based Evaluation Evaluation │ │ ↓ ↓ Question Question Context Expert Answer Answer Model Answer │ │ ↓ ↓ LLM Evaluator LLM Evaluator │ │ ↓ ↓ 是否有依据? A / B / C / D / E 是否幻觉? 是否冲突? 是否完整?五十二、本节学习总结
第十节主要学习的是:
当 LLM 的输出是开放式自然语言、不存在唯一标准答案时,不能再简单使用字符串或者集合进行比较,而应该从事实和语义层面对回答进行评价。
第一种方法:
用户问题 + Context + 模型回答 + Rubric交给 Evaluator:
检查 Groundedness 检查 Hallucination 检查 Contradiction 检查 Completeness第二种方法:
用户问题 + Expert Answer + 模型回答交给 Evaluator:
比较两者事实内容并返回:
A B C D E这种方法充分利用了 LLM 的:
自然语言理解能力 + 语义比较能力使我们可以评价:
文字不同 但语义正确的开放式回答。
