第三章 评估输入-分类

在本章中,我们将重点讨论评估输入任务,这对于确保系统的质量和安全性至关重要。

对于需要处理不同情况下的许多独立指令集的任务,首先对查询类型进行分类,并以此为基础确定要使用哪些指令,具有诸多益处。

这可以通过定义固定的类别和 hard-coding 与处理给定类别任务相关的指令来实现。

例如,在构建客户服务助手时,首先对查询类型进行分类,然后根据该分类确定要使用哪些指令,这一点可能非常重要。

举个具体的例子,如果用户要求关闭其帐户,那么二级指令可能是添加有关如何关闭账户的额外说明;而如果用户询问特定产品的信息,则二级指令可能会添加更多的产品信息。

环境配置

参考第二章的 环境配置小节内容即可。

对用户指令进行分类

在这里,我们使用系统消息 (system_message) 作为系统的全局指导,并选用 # 作为分隔符。

分隔符是一种用于区分指令或输出中不同部分的工具,它能帮助模型识别各个部分,从而提高系统在执行特定任务时的准确性和效率。

在这个例子中,我们选择使用 # 作为分隔符。

# 是一个理想的分隔符,因为它可以被视为一个独立的 token。

 private String delimiter = "###";

这是我们的 system message,我们正在以下面的方式询问模型。


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)的例子。

   
    String message = "我希望你删除我的个人资料和所有用户数据。";
        

将这个消息格式化为一个消息列表,系统消息和用户消息使用"####"进行分隔。 我们思考一下,作为人类,这句话属于哪个类别:“我想让您删除我的个人资料。“这句话看上去属于"账户管理”,或者属于"关闭账户”。

        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)的好处是,您可以轻松地将其读入某个对象中,如果您使用其他语言,也可以转换为其他对象,然后输入到后续步骤中。

这是另一个用户消息: "告诉我更多关于你们的平板电视的信息"我们运用相同的消息列表来获取模型的响应,然后打印出来。
这里返回了另一个分类结果,并且看起来应该是正确的。


        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": "产品信息"
}

如果您有任何特定的问题或需要更详细的信息,请告诉我,我会尽力回答。
因此,根据客户咨询的分类,我们现在可以提供一套更具体的指令来处理后续步骤。
在这种情况下,我们可能会添加关于电视的额外信息,而在其他情况下,我们可能希望提供关闭账户的链接或类似的内容。 在接下来的章节中,我们将进一步了解处理输入的不同方法.

10-03 19:58