第八章,搭建一个带评估的端到端问答系统
在本章中,我们将搭建一个带评估的端到端问答系统,这个系统综合了之前多节课的内容,并加入了评估过程。
-
检查输入,确认其是否能通过审核 API 的审核。
-
如果通过了审核,我们将查找产品列表。
-
如果找到了产品,我们将尝试查找它们的相关信息。
-
我们使用模型回答用户提出的问题。
-
我们将通过审核 API 对生成的答案进行审核。
-
如果没有被标记为有害的,我们将把答案返回给用户。
一,环境配置
参考第二章的 环境配置小节内容即可。
用于处理用户查询的链式 Prompt 系统
一个端到端实现问答的函数
java
//问答函数
public String processUserMessageCh(String userInput, List<ChatMessage> chatMessages) {
// 第一步: 使用 OpenAI 的 Moderation API 检查用户输入是否合规或者是一个注入的 Prompt
Moderation moderation = this.moderation(userInput);
if (moderation.flagged) {
log.error("第一步:输入被 Moderation 拒绝");
return "抱歉,您的请求不合规";
}
log.info("第一步:输入通过 Moderation 检查");
//第二步:抽取出商品和对应的目录,类似于之前课程中的方法,做了一个封装
String categoryAndProductResponse = findCategoryAndProductOnly(userInput, allProducts);
log.info("第二步:抽取出商品列表");
//第三步:查找商品对应信息
checkProducts(categoryAndProductResponse);
log.info("第三步:查找抽取出的商品信息");
//第四步:根据信息生成回答
String system = "您是一家大型电子商店的客户服务助理。\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 + userInput + delimiter);
messages.add(userMessage);
ChatMessage assistant = new ChatMessage();
assistant.setRole("assistant");
assistant.setContent("相关商品信息:\n" + categoryAndProductResponse);
messages.add(assistant);
//通过附加 all_messages 实现多轮对话
chatMessages.addAll(messages);
String result = this.getCompletionFromMessage(messages, 0);
log.info("第四步:生成用户回答");
//将该轮信息加入到历史信息中
ChatMessage assistantResult = new ChatMessage();
assistantResult.setRole("assistant");
assistantResult.setContent(result);
chatMessages.add(assistantResult);
//第五步:基于 Moderation API 检查输出是否合规
Moderation moderationResult = this.moderation(result);
if (moderationResult.flagged) {
log.error("第五步:输出被 Moderation 拒绝");
return "抱歉,我们不能提供该信息";
}
log.info("第五步:输出经过 Moderation 检查");
//第六步:模型检查是否很好地回答了用户问题
String checkUserMessage = "用户信息: " + delimiter + userInput + delimiter + " \n" +
"代理回复: " + delimiter + result + delimiter + "\n" +
"\n" +
"回复是否足够回答问题\n" +
"如果足够,回答 Y\n" +
"如果不足够,回答 N\n" +
"仅回答上述字母即可";
ChatMessage userMessage2 = new ChatMessage();
userMessage2.setRole("user");
userMessage2.setContent(checkUserMessage);
List<ChatMessage> checkMessage = Arrays.asList(
systemMessage,
userMessage2
);
String checkResult = this.getCompletionFromMessage(checkMessage, 0);
log.info("第六步:模型评估该回答");
if (checkResult.contains("Y")) {
log.info("第七步:模型赞同了该回答.");
return result;
} else {
log.info("第七步:模型不赞成该回答.");
return "很抱歉,我无法提供您所需的信息。我将为您转接到一位人工客服代表以获取进一步帮助。";
}
}
//从用户问题中抽取商品和类别
public String findCategoryAndProductOnly(String userInput, String productsAndCategory) {
String system = "您将获得客户服务查询。\n" +
" 客户服务查询将使用" + delimiter + "字符分隔。\n" +
" 输出一个可解析的Python列表,列表每一个元素是一个JSON对象,每个对象具有以下格式:\n" +
" 'category': <包括以下几个类别:Computers and Laptops,Smartphones and Accessories,Televisions and Home Theater Systems,Gaming Consoles and Accessories,Audio Equipment,Cameras and Camcorders>\n" +
" 以及\n" +
" 'products': <必须是下面的允许产品列表中找到的产品列表>\n" +
"\n" +
" 其中类别和产品必须在客户服务查询中找到。\n" +
" 如果提到了产品,则必须将其与允许产品列表中的正确类别关联。\n" +
" 如果未找到任何产品或类别,则输出一个空列表。\n" +
" 除了列表外,不要输出其他任何信息!\n" +
"\n" +
" 允许的产品以JSON格式提供。\n" +
" 每个项的键表示类别。\n" +
" 每个项的值是该类别中的产品列表。\n" +
" 允许的产品: " + productsAndCategory;
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 + userInput + delimiter);
messages.add(userMessage);
return this.getCompletionFromMessage(messages, 0, 600);
}
//检查GPT返回结果中的商品应该是存在于商品列表中的
public Boolean checkProducts(String categoryAndProductResponse) {
return true;
}
测试:
java
String result = processUserMessageCh("请告诉我关于 smartx pro phone 和 the fotosnap camera 的信息。另外,请告诉我关于你们的tvs的情况。", new ArrayList<>());
log.info("result: {}", result);
输出结果:
第一步:输入通过 Moderation 检查
第二步:抽取出商品列表
第三步:查找抽取出的商品信息
第四步:生成用户回答
第五步:输出经过 Moderation 检查
第六步:模型评估该回答
第七步:模型赞同了该回答.
关于SmartX Pro手机和FotoSnap相机的信息如下:
SmartX Pro手机:
- 品牌:SmartX
- 型号:SX-PP10
- 屏幕尺寸:6.1英寸
- 存储容量:128GB
- 摄像功能:12MP双摄像头
- 网络:支持5G
- 保修期:1年
- 价格:899.99美元
FotoSnap相机:
- 品牌:FotoSnap
- DSLR相机型号:FS-DSLR200
- 传感器像素:24.2MP
- 视频分辨率:1080p
- LCD屏幕尺寸:3英寸
- 可更换镜头
- 保修期:1年
- 价格:599.99美元
我们还有其他类型的相机可供选择,如无反相机和摄像机。您对这些产品有兴趣吗?如果有,请告诉我您对哪种类型的相机或摄像机感兴趣,我可以为您提供更多信息。
通过监控系统在更多输入上的质量,您可以修改步骤,提高系统的整体性能。 也许我们会发现,对于某些步骤,我们的提示可能更好,也许有些步骤甚至不必要,也许我们会找到更好的检索方法等等。
我们将在下一章中进一步讨论这个问题。
Java快速转换到大模型开发:
配套课程的所有代码已经发布在:https://github.com/Starcloud-Cloud/java-langchain
课程合作请留言