第三章 评估输入-分类
在本章中,我们将重点讨论评估输入任务,这对于确保系统的质量和安全性至关重要。
对于需要处理不同情况下的许多独立指令集的任务,首先对查询类型进行分类,并以此为基础确定要使用哪些指令,具有诸多益处。
这可以通过定义固定的类别和 hard-coding 与处理给定类别任务相关的指令来实现。
例如,在构建客户服务助手时,首先对查询类型进行分类,然后根据该分类确定要使用哪些指令,这一点可能非常重要。
举个具体的例子,如果用户要求关闭其帐户,那么二级指令可能是添加有关如何关闭账户的额外说明;而如果用户询问特定产品的信息,则二级指令可能会添加更多的产品信息。
环境配置
参考第二章的 环境配置小节内容即可。
对用户指令进行分类
在这里,我们使用系统消息 (system_message) 作为系统的全局指导,并选用 # 作为分隔符。
分隔符是一种用于区分指令或输出中不同部分的工具,它能帮助模型识别各个部分,从而提高系统在执行特定任务时的准确性和效率。
在这个例子中,我们选择使用 # 作为分隔符。
#
是一个理想的分隔符,因为它可以被视为一个独立的 token。
java
private String delimiter = "###";
这是我们的 system message,我们正在以下面的方式询问模型。
java
private String system = "你将获得客户服务查询。\n" +
"每个客户服务查询都将用{delimiter}字符分隔。\n" +
"将每个查询分类到一个主要类别和一个次要类别中。\n" +
"以 JSON 格式提供你的输出,包含以下键:primary 和 secondary。\n" +
"\n" +
"主要类别:计费(Billing)、技术支持(Technical Support)、账户管理(Account Management)或一般咨询(General Inquiry)。\n" +
"\n" +
"计费次要类别:\n" +
"取消订阅或升级(Unsubscribe or upgrade)\n" +
"添加付款方式(Add a payment method)\n" +
"收费解释(Explanation for charge)\n" +
"争议费用(Dispute a charge)\n" +
"\n" +
"技术支持次要类别:\n" +
"常规故障排除(General troubleshooting)\n" +
"设备兼容性(Device compatibility)\n" +
"软件更新(Software updates)\n" +
"\n" +
"账户管理次要类别:\n" +
"重置密码(Password reset)\n" +
"更新个人信息(Update personal information)\n" +
"关闭账户(Close account)\n" +
"账户安全(Account security)\n" +
"\n" +
"一般咨询次要类别:\n" +
"产品信息(Product information)\n" +
"定价(Pricing)\n" +
"反馈(Feedback)\n" +
"与人工对话(Speak to a human)";
现在我们来看一个用户消息(user message)的例子。
java
String message = "我希望你删除我的个人资料和所有用户数据。";
将这个消息格式化为一个消息列表,系统消息和用户消息使用"####"进行分隔。 我们思考一下,作为人类,这句话属于哪个类别:"我想让您删除我的个人资料。"这句话看上去属于"账户管理",或者属于"关闭账户"。
java
String message = "我希望你删除我的个人资料和所有用户数据。";
List<ChatMessage> chatMessages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage();
chatMessage.setRole("system");
chatMessage.setContent(system);
chatMessages.add(chatMessage);
ChatMessage chatMessage2 = new ChatMessage();
chatMessage2.setRole("user");
chatMessage2.setContent(delimiter + message + delimiter);
chatMessages.add(chatMessage2);
String result = this.getCompletionFromMessage(chatMessages, 1);
log.info("test1:\n{}", result);
{"primary": "账户管理", "secondary": "关闭账户"}
让我们看看模型是如何思考的, 模型的分类是将"账户管理"作为"primary","关闭账户"作为"secondary"。
请求结构化输出(如 JSON)的好处是,您可以轻松地将其读入某个对象中,如果您使用其他语言,也可以转换为其他对象,然后输入到后续步骤中。
这是另一个用户消息: "告诉我更多关于你们的平板电视的信息"我们运用相同的消息列表来获取模型的响应,然后打印出来。
这里返回了另一个分类结果,并且看起来应该是正确的。
java
String message = "告诉我更多有关你们的平板电脑的信息";
List<ChatMessage> chatMessages = new ArrayList<>();
ChatMessage chatMessage = new ChatMessage();
chatMessage.setRole("system");
chatMessage.setContent(system);
chatMessages.add(chatMessage);
ChatMessage chatMessage2 = new ChatMessage();
chatMessage2.setRole("user");
chatMessage2.setContent(delimiter + message + delimiter);
chatMessages.add(chatMessage2);
String result = this.getCompletionFromMessage(chatMessages, 1);
log.info("test2:\n{}", result);
{
"primary": "一般咨询",
"secondary": "产品信息"
}
如果您有任何特定的问题或需要更详细的信息,请告诉我,我会尽力回答。
因此,根据客户咨询的分类,我们现在可以提供一套更具体的指令来处理后续步骤。
在这种情况下,我们可能会添加关于电视的额外信息,而在其他情况下,我们可能希望提供关闭账户的链接或类似的内容。 在接下来的章节中,我们将进一步了解处理输入的不同方法.
Java快速转换到大模型开发:
配套课程的所有代码已经发布在:https://github.com/Starcloud-Cloud/java-langchain
课程合作请留言