AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


使用 LangChain 构建一个有记忆的聊天机器人
发布日期:2024-11-10 15:02:42 浏览次数: 1610 来源:PyTorch研习社



我们将介绍一个如何设计和实现 LLM 驱动的聊天机器人的示例。这个聊天机器人将能够进行对话并记住之前的交互。

请注意,我们构建的这个聊天机器人将仅使用语言模型进行对话。


如果没有记忆会怎么样? 





我们可以看到,它没有将之前的对话转为上下文,也无法回答问题。这给聊天机器人带来了糟糕的用户体验!


为了解决这个问题,我们需要将整个对话历史记录传递到模型中。让我们看看当我们这样做时会发生什么:

现在我们可以看到我们得到了很好的回应!


这是聊天机器人对话式互动能力的基本理念。那么我们如何才能最好地实现这一点呢?



保存消息历史记录




LangGraph 实现了内置持久层,使其成为支持多轮对话的聊天应用程序的理想选择。


将我们的聊天模型包装在最小的 LangGraph 应用程序中,使我们能够自动保存消息历史记录,从而简化多轮对话应用程序的开发。


LangGraph 附带一个简单的内存检查点,我们将在下面使用它。


现在我们需要创建一个 config,每次将其传递给可运行程序。此 config 包含不直接属于输入但仍然有用的信息。在本例中,我们希望包含一个 thread_id。它应该如下所示:


这使我们能够使用单个应用程序支持多个对话线程,这是应用程序有多个用户时的常见要求。


然后我们可以调用该应用程序:


太棒了!我们的聊天机器人现在可以记住我们的聊天记录了。如果我们更改配置以引用不同的 thread_id,我们可以看到它会重新开始对话。


但是,我们总是可以回到原始对话(因为我们将其保存在内存中,以后也可以保存在 Postgres 这样的数据库中):


这就是我们如何支持聊天机器人与许多用户进行对话!


对于异步支持,将 call_model 节点更新为异步函数,并在调用应用程序时使用 .ainvoke:


现在,我们所做的只是在模型周围添加了一个简单的持久层。我们可以通过添加提示模板来开始让聊天机器人变得更加复杂和个性化。



提示模板




你可以参考LangChain 中的 Prompt Template(提示模板)学习一下。


提示模板有助于将原始用户信息转换为 LLM 可以使用的格式。在这种情况下,原始用户输入只是一条消息,我们将它传递给 LLM。现在让我们让它更复杂一点。首先,让我们添加一条带有一些自定义指令的系统消息(但仍然将消息作为输入)。接下来,除了消息之外,我们还将添加更多输入。


要添加系统消息,我们将创建一个 ChatPromptTemplate。我们将利用 MessagesPlaceholder 传递所有消息。

我们现在可以更新我们的应用程序以包含此模板:

我们以同样的方式调用应用程序:

现在我们更改一下提示模板:


请注意,我们在提示中添加了新的语言输入。我们的应用程序现在有两个参数——输入 messages 和 language。我们应该更新应用程序的状态以反映这一点:


请看效果:

注意,整个 state(状态)是持久的,因此如果不需要更改,我们可以省略 language 等参数:



管理对话历史记录




构建聊天机器人时需要理解的一个重要概念是如何管理对话历史记录。如果不加以管理,消息列表将无限制地增长,并可能溢出 LLM 的上下文窗口。因此,添加一个限制传入消息大小的步骤非常重要。


重要的是,我们需要在提示模板之前,但要在从消息历史记录中加载以前的消息之后执行此操作。


我们可以通过在提示前面添加一个简单的步骤来适当修改 messages 键,然后将该新链包装在消息历史记录类中来实现这一点。


LangChain 附带一些用于管理消息列表的内置助手。在本例中,我们将使用 trim_messages 助手来减少我们发送给模型的消息数量。trim_messages 允许我们指定要保留多少个 token,以及其他参数,例如我们是否要始终保留系统消息以及是否允许部分消息:

注意!如果你不是用的 OpenAI 官方模型的话,可能就会报错:

那么你可能需要自己写一个计算 token 数量的方法。这计算结果可能不太准,但是多少有点作用:


现在我们再来试试:


为了在我们的链中使用它,我们只需要在将 messages 输入传递给我们的提示之前运行 trimmer。


现在,如果我们尝试询问模型我们的名字,它将不会知道,因为我们修剪了聊天记录的那部分:


但如果我们询问最近几条消息中的信息,它会记住:




流式输出




现在我们有一个可以运行的聊天机器人。但是,聊天机器人应用程序的一个非常重要的用户体验考虑因素是流式传输。LLM 有时可能需要一段时间才能响应,因此为了改善用户体验,大多数应用程序都会在生成每个 token 时将其流回。这允许用户查看进度。


其实这样做非常简单!


默认情况下,我们的 LangGraph 应用程序中的 .stream 会流式传输应用程序步骤 - 在本例中为模型响应的单个步骤。设置 stream_mode="messages" 允许我们改为流式传输输出 token:


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询