如何在LangChain的agent中记录对话历史

  在前两篇文章中,我分别实现了可以抓取并总结网页的agent和一个可以管理日程的agent,里面演示了基本agent创建和使用流程,也为agent添加了特殊的功能。但你仔细观察就会发现,我们的两个agent都是只支持单轮对话,也就是你之前和它说过什么,它不知道。 有些时候其实多轮对话的能力还是很重要的,比如在网页总结的agent中,如果它总结的格式不是我们想要的,我们就可以重新让他汇总整理下,显然这个功能在这里是不支持的。所以我们今天就来看下,如何让agent具备记忆的功能。

  LangChain在早期曾推迟过Memory模块,但Memory模块目前被官方标记为beta版本,说是并为这边好投入生产,而且也不支持最新的LCEL语法,但是ChatMessageHistory这个功能是个例外,它已经支持LCEL并且基本可以用在生产上了,所以我们今天说下如何使用ChatMessageHistory让我们的agent记录下对话历史,实现多轮对话。

  首先还是来创建基本的agent,这里我们就创建一个简单的对话agent,如果你想创建具备某些功能的复杂agent,可以参考我之前两篇实践文章 抓取并总结网页的agent,管理日程的agent。

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.runnables.history import RunnableWithMessageHistory,BaseChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_openai.chat_models import ChatOpenAIllm = ChatOpenAI(model="gpt-3.5-turbo", max_tokens=4096)
prompt = ChatPromptTemplate.from_messages([("system","你是一个智能聊天机器人,名字叫二狗,请用markdown格式回答任何问题",),MessagesPlaceholder(variable_name="history"),  ("human", "{input}"),]
)
chain = prompt | llm

  要注意的是,上面的prompt中必须要留下历史消息history的占位符,这样agent才能在每次调用llm的时候将历史消息传递过去。

  然后就是创建agent了,当然这里和普通的agent创是有区别的,需要通过RunnableWithMessageHistory()来创建,其中有个特殊的参数,就是需要传入一个能根据session_id获取历史信息的方法,这里我们就先用最简单纯内存的实现方式,完整的创建代码如下:

store = {}
def get_session_history(session_id: str) -> BaseChatMessageHistory:if session_id not in store:store[session_id] = ChatMessageHistory()return store[session_id]with_message_history = RunnableWithMessageHistory(chain,get_session_history,input_messages_key="input",history_messages_key="history",
)

  当然调用的agent时候,也需要新增一个config参数。


res = with_message_history.invoke({"input": "我刚说过什么??"},config={"configurable": {"session_id": "你的session_id"}}   # 主要是用来不同的聊天上下文 
)
res

  其中ChatMessageHistory是最基本的聊天历史记录实现,LangChain也提供很多具备持久化能力的实现,比如基于Redis的RedisChatMessageHistory……,具体可以看下官方文档https://python.langchain.com/v0.1/docs/integrations/memory/。

完整示例代码我已经放在github https://github.com/xindoo/langchain-examples/blob/main/history.ipynb,后续其他LangChain相关实践我会第一时间更新到github上,有兴趣可以关注下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/11056.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Midjourney与Stable Diffusion大比拼:AI绘画技术的未来

在当今快速发展的人工智能技术浪潮中,AI绘画软件成为了艺术和技术交汇的新领域。两大巨头——Midjourney和Stable Diffusion,在这一领域中引领风骚,它们以其独特的功能和强大的生成能力,让创作者能够将想象力化为现实。本文将深入…

进程与线程含义、区别及在操作系统中的意义(简要)

在现代操作系统中,进程和线程是构建多任务环境的基础。它们虽然紧密相关,但各自扮演着不同的角色。本文将深入探讨进程与线程的概念、它们之间的区别,以及为什么操作系统中会存在进程这一概念。 进程:独立运行的实体 它是操作系…

conan2 基础入门(04)-指定编译器(gcc为例)

conan2 基础入门(04)-指定编译器(gcc为例) 文章目录 conan2 基础入门(04)-指定编译器(gcc为例)⭐准备生成profile文件预备文件和Code ⭐使用指令预览正确执行结果可能出现的问题 ⭐具体讲解conancmake ENDsettings.yml ⭐准备 生成profile文件 # 生成默认profile文件&#xf…

国产操作系统下Chrome的命令行使用 _ 统信 _ 麒麟

原文链接:国产操作系统下Chrome的命令行使用 | 统信 | 麒麟 Hello,大家好啊!今天我们来聊聊如何在国产操作系统上使用命令行操作Google Chrome。无论是进行自动化测试、网页截图还是网页数据抓取,使用命令行操作Google Chrome都能…

Go编程语言的调试器Delve | Goland远程连接Linux开发调试(go远程开发)

文章目录 Go编程语言的调试器一、什么是Delve二、delve 安装安装报错cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in $PATH解决 三、delve命令行使用delve 常见的调试模式常用调试方法todo调试程序代码与动态库加载程序运行…

常用的简单友好的工单系统(免费)- WGCAT

最近在项目中,有工单系统的需求场景,所以想寻找一款轻量简单的运维工单软件,主要用来记录和处理工作中的一些故障、维护,主要用来记录设备的维护状态,包括服务器、主机、交换机那些 WGCAT,是一款简单轻量的…

Hive on Tez 作业优化参数

常用参数 参数名 参数说明 默认值 所在配置文件 关联问题 hive.tez.container.size Tez AppMaster向RM申请的container大小 -(单位:MB) hive-site.xml OOM tez.runtime.io.sort.mb 这个参数设定了 Tez 运行排序操作时可用的最大内存。排序操作的内存大小也会影响到排序的效率…

知从科技战略客户经理张志强受邀出席2024 AutoSec中国汽车网络安全与数据安全峰会

4月11-12日,AutoSec8周年年会暨中国汽车网络安全及数据安全合规峰会在上海成功举办。此次峰会吸引了来自全球各地的头部汽车网络安全企业、OEM厂商、安全专家和学者等齐聚盛会,零距离共话智能网联汽车产业的新发展、新趋势。 知从科技董事长成云霞亲自带…

mapreduce | 自定义Partition分区(案例1)

1.需求 将学生成绩,按照各个成绩降序排序,各个科目成绩单独输出。 # 自定义partition 将下面数据分区处理: 人名 科目 成绩 张三 语文 10 李四 数学 30 王五 语文 20 赵6 英语 40 张三 数据 50 李四 语文 10 张三 英语 70 李四 英语…

MapReduce | 二次排序

1.需求 主播数据--按照观众人数降序排序,如果观众人数相同,按照直播时长降序 # 案例数据 用户id 观众人数 直播时长 团团 300 1000 小黑 200 2000 哦吼 400 7000 卢本伟 100 6000 八戒 250 5000 悟空 100 4000 唐僧 100 3000 # 期望结果 哦吼 4…

ftp方式和http方式搭建云仓库

1.搭建阿里云仓库 国外云仓库比较慢,可以使用阿里云仓库代替 1.服务端和客户端切换到 yum.repo.d 目录 将自带的仓库移走 [rootlocalhost ~] cd /etc/yum.repos.d/ [rootlocalhost yum.repos.d] mkdir bak [rootlocalhost yum.repos.d] mv *.repo bak/ [rootloca…

字典是如何实现的?Rehash 了解吗?

字典是 Redis 服务器中出现最为频繁的复合型数据结构。除了 hash 结构的数据会用到字典外,整个 Redis 数据库的所有 key 和 value 也组成了一个 全局字典,还有带过期时间的 key 也是一个字典。(存储在 RedisDb 数据结构中) 字典结构是什么样的呢&#xf…

vue3 自定义国际化、elementPlus 国际化

自定义国际化 1. 引入 vue-i18n 插件 pnpm install vue-i18nnext 2. 页面添加语言文件目录,添加自定义的语言文件 3.语言目录里添加 index.ts, 内容如下 import { createI18n } from "vue-i18n";// 自定义语言文件 import zhCN from "…

【C/C++】内存分布

本文第一部分主要介绍了程序内存区域的划分以及数据的存储。第二部分有一段代码和一些题目,全面直观得分析了程序中的数组在内存中的存储。 因为不同的数据有不同的存储需求,各区域满足不同的需求,所以程序内存会有区域的划分。 根据需求的不…

通过pytest-xdist插件并发执行用例时, scope=session的fixture会运行多次问题的解决方案

场景 在UI自动化项目中,使用的是pytest playwright, 需要实现同一个用户只登录一次的,所以在conftest.py中定义了一个scopesession的fixture,然后在此fixture中实现了系统登录,在非并发模式下执行的时候,能保证同一个…

MFC重要的初始化函数InitInstance

MFC应用程序最早处理的类的初始化函数通常是CWinApp类的构造函数。CWinApp类是MFC应用程序的主类,负责整个应用程序的初始化和管理。 在MFC应用程序中,通常会创建一个派生自CWinApp类的应用程序类,例如CMyApp。在应用程序启动时,…

【力扣】第 396 场周赛 A~C

原题链接:竞赛 - 力扣 (LeetCode) 目录 A. 有效单词 B. K周期字符串需要的最少操作次数 C. 同位字符串连接的最小长度 (补题) A. 有效单词 根据题意模拟即可。 首先字符串长度小于3,直接return false; f1判断是否有元音字母…

开源模型应用落地-qwen模型小试-function call(十)

一、前言 每个模型都有自己的限制,有些情况下它们无法满足复杂的业务需求。但是,可以通过一个外置函数的方式,例如:"Function Call",让开发者能够更加灵活地利用大型语言模型,帮助开发者在特定场景下解决问题。 VS 开源模型应用落地-chatglm3-6b-function call…

Hive大表join大表如何调优

目录 一、调优思路1、SQL优化1.1 大小表join1.2 大大表join 2、insert into替换union all3、排序order by换位sort by4、并行执行5、数据倾斜优化6、小文件优化 二、实战2.1 场景2.2 限制所需的字段,间接mapjoin2.2 解决异常值倾斜,如NULL加随机数打散2.…

【CV】计算机视觉是什么?

计算机视觉是一门研究如何使机器“看”的学科,旨在实现从图像或视频中获取信息的技术和方法。它涵盖了图像处理、模式识别、机器学习等多个领域,是人工智能领域的重要分支之一。以下是计算机视觉的一般概要介绍: 概要介绍: 图像…