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分
这就是一种:
Rubric
LLM 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 V
LLM 回答:
该芯片推荐的 VDD 工作范围为
3.0V~3.6V,典型值为3.3V。
这时候 Evaluator 可以检查:
是否根据 Datasheet?
3.0V 是否正确?
3.6V 是否正确?
3.3V 是否正确?
有没有额外编造参数?
如果模型回答:
工作范围为3.0V~5.0V
Evaluator 就应该发现:
5.0V
和 Context:
Max = 3.6V
发生冲突。
这就是:
Context-based Evaluation
在实际技术文档问答中的应用。
四十六、如果是生成测试项,也可以怎么评价?
例如 Datasheet:
VDD Recommended Operating Range:
3.0V ~ 3.6V
LLM 自动生成测试项:
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 的:
自然语言理解能力
+
语义比较能力
使我们可以评价:
文字不同
但语义正确
的开放式回答。
更多推荐


所有评论(0)