news 2026/4/22 1:57:04

LangChain构建聊天机器人-聊天记录保存

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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=用户,AIMessage=AI) # print(f"{type(message).__name__}: {message.content}")
(2)代码运行流程

1、准备阶段:导入工具 → 造一个“内存容器”(history),此时容器是空的;

2、第一轮聊天:

- 给容器加用户消息:“你是谁?”(容器里现在有1条消息:用户1);

- 调用大模型:大脑读取容器里的用户1消息,生成回应(比如“我是你的AI助手”),存到aimessage里;

- 打印回应:在屏幕上显示AI说的话;

- 保存AI回应:把aimessage(AI1)加到容器里(容器里现在有2条消息:用户1、AI1);

3、第二轮聊天:

- 给容器加用户消息:“请重复一次”(容器里现在有3条消息:用户1、AI1、用户2);

- 调用大模型:大脑读取容器里的3条消息,知道用户2是让重复AI1的话,所以生成重复的回应,存到aimessage2里;

- 打印回应:在屏幕上显示AI重复的话;

- 保存AI回应:把aimessage2(AI2)加到容器里(容器里现在有4条消息:用户1、AI1、用户2、AI2);

4、可选操作:打印容器里的所有消息,能清晰看到每一条聊天记录的类型和内容。

(3)局限性

这种“内存存储”的方式,最大的问题就是“临时存储”,就像我们在纸上写东西,一擦就没了:

- 只要你关闭运行代码的窗口、重启电脑,或者重新运行代码,这个“history容器”就会被重新创建,里面的所有聊天记录都会消失;

- 适合场景:调试代码(比如测试聊天逻辑对不对),不适合真正的使用(比如做一个能长期用的聊天机器人,用户下次打开还能看到之前的聊天记录)。

三、持久化存储:基于外部存储系统的扩展实现

既然内存存储“重启就忘”,那我们就用“外部存储系统”(比如 Redis、MongoDB)来保存聊天记录,实现“持久化存储”——不管你重启电脑、关闭窗口,聊天记录都能一直保存,下次打开还能读取。

LangChain 非常贴心,针对不同的外部存储系统,都提供了对应的“保存工具”(都是BaseChatMessageHistory的子类),而且用法和“内存存储”几乎一样,只要替换一下“容器”(history)的实现类,核心聊天逻辑完全不用改,也能轻松切换。

1. 目前支持的主流外部存储系统(了解即可,重点学Redis)

LangChain 支持很多外部存储系统,结合官方文档(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_id="Test", # 会话ID(非常重要!) # 作用:区分不同用户、不同会话的聊天记录,比如用户A的会话ID是"UserA",用户B的是"UserB" # 这样不同用户的聊天记录不会混乱,下次打开时,输入相同的session_id,就能加载之前的记录 url="redis://127.0.0.1:6380/0" # Redis 连接地址(重点看这里) # 解析:redis:// 是 Redis 的连接协议,127.0.0.1 是本地IP(自己电脑的IP),6380是Redis端口(如果你的Redis是默认端口6379,就改成6379) # 0 是 Redis 的数据库索引(Redis 有多个数据库,我们用第0个即可,不用改) ) # 第三步:配置大模型(机器人的大脑,重点看注释,可直接替换成自己的大模型) llm = ChatOpenAI( model="qwen-plus", # 大模型名称:阿里云百炼的“通义千问增强版”,基础版用"qwen-turbo"(更便宜) base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", # 阿里云百炼的API接口地址(固定不变,不用改) openai_api_key=load_key("BAILIAN_API_KEY"), # 加载 API 密钥(从配置文件读取,避免硬编码) # 补充:如果没有load_key函数,可直接替换成自己的API密钥,比如: # openai_api_key="你的API密钥字符串"(注意:不要泄露给别人) temperature=0.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 回应:把 aimessage(AI1)加到 Redis 容器里(此时 Redis 里有2条消息,永久保存);

4、第二轮聊天:

- 给 Redis 容器加用户消息:“请重复一次”(Redis 里现在有3条消息);

- 调用大模型:大脑读取 Redis 里的3条消息,知道用户让重复 AI1 的话,生成重复回应;

- 打印回应:显示 AI 重复的话;

- 保存 AI 回应:把 aimessage2(AI2)加到 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/v1):

4、学习建议:先把“内存存储”和“Redis 存储”的代码练熟,确保能成功运行、看到效果,再学习其他存储系统和自定义存储方式,循序渐进,不要急于求成。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 1:46:37

Transformer中跳过连接的作用与优化实践

1. 跳过连接在Transformer模型中的作用机制跳过连接(Skip Connection)最早出现在残差网络(ResNet)中,用于解决深度神经网络中的梯度消失问题。当这项技术被引入Transformer架构时,它带来了三个关键改进&…

作者头像 李华
网站建设 2026/4/22 1:38:58

虚拟助手如何重塑儿童人机交互与未来市场

1. 虚拟助手的崛起:从新奇玩具到家庭必需品1999年夏天,我拥有了人生第一部手机——Sagem RC 922。这部只能存储100个联系人、带着外置天线的设备,在诺基亚席卷市场的时代显得如此简陋。但正是这个只能打电话、发短信的"砖头"&#…

作者头像 李华