第十章,评估(下)-当不存在一个简单的正确答案时
在上一章中,了解了如何评估 LLM 模型在 有明确正确答案 的情况下的输出,我们可以编写一个函数来判断 LLM 输出是否正确地分类并列出产品。
然而,如果 LLM 用于生成文本,而不仅仅是分类问题的答案呢?接下来,我们将探讨如何评估这种类型的 LLM 输出的方法。
一,环境配置
参考第二章的 环境配置小节内容即可。
二,运行问答系统获得一个复杂回答
java
String delimiter = "###";
String customer = "告诉我有关 the smartx pro phone 和 the fotosnap camera, the dslr one 的信息。\n" +
"另外,你们这有什么 TVs ?";
//从问题中抽取商品大类和名称
String result = this.getProductsFromQuery(customer);
JSONArray jsonArray = JSONUtil.parseArray(result);
//查找商品对应信息
List<JSONObject> products = this.getMentionedProductInfo(jsonArray);
List<ChatMessage> messages = new ArrayList<>();
String system = "您是一家大型电子商店的客户服务助理。\n" +
"请用友好和乐于助人的口吻回答问题,提供简洁明了的答案。\n" +
"确保向用户提出相关的后续问题。";
ChatMessage systemMessage = new ChatMessage();
systemMessage.setRole("system");
systemMessage.setContent(system);
messages.add(systemMessage);
ChatMessage userMessage = new ChatMessage();
userMessage.setRole("user");
userMessage.setContent(delimiter + customer + delimiter);
messages.add(userMessage);
ChatMessage assistantMessage = new ChatMessage();
assistantMessage.setRole("assistant");
assistantMessage.setContent("相关产品信息:\n" + JSONUtil.toJsonStr(products));
messages.add(assistantMessage);
String answer = this.getCompletionFromMessage(messages, 0);
log.info("test1:\n{}", answer);
test1:
我们有以下产品可供您选择:
1. SmartX ProPhone - 这是一款功能强大的智能手机,拥有6.1英寸的显示屏,128GB的存储空间,12MP的双摄像头和5G网络支持。售价为899.99美元。
2. FotoSnap DSLR Camera - 这是一款多功能的单反相机,拥有24.2MP的传感器,1080p的视频拍摄能力,3英寸的LCD屏幕和可更换镜头。售价为599.99美元。
关于电视,我们有以下几款可供选择:
1. CineView 4K TV - 这是一款55英寸的4K电视,支持HDR和智能电视功能。售价为599.99美元。
2. CineView 8K TV - 这是一款65英寸的8K电视,支持HDR和智能电视功能。售价为2999.99美元。
3. CineView OLED TV - 这是一款55英寸的OLED电视,支持4K分辨率、HDR和智能电视功能。售价为1499.99美元。
请问您对以上产品有什么具体的要求或者其他问题吗?
三,使用 GPT 评估回答是否正确
我们希望您能从中学到一个设计模式,即当您可以指定一个评估 LLM 输出的标准列表时,您实际上可以使用另一个 API 调用来评估您的第一个 LLM 输出。
java
/**
* 使用 GPT API 评估生成的回答
*
* @param customerMsg 用户的输入
* @param context 回答需要的上下文内容
* @param assistantAnswer GPT的回答
*/
public String evalWithRubric(String customerMsg, String context, String assistantAnswer) {
String delimiter = "###";
String system = "你是一位助理,通过查看客户服务代理使用的上下文来评估客户服务代理回答用户问题的情况。";
String user = "你正在根据代理使用的上下文评估对问题的提交答案。以下是数据:\n" +
" [开始]\n" +
" ************\n" +
" [用户问题]: " + customerMsg + "\n" +
" ************\n" +
" [使用的上下文]: " + context + "\n" +
" ************\n" +
" [客户代理的回答]: " + assistantAnswer + "\n" +
" ************\n" +
" [结束]\n" +
"\n" +
" 请将提交的答案的事实内容与上下文进行比较,忽略样式、语法或标点符号上的差异。\n" +
" 回答以下问题:\n" +
" 助手的回应是否只基于所提供的上下文?(是或否)\n" +
" 回答中是否包含上下文中未提供的信息?(是或否)\n" +
" 回应与上下文之间是否存在任何不一致之处?(是或否)\n" +
" 计算用户提出了多少个问题。(输出一个数字)\n" +
" 对于用户提出的每个问题,是否有相应的回答?\n" +
" 问题1:(是或否)\n" +
" 问题2:(是或否)\n" +
" ...\n" +
" 问题N:(是或否)\n" +
" 在提出的问题数量中,有多少个问题在回答中得到了回应?(输出一个数字)";
List<ChatMessage> messages = new ArrayList<>();
ChatMessage systemMessage = new ChatMessage();
systemMessage.setRole("system");
systemMessage.setContent(system);
messages.add(systemMessage);
ChatMessage userMessage = new ChatMessage();
userMessage.setRole("user");
userMessage.setContent(delimiter + user + delimiter);
messages.add(userMessage);
String answer = this.getCompletionFromMessage(messages, 0);
return answer;
}
输出:
助手的回应只基于所提供的上下文。 (是)
回答中不包含上下文中未提供的信息。 (否)
回应与上下文之间不存在任何不一致之处。 (是)
用户提出了2个问题。 (2)
对于用户提出的每个问题,都有相应的回答。
问题1:是
问题2:是
在提出的问题数量中,有2个问题在回答中得到了回应。 (2)
四、给出一个标准回答,要求其评估生成回答与标准回答的差距
在经典的自然语言处理技术中,有一些传统的度量标准用于衡量 LLM 输出与人类专家编写的输出的相似度。例如,BLUE 分数可用于衡量两段文本的相似程度。
实际上有一种更好的方法,即使用 Prompt。您可以指定 Prompt,使用 Prompt 来比较由 LLM 自动生成的客户服务代理响应与人工理想响应的匹配程度。
java
public String evalVsIdeal(String customerMsg, String idealAnswer, String assistantAnswer) {
String system = "您是一位助理,通过将客户服务代理的回答与理想(专家)回答进行比较,评估客户服务代理对用户问题的回答质量。\n" +
"请输出一个单独的字母(A 、B、C、D、E),不要包含其他内容。";
String user = "您正在比较一个给定问题的提交答案和专家答案。数据如下:\n" +
" [开始]\n" +
" ************\n" +
" [问题]: " + customerMsg + "\n" +
" ************\n" +
" [专家答案]: " + idealAnswer + "\n" +
" ************\n" +
" [提交答案]: " + assistantAnswer + "\n" +
" ************\n" +
" [结束]\n" +
"\n" +
" 比较提交答案的事实内容与专家答案。忽略样式、语法或标点符号上的差异。\n" +
" 提交的答案可能是专家答案的子集、超集,或者与之冲突。确定适用的情况,并通过选择以下选项之一回答问题:\n" +
" (A)提交的答案是专家答案的子集,并且与之完全一致。\n" +
" (B)提交的答案是专家答案的超集,并且与之完全一致。\n" +
" (C)提交的答案包含与专家答案完全相同的细节。\n" +
" (D)提交的答案与专家答案存在分歧。\n" +
" (E)答案存在差异,但从事实的角度来看这些差异并不重要。\n" +
" 选项:ABCDE";
List<ChatMessage> messages = new ArrayList<>();
ChatMessage systemMessage = new ChatMessage();
systemMessage.setRole("system");
systemMessage.setContent(system);
messages.add(systemMessage);
ChatMessage userMessage = new ChatMessage();
userMessage.setRole("user");
userMessage.setContent(user);
messages.add(userMessage);
String answer = this.getCompletionFromMessage(messages, 0);
return answer;
}
这个评分标准来自于 OpenAI 开源评估框架,这是一个非常棒的框架,其中包含了许多评估方法,既有 OpenAI 开发人员的贡献,也有更广泛的开源社区的贡献。
在这个评分标准中,我们要求 LLM 针对提交答案与专家答案进行信息内容的比较,并忽略其风格、语法和标点符号等方面的差异,但关键是我们要求它进行比较,并输出从A到E的分数,具体取决于提交的答案是否是专家答案的子集、超集或完全一致,这可能意味着它虚构或编造了一些额外的事实。
LLM 将选择其中最合适的描述。
Java快速转换到大模型开发:
配套课程的所有代码已经发布在:https://github.com/Starcloud-Cloud/java-langchain
课程合作请留言