LangChain构建聊天机器人-聊天记录保存
一、核心技术知识点梳理1、什么是“存储系统”内存和外部存储的区别聊天记录存哪里1存储系统就是“保存数据的地方”比如我们电脑的“文件夹”本地存储、U盘外部存储还有示例中用到的 Redis、MongoDB都是“数据库”专门用来高效保存和读取数据。2内存临时存储相当于电脑的“临时记事本”用来存放正在使用的数据。比如我们打开一个文档文档内容会暂时存在内存里一旦关闭文档、重启电脑内存里的内容就没了对应 LangChain 中的InMemoryChatMessageHistory。3外部存储持久化存储相当于电脑的“硬盘”“U盘”用来永久保存数据。比如我们把文档保存到硬盘即使重启电脑文档还在对应 LangChain 中的 Redis、MongoDB、PostgreSQL 等。✅ 简单理解保存聊天记录用“内存”就是“临时记住”重启就忘用“外部存储”就是“永久记住”下次打开还能看到之前的聊天内容。2、保存聊天记录的核心意义聊天机器人保存聊天记录就像我们和朋友聊天时“记住之前说过的话”核心作用有两个非常好理解1、实现“多轮对话”比如你问机器人“你是谁”机器人回答“我是你的AI助手”然后你说“请重复一次”机器人能记住上一句的回答重复“我是你的AI助手”。如果不保存聊天记录机器人会忘记上一句不知道你让它“重复什么”。2、实现“聊天记录检索”比如你和机器人聊了很多内容后面想回顾“你之前说的某个知识点”机器人可以通过保存的聊天记录快速找到并回复你不用你重新输入。简单说不保存聊天记录机器人就是“健忘症”保存了机器人就是“有记忆的朋友”。二、LangChain 中聊天记录保存的核心类体系LangChain 为了让我们“快速保存聊天记录”提供了现成的“类模板”我们只要拿来用就好。核心分为“父类”和“子类”就像“动物”父类和“猫、狗”子类——猫和狗都有动物的基本特征会呼吸、会动还多了自己的专属特征猫会抓老鼠、狗会叫。1. 父类BaseChatMessageHistory所有保存方式的“基础模板”这个类是 LangChain 专门设计的“聊天记录保存基础模板”它定义了所有保存方式都要有的“基本功能”比如- 添加用户消息比如“你是谁”- 添加AI消息比如“我是你的AI助手”- 获取所有历史消息查看之前的聊天记录- 清空消息删除所有聊天记录✅ 简单理解这个父类就像“所有存储聊天记录工具的通用模板”后续不管是“内存保存”“Redis保存”“MongoDB保存”都是在这个模板的基础上增加了自己的“专属功能”比如 Redis 保存能“永久存储”内存保存只能“临时存储”。⚠️ 注意这个父类只是“模板”不能直接用就像“动物”这个模板不能直接拿来当宠物我们需要用它的“子类”具体的保存工具。2. 默认实现InMemoryChatMessageHistory内存存储这是 LangChain 默认提供的“聊天记录保存工具”是BaseChatMessageHistory的“子类”专门用来“临时保存聊天记录”优点是不用安装任何额外依赖拿来就能用适合入门调试比如测试聊天逻辑。1核心用法完整代码示例逐行拆解运行流程# 第一步导入“内存保存聊天记录”的工具从LangChain的核心模块里拿 # langchain_core.chat_history 是LangChain专门存放“聊天记录相关工具”的地方 # InMemoryChatMessageHistory 就是我们要用到的“内存保存工具” from langchain_core.chat_history import InMemoryChatMessageHistory # 第二步实例化工具造一个能保存聊天记录的“容器” # history 就是这个“容器”的名字我们后续所有的聊天记录操作都通过这个“容器”来做 # InMemoryChatMessageHistory() 就是“用内存保存模板造一个具体的容器” history InMemoryChatMessageHistory() # 第三步第一轮聊天完整流程用户发消息 → 机器人回应 → 保存回应 # 1. 给“容器”添加用户消息就是我们说的话 # add_user_message() 是“容器”的功能专门用来添加用户说的话 history.add_user_message(你是谁) # 括号里就是用户说的内容 # 2. 调用大模型机器人的大脑让它根据历史消息目前只有用户的“你是谁”生成回应 # llm 是我们之前配置好的“大模型对象”后面会讲怎么配置这里先知道它是“大脑”即可 # llm.invoke() 是“大脑”的功能专门用来接收指令、生成回应 # history.messages 是“容器”里的所有历史消息目前只有用户的消息 aimessage llm.invoke(history.messages) # 让大脑根据用户消息生成回应并存到aimessage里 # 3. 打印AI的回应看看机器人说了什么 print(aimessage.content) # aimessage.content 就是机器人回应的具体内容 # 4. 把机器人的回应也保存到“容器”里这样“容器”里就有用户和机器人的消息了 history.add_message(aimessage) # add_message() 可以添加任何消息用户/AI # 第四步第二轮聊天依赖上一轮的聊天记录体现“有记忆” # 1. 给“容器”添加用户的第二次消息“请重复一次” history.add_user_message(请重复一次) # 此时“容器”里已有用户1、AI1的消息 # 2. 再次调用大模型此时大脑会读取“容器”里的所有历史消息用户1、AI1 # 所以大脑知道用户让“重复”的是上一轮AI说的话 aimessage2 llm.invoke(history.messages) # 3. 打印第二轮AI的回应应该是重复上一轮的回答 print(aimessage2.content) # 4. 把第二轮AI的回应也保存到“容器”里 history.add_message(aimessage2) # 第五步可选操作打印所有历史聊天记录看看“容器”里存了什么方便调试 # 注释掉的代码取消注释删除前面的#就能运行 # print(Chat History:) # 打印“聊天记录”这几个字方便区分 # for message in history.messages: # 循环遍历“容器”里的所有消息 # # 打印消息类型是用户发的还是AI发的和消息内容 # # type(message).__name__ 能显示消息类型比如HumanMessage用户AIMessageAI # print(f{type(message).__name__}: {message.content})2代码运行流程1、准备阶段导入工具 → 造一个“内存容器”history此时容器是空的2、第一轮聊天- 给容器加用户消息“你是谁”容器里现在有1条消息用户1- 调用大模型大脑读取容器里的用户1消息生成回应比如“我是你的AI助手”存到aimessage里- 打印回应在屏幕上显示AI说的话- 保存AI回应把aimessageAI1加到容器里容器里现在有2条消息用户1、AI13、第二轮聊天- 给容器加用户消息“请重复一次”容器里现在有3条消息用户1、AI1、用户2- 调用大模型大脑读取容器里的3条消息知道用户2是让重复AI1的话所以生成重复的回应存到aimessage2里- 打印回应在屏幕上显示AI重复的话- 保存AI回应把aimessage2AI2加到容器里容器里现在有4条消息用户1、AI1、用户2、AI24、可选操作打印容器里的所有消息能清晰看到每一条聊天记录的类型和内容。3局限性这种“内存存储”的方式最大的问题就是“临时存储”就像我们在纸上写东西一擦就没了- 只要你关闭运行代码的窗口、重启电脑或者重新运行代码这个“history容器”就会被重新创建里面的所有聊天记录都会消失- 适合场景调试代码比如测试聊天逻辑对不对不适合真正的使用比如做一个能长期用的聊天机器人用户下次打开还能看到之前的聊天记录。三、持久化存储基于外部存储系统的扩展实现既然内存存储“重启就忘”那我们就用“外部存储系统”比如 Redis、MongoDB来保存聊天记录实现“持久化存储”——不管你重启电脑、关闭窗口聊天记录都能一直保存下次打开还能读取。LangChain 非常贴心针对不同的外部存储系统都提供了对应的“保存工具”都是BaseChatMessageHistory的子类而且用法和“内存存储”几乎一样只要替换一下“容器”history的实现类核心聊天逻辑完全不用改也能轻松切换。1. 目前支持的主流外部存储系统了解即可重点学RedisLangChain 支持很多外部存储系统结合官方文档https://python.langchain.com/docs/integrations/memory/主流的有- Redis高性能、操作简单适合入门适合高频访问的场景比如聊天机器人- MongoDB适合存储结构化/半结构化的聊天记录支持复杂查询比如按时间筛选聊天记录- PostgreSQL适合需要“事务支持”的场景比如多个人同时聊天确保聊天记录不混乱数据一致性高- MySQL和 PostgreSQL 类似也是关系型数据库适合有数据库基础的。✅ 建议先学 Redis操作最简单容易上手学会后再学其他存储系统逻辑都差不多。2. 重点示例基于 Redis 实现聊天记录持久化手把手教学Redis 是一款“高性能的键值对存储系统”可以理解为“一个专门用来快速保存和读取数据的工具”我们用它来保存聊天记录既能实现“永久存储”又能快速读取非常适合聊天机器人。下面从“前置准备”到“代码运行”逐步拆解跟着做就能成功。1前置准备3步缺一不可必做第一步安装 Redis 服务相当于“安装一个能永久保存数据的容器”第二步安装 Redis 相关依赖包让 Python 代码能“认识”Redis第三步准备 API 密钥大模型的“通行证”2完整代码实现兼容新版 LangChain 逐行拆解 运行流程# 第一步导入所需模块不用记直接复制即可后面解释每个模块的作用 # 1. 导入 Redis 聊天记录保存工具LangChain 专门为 Redis 设计的工具 from langchain_community.chat_message_histories import RedisChatMessageHistory # 2. 导入 OpenAI 风格的大模型调用工具用来调用阿里云百炼、OpenAI 等大模型 from langchain_openai import ChatOpenAI # 3. 导入加载 API 密钥的函数自己写的用来读取保存好的 API 密钥避免硬编码 # 注意如果你没有这个函数可以自己简单写一个后面会补充示例 from config.load_key import load_key # 第二步实例化 Redis 聊天记录容器造一个能永久保存聊天记录的“容器” # history 就是这个容器的名字和内存存储的容器名字一样后续操作也一样 history RedisChatMessageHistory( session_idTest, # 会话ID非常重要 # 作用区分不同用户、不同会话的聊天记录比如用户A的会话ID是UserA用户B的是UserB # 这样不同用户的聊天记录不会混乱下次打开时输入相同的session_id就能加载之前的记录 urlredis://127.0.0.1:6380/0 # Redis 连接地址重点看这里 # 解析redis:// 是 Redis 的连接协议127.0.0.1 是本地IP自己电脑的IP6380是Redis端口如果你的Redis是默认端口6379就改成6379 # 0 是 Redis 的数据库索引Redis 有多个数据库我们用第0个即可不用改 ) # 第三步配置大模型机器人的大脑重点看注释可直接替换成自己的大模型 llm ChatOpenAI( modelqwen-plus, # 大模型名称阿里云百炼的“通义千问增强版”基础版用qwen-turbo更便宜 base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1, # 阿里云百炼的API接口地址固定不变不用改 openai_api_keyload_key(BAILIAN_API_KEY), # 加载 API 密钥从配置文件读取避免硬编码 # 补充如果没有load_key函数可直接替换成自己的API密钥比如 # openai_api_key你的API密钥字符串注意不要泄露给别人 temperature0.0 # 温度参数必看 # 作用控制AI回应的随机性0表示完全不随机回应最稳定每次回答都一样 # 1表示完全随机回应可能不一样建议设为0方便调试 ) # 第四步核心聊天逻辑和内存存储的逻辑完全一样不用改任何代码 # 第一轮聊天 history.add_user_message(你是谁) # 给Redis容器添加用户消息 # 调用大模型大脑读取Redis容器里的历史消息首次为空生成回应 aimessage llm.invoke(history.messages) print(AI, aimessage.content) # 打印AI回应 history.add_message(aimessage) # 把AI回应保存到Redis永久保存 # 第二轮聊天依赖上一轮的历史记录体现“永久记忆” history.add_user_message(请重复一次) # 给Redis容器添加第二次用户消息 # 调用大模型大脑读取Redis容器里的所有历史消息用户1、AI1生成重复回应 aimessage2 llm.invoke(history.messages) print(AI, aimessage2.content) # 打印AI回应 history.add_message(aimessage2) # 把第二次AI回应保存到Redis永久保存3代码运行流程逐步理解知道每一步做了什么1、准备阶段导入工具 → 实例化 Redis 容器history此时 Redis 容器是空的因为是第一次运行2、配置大模型告诉代码“用哪个大脑”阿里云百炼 qwen-plus、“怎么连接大脑”base_url、“通行证是什么”API密钥3、第一轮聊天- 给 Redis 容器加用户消息“你是谁”此时 Redis 里会保存这条消息永久有效- 调用大模型大脑读取 Redis 容器里的用户1消息生成回应比如“我是你的AI助手”存到 aimessage 里- 打印回应在屏幕上显示 AI 说的话- 保存 AI 回应把 aimessageAI1加到 Redis 容器里此时 Redis 里有2条消息永久保存4、第二轮聊天- 给 Redis 容器加用户消息“请重复一次”Redis 里现在有3条消息- 调用大模型大脑读取 Redis 里的3条消息知道用户让重复 AI1 的话生成重复回应- 打印回应显示 AI 重复的话- 保存 AI 回应把 aimessage2AI2加到 Redis 里此时 Redis 里有4条消息永久保存5、 验证“永久存储”关闭运行代码的窗口、关闭 Redis 服务双击 redis-server.exe 打开的黑色窗口然后重新启动 Redis 服务重新运行代码注意session_id 要和之前一样还是“Test”此时代码会自动从 Redis 里加载之前的4条聊天记录你再输入“请重复一次”AI 依然能记住上一轮的内容。四、扩展自定义存储方式继承 BaseChatMessageHistory如果 LangChain 提供的存储方式内存、Redis、MongoDB 等都满足不了你的需求比如你想把聊天记录保存到本地文件夹的 txt 文件里LangChain 支持你“自己造一个保存工具”核心就是“继承 BaseChatMessageHistory 父类重写它的方法”。✅ 简单理解就像“动物”父类有“会呼吸”“会动”的方法你造一个“外星动物”子类可以重写“会呼吸”的方法比如用氧气呼吸改成用氮气呼吸同时保留“会动”的方法。具体实现方法1、 打开BaseChatMessageHistory的源码用 Python 开发工具比如 PyCharm找到这个类双击打开2、源码注释里会演示“如何扩展一个基于文件保存消息的实现类”核心是重写3个方法-add_message(self, message)重写“添加消息”的逻辑比如把消息写到 txt 文件里-get_messages(self)重写“获取消息”的逻辑比如从 txt 文件里读取消息-clear(self)重写“清空消息”的逻辑比如删除 txt 文件里的内容。五、补充说明必看汇总重点1、LangChain 生态非常强大官方文档显示有 1000 集成包括各种大模型、存储系统、工具等Redis、MongoDB、PostgreSQL 等存储系统都有官方扩展包不用自己从零开发安装依赖、替换实现类即可使用。2、不同存储系统的选择3、关于阿里云百炼 API 接口https://dashscope.aliyuncs.com/compatible-mode/v14、学习建议先把“内存存储”和“Redis 存储”的代码练熟确保能成功运行、看到效果再学习其他存储系统和自定义存储方式循序渐进不要急于求成。