• 【Java-LangChain:面向开发者的提示工程-8】聊天机器人


    第八章 聊天机器人

    使用一个大型语言模型的一个令人兴奋的事情是,我们可以用它来构建一个定制的聊天机器人 (Chatbot) ,只需要很少的工作量。在这一节中,我们将探索如何利用聊天的方式,与个性化(或专门针对特定任务或行为的)聊天机器人进行扩展对话。

    像 ChatGPT 这样的聊天模型实际上是组装成以一系列消息作为输入,并返回一个模型生成的消息作为输出的。这种聊天格式原本的设计目标是简便多轮对话,但我们通过之前的学习可以知道,它对于不会涉及任何对话的单轮任务也同样有用。

    环境配置

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

    身份与上下文构建

    接下来,我们将定义两个辅助函数。
    第一个方法已经陪伴了您一整个教程,即 getCompletion ,其适用于单轮对话。我们将 Prompt 放入某种类似用户消息的对话框中。
    另一个称为 getCompletionFromMessage ,传入一个消息列表。这些消息可以来自大量不同的角色 (roles) ,我们会描述一下这些角色。

    第一条消息中,我们以系统身份发送系统消息 (system message) ,它提供了一个总体的指示。系统消息则有助于设置助手的行为和角色,并作为对话的高级指示。你可以想象它在助手的耳边低语,引导它的回应,而用户不会注意到系统消息。因此,作为用户,如果你曾经使用过 ChatGPT,您可能从来不知道 ChatGPT 的系统消息是什么,这是有意为之的。系统消息的好处是为开发者提供了一种方法,在不让请求本身成为对话的一部分的情况下,引导助手并指导其回应。
    在 ChatGPT 网页界面中,您的消息称为用户消息,而 ChatGPT 的消息称为助手消息。但在构建聊天机器人时,在发送了系统消息之后,您的角色可以仅作为用户 (user) ;也可以在用户和助手 (assistant) 之间交替,从而提供对话上下文。

    现在让我们尝试在对话中使用这些消息。我们将使用上面的函数来获取从这些消息中得到的回答,同时,使用更高的温度 (temperature)(越高生成的越多样,更多内容见第七章)。
    系统消息说,你是一个说话像莎士比亚的助手。这是我们向助手描述它应该如何表现的方式。然后,第一个用户消息是给我讲个笑话。接下来以助手身份给出回复是,为什么鸡会过马路? 最后发送用户消息是我不知道。

            List<ChatMessage> chatMessages = new ArrayList<>();
    
            ChatMessage  message = new ChatMessage();
            message.setRole("system");
            message.setContent("你是一个像莎士比亚一样说话的助手。");
            chatMessages.add(message);
    
            ChatMessage  message1 = new ChatMessage();
            message1.setRole("user");
            message1.setContent("给我讲个笑话");
            chatMessages.add(message1);
    
            ChatMessage  message2 = new ChatMessage();
            message2.setRole("assistant");
            message2.setContent("鸡为什么过马路");
            chatMessages.add(message2);
    
            ChatMessage  message3 = new ChatMessage();
            message3.setRole("user");
            message3.setContent("我不知道");
            chatMessages.add(message3);
    
    
            String result = this.getCompletionFromMessage(chatMessages, 1.5d);
    
            log.info("iterative1:\n{}", result);
    
    
    • 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
    因为它想躲过汤锅! 这个笑话有些“愚蠢”,与幽默玩了一个常见的危险情境,引起一些意外,以尽力让人们笑一笑。这种类型的笑话强调了荒诞和意想不到的情节。
    
    • 1

    让我们看另一个例子。助手的消息是你是一个友好的聊天机器人,第一个用户消息是嗨,我叫Isa。我们想要得到第一个用户消息。

            List<ChatMessage> chatMessages = new ArrayList<>();
    
            ChatMessage  message = new ChatMessage();
            message.setRole("system");
            message.setContent("你是个友好的聊天机器人。");
            chatMessages.add(message);
    
            ChatMessage  message1 = new ChatMessage();
            message1.setRole("user");
            message1.setContent("Hi, 我是Isa。");
            chatMessages.add(message1);
    
    
            String result = this.getCompletionFromMessage(chatMessages, 1.5d);
    
            log.info("iterative2:\n{}", result);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    嗨Isa,很高兴认识你!有什么我可以帮助你的吗?
    
    • 1

    让我们再试一个例子。系统消息是,你是一个友好的聊天机器人,第一个用户消息是,是的,你能提醒我我的名字是什么吗?

            List<ChatMessage> chatMessages = new ArrayList<>();
    
            ChatMessage  message = new ChatMessage();
            message.setRole("system");
            message.setContent("你是个友好的聊天机器人。");
            chatMessages.add(message);
    
            ChatMessage  message1 = new ChatMessage();
            message1.setRole("user");
            message1.setContent("好,你能提醒我,我的名字是什么吗?");
            chatMessages.add(message1);
    
    
            String result = this.getCompletionFromMessage(chatMessages, 1.5d);
    
            log.info("iterative3:\n{}", result);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    当然可以!请告诉我你的名字,我将会一直记得。
    
    • 1

    如上所见,模型实际上并不知道我的名字。

    因此,每次与语言模型的交互都互相独立,这意味着我们必须提供所有相关的消息,以便模型在当前对话中进行引用。如果想让模型引用或 “记住” 对话的早期部分,则必须在模型的输入中提供早期的交流。我们将其称为上下文 (context) 。尝试以下示例。

            List<ChatMessage> chatMessages = new ArrayList<>();
    
            ChatMessage  message = new ChatMessage();
            message.setRole("system");
            message.setContent("你是个友好的聊天机器人。");
            chatMessages.add(message);
    
            ChatMessage  message1 = new ChatMessage();
            message1.setRole("user");
            message1.setContent("Hi, 我是Isa");
            chatMessages.add(message1);
    
            ChatMessage  message2 = new ChatMessage();
            message2.setRole("assistant");
            message2.setContent("Hi Isa! 很高兴认识你。今天有什么可以帮到你的吗?");
            chatMessages.add(message2);
    
            ChatMessage  message3 = new ChatMessage();
            message3.setRole("user");
            message3.setContent("是的,你可以提醒我, 我的名字是什么?");
            chatMessages.add(message3);
    
    
            String result = this.getCompletionFromMessage(chatMessages, 1.5d);
    
            log.info("iterative4:\n{}", result);
    
    
    • 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
    当然,Isa,你的名字是Isa。请问有什么具体的提醒需要我帮助你吗?
    
    • 1

    现在我们已经给模型提供了上下文,也就是之前的对话中提到的我的名字,然后我们会问同样的问题,也就是我的名字是什么。因为模型有了需要的全部上下文,所以它能够做出回应,就像我们在输入的消息列表中看到的一样。

    订餐机器人

    现在,我们构建一个 “订餐机器人”,我们需要它自动收集用户信息,接受比萨饼店的订单。

    下面这个函数将收集我们的用户消息,以便我们可以避免像刚才一样手动输入。这个函数将从我们下面构建的用户界面中收集 Prompt ,然后将其附加到一个名为上下文( context )的列表中,并在每次调用模型时使用该上下文。
    模型的响应也会添加到上下文中,所以用户消息和模型消息都被添加到上下文中,上下文逐渐变长。这样,模型就有了需要的信息来确定下一步要做什么。

    
    
    
    • 1
    • 2

    现在,我们将设置并运行这个 UI 来显示订单机器人。初始的上下文包含了包含菜单的系统消息,在每次调用时都会使用。此后随着对话进行,上下文也会不断增长。

    Java快速转换到大模型开发:
    配套课程的所有代码已经发布在:https://github.com/Starcloud-Cloud/java-langchain
    课程合作请留言

  • 相关阅读:
    [python][flask] Flask 入门(以一个博客后台为例)
    Flink DataStream 作业调优
    D - Square Permutation-AtCoder Beginner Contest 324
    pivot转换表
    drf_day04
    软件项目管理==风险计划
    前端--CSS
    单词记忆系统三:优化音标输入(允许键盘字符直接输入和音标序号混合输入)
    git容易出问题的命令
    VM虚拟机 13.5 for Mac
  • 原文地址:https://blog.csdn.net/df007df/article/details/133499169