langchain 基础 05 - 文档评估

类似机器学习的评估准确度,llm 输出也可以评估输出效果,这里 llm 既生成答案,又评估输出,既当学生又当老师

评估步骤为:

  • 首先,我们使用 LLM 自动构建了问答测试集,包含问题及标准答案。
  • 然后,同一 LLM 试图回答测试集中的所有问题,得到响应。
  • 下一步,需要评估语言模型的回答是否正确

创建测试集

创建测试集有两种方式,第一种是定义一个字典数组,第二种是使用 llm 基于答案生成提问,组成 (query-answer) 数据对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 1.手动定义测试集
examples = [
{
"query": "高清电视机怎么进行护理?",
"answer": "使用干布清洁。"
},
{
"query": "旅行背包有内外袋吗?",
"answer": "有。"
}
]
# 2.通过QAGenerateChain 生成测试集
from langchain.evaluation.qa import QAGenerateChain
from langchain.prompts import PromptTemplate
template = """You are a teacher coming up with questions to ask on a quiz.
Given the following document, please generate a question and answer based on that document.
Example Format:
<Begin Document>
...
<End Document>
QUESTION: question here
ANSWER: answer here
These questions should be detailed and be based explicitly on information in the document. Begin!
<Begin Document>
{doc}
<End Document>
请使用中文输出
"""
prompt_template=PromptTemplate(template=template)
qagenerate_chain=QAGenerateChain.from_llm(llm=llm)
qagenerate_chain.prompt=prompt_template
docs=[
"林冲被陷害后,流放至沧州。在风雪交加的夜晚,他来到破败的山神庙中避寒。庙内,他听到陆谦等人密谋放火烧死他,愤怒之下,林冲冲出庙门,手刃仇敌,从此踏上了梁山之路",
"武松在景阳冈醉酒后,不顾村民警告,独自上山。夜幕降临,一只凶猛的老虎出现。武松凭借过人的胆识和力量,赤手空拳与虎搏斗,最终打死猛虎,成为打虎英雄,声名远扬"
]
qa_pairs = qagenerate_chain.apply([{"doc": doc} for doc in docs])
print(qa_pairs)

[{‘qa_pairs’: {‘query’: ‘林冲在被陷害后流放到哪里?他在什么情况下来到了破败的山神庙?’, ‘answer’: ‘林冲被陷害后流放至沧州。在一个风雪交加的夜晚,他来到破败的山神庙中避寒。’}}, {‘qa_pairs’: {‘query’: ‘武松在景阳冈的故事中,他面对老虎的方式是怎样的?’, ‘answer’: ‘武松不顾村民的警告,独自上山,并且凭借过人的胆识和力量,赤手空拳与虎搏斗,最终打死猛虎。’}}]

通过 LLM 评估 LLM

提取 qa_pairs 中的 query 部分,使用 llm 重新回答,然后将回答结果和 answer 比较,llm 输出正确 / 错误两种回答

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 展开qa_pairs
examples=[{'query':example['qa_pairs']['query'],'answer':example['qa_pairs']['answer']} for example in qa_pairs]
# 提取query部分,让llm重新回答
querys=[example['query'] for example in examples]
outputs = llm.batch(querys)
# 整合query、answer、result
predictions=[]
for example,predict in zip(examples,outputs):
predictions.append({
'query':example['query'],
'answer':example['answer'],
'result':predict.content
})
predictions

[{‘query’: ‘林冲在被陷害后流放到哪里?他在什么情况下来到了破败的山神庙?’,
‘answer’: ‘林冲被陷害后流放至沧州。在一个风雪交加的夜晚,他来到破败的山神庙中避寒。’,
‘result’: ‘林冲被陷害后被流放到沧州。按照《水浒传》的情节发展,高俅等人设计陷害林冲,使他误入白虎堂并诬蔑他私通敌国。林冲虽经多方解释但仍被判刺配充军。\n\n 在前往沧州的路途上,林冲因为遭到高俅派来的陆谦、富安等人的追杀而逃亡。途中经过一个破败的山神庙,在雪夜中躲避风雨和可能的追兵,此时他来到了破败的山神庙,并在此处听到了陆谦等人讨论如何烧死他的对话,从而得知了他们的阴谋。\n\n 这一情节是《水浒传》中非常著名的一个转折点,林冲由此从忍辱负重的状态转变为决心复仇。’},
{‘query’: ‘武松在景阳冈的故事中,他面对老虎的方式是怎样的?’,
‘answer’: ‘武松不顾村民的警告,独自上山,并且凭借过人的胆识和力量,赤手空拳与虎搏斗,最终打死猛虎。’,
‘result’: ‘武松在《水浒传》中的景阳冈打虎情节中展现了勇敢无畏的一面。据小说描述,武松酒后路过景阳冈,在月黑风高的夜晚独自一人上山。在喝酒之前,他已经知道山上有猛虎出没,但他仍然决定挑战这一危险。\n\n 当武松遇到老虎时,他先是使用哨棒来攻击,但因为多次被老虎躲开,最终发现哨棒已经断裂。在这种情况下,武松展现了惊人的勇气和力量,赤手空拳与老虎进行肉搏战。他灵活运用身体技巧,利用树木等自然环境掩护自己,并且在战斗中表现出极大的毅力和决心。\n\n 经过一番激烈的搏斗,武松终于制服了老虎。这一情节不仅突显了他的勇敢、智慧以及体格的强壮,还体现了人在面对险境时所可能展现出的人性光辉与不屈精神。这个故事在中国文化中被视为英雄主义和个人勇气的象征之一。’}]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import langchain
langchain.debug = False
# 对预测的结果进行评估,导入QA问题回答,评估链,通过语言模型创建此链
from langchain.evaluation.qa import QAEvalChain #导入QA问题回答,评估链
#通过调用chatGPT进行评估
eval_chain = QAEvalChain.from_llm(llm)
#在此链上调用evaluate,进行评估
graded_outputs = eval_chain.evaluate(examples, predictions)
for i, eg in enumerate(examples):
print(f"Example {i}:")
print("Question: " + predictions[i]['query'])
print("Real Answer: " + predictions[i]['answer'])
print("Predicted Answer: " + predictions[i]['result'])
print("Predicted Grade: " + graded_outputs[i]['results'])
print('----'*5)

Example 0:
Question: 林冲在被陷害后流放到哪里?他在什么情况下来到了破败的山神庙?
Real Answer: 林冲被陷害后流放至沧州。在一个风雪交加的夜晚,他来到破败的山神庙中避寒。
Predicted Answer: 林冲被陷害后被流放到沧州。按照《水浒传》的情节发展,高俅等人设计陷害林冲,使他误入白虎堂并诬蔑他私通敌国。林冲虽经多方解释但仍被判刺配充军。
在前往沧州的路途上,林冲因为遭到高俅派来的陆谦、富安等人的追杀而逃亡。途中经过一个破败的山神庙,在雪夜中躲避风雨和可能的追兵,此时他来到了破败的山神庙,并在此处听到了陆谦等人讨论如何烧死他的对话,从而得知了他们的阴谋。
这一情节是《水浒传》中非常著名的一个转折点,林冲由此从忍辱负重的状态转变为决心复仇。
Predicted Grade: GRADE: CORRECT
解析:学生的回答中包含了林冲被流放到沧州这一关键信息,并且提到了他在一个风雪交加的夜晚来到破败的山神庙避寒的情节,这与真实答案中的描述一致。虽然学生提供了更多的背景信息和情节发展细节,但这些额外的信息并未影响到对事实准确性的评判,因此可以判定为正确。
--------------------
Example 1:
Question: 武松在景阳冈的故事中,他面对老虎的方式是怎样的?
Real Answer: 武松不顾村民的警告,独自上山,并且凭借过人的胆识和力量,赤手空拳与虎搏斗,最终打死猛虎。
Predicted Answer: 武松在《水浒传》中的景阳冈打虎情节中展现了勇敢无畏的一面。据小说描述,武松酒后路过景阳冈,在月黑风高的夜晚独自一人上山。在喝酒之前,他已经知道山上有猛虎出没,但他仍然决定挑战这一危险。
当武松遇到老虎时,他先是使用哨棒来攻击,但因为多次被老虎躲开,最终发现哨棒已经断裂。在这种情况下,武松展现了惊人的勇气和力量,赤手空拳与老虎进行肉搏战。他灵活运用身体技巧,利用树木等自然环境掩护自己,并且在战斗中表现出极大的毅力和决心。
经过一番激烈的搏斗,武松终于制服了老虎。这一情节不仅突显了他的勇敢、智慧以及体格的强壮,还体现了人在面对险境时所可能展现出的人性光辉与不屈精神。这个故事在中国文化中被视为英雄主义和个人勇气的象征之一。
Predicted Grade: GRADE: CORRECT
尽管学生的回答比题目要求更加详细,包含了更多的背景信息和对故事更深层次的理解,但其核心内容准确无误地反映了武松面对老虎的方式。因此,可以判断为正确答案。
--------------------

这种全自动的评估方式极大地简化了问答系统的评估和优化过程,开发者无需手动准备测试用例,也无需逐一判断正确性,大大提升了工作效率

借助 LangChain 的自动评估功能,我们可以快速评估语言模型在不同文档集上的问答效果,并可以持续地进行模型调优,无需人工干预。这种自动化的评估方法解放了双手,使我们可以更高效地迭代优化问答系统的性能