22. LangChain组件——memory长期会话记忆
1. 长期会话记忆实现的核心思想步骤?2. 代码实战
import os, json
from typing import Sequence
from langchain_community.chat_models import ChatTongyi
from langchain_core.messages import message_to_dict, messages_from_dict, BaseMessage
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableWithMessageHistory
from typing import List
# message_to_dict:单个消息对象(BaseMessage类实例) -> 字典
# messages_from_dict:[字典、字典...]-> [消息、消息...]
# AIMessage、HumanMessage、SystemMessage 都是BaseMessage的子类
class FileChatMessageHistory(BaseChatMessageHistory):
def __init__(self, session_id, storage_path):
self.session_id = session_id # 会话id
self.storage_path = r'E:\AI大模型RAG与智能体开发\P3_LangChainRAG开发\chat_history' # 不同会话id的存储文件,所在的文件夹路径 <b>(按情况改成自己的文件存储地址)</b>
# 完整的文件路径
self.file_path = os.path.join(self.storage_path, self.session_id)
print(self.file_path)
# 确保文件夹是存在的
os.makedirs(os.path.dirname(self.file_path), exist_ok=True)
def add_messages(self, messages: Sequence) -> None:
# Sequence序列 类似list、tuple
all_messages = list(self.messages) # 已有的消息列表
all_messages.extend(messages) # 新的和已有的融合成一个list
# 将数据同步写入到本地文件中
# 类对象写入文件 -> 一堆二进制
# 为了方便,可以将BaseMessage消息转为字典(借助json模块以json字符串写入文件)
# 官方message_to_dict:单个消息对象(BaseMessage类实例) -> 字典
# new_messages = []
# for message in all_messages:
# d = message_to_dict(message)
# new_messages.append(d)
new_messages =
# 将数据写入文件
with open(self.file_path, "w", encoding="utf-8") as f:
json.dump(new_messages, f)
@property # @property装饰器将messages方法变成成员属性用
def messages(self) -> List:
# 当前文件内: list[字典]
try:
with open(self.file_path, "r", encoding="utf-8") as f:
messages_data = json.load(f) # 返回值就是:list[字典]
return messages_from_dict(messages_data)
except FileNotFoundError:
return []
def clear(self) -> None:
with open(self.file_path, "w", encoding="utf-8") as f:
json.dump([], f)
model = ChatTongyi(model="qwen3-max")
# prompt = PromptTemplate.from_template(
# "你需要根据会话历史回应用户问题。对话历史:{chat_history},用户提问:{input},请回答"
# )
prompt = ChatPromptTemplate.from_messages(
[
("system", "你需要根据会话历史回应用户问题。对话历史:"),
MessagesPlaceholder("chat_history"),
("human", "请回答如下问题:{input}")
]
)
str_parser = StrOutputParser()
def print_prompt(full_prompt):
print("="*20, full_prompt.to_string(), "="*20)
return full_prompt
base_chain = prompt | print_prompt | model | str_parser
def get_history(session_id):
return FileChatMessageHistory(session_id, "./chat_history")
# 创建一个新的链,对原有链增强功能:自动附加历史消息
conversation_chain = RunnableWithMessageHistory(
base_chain, # 被增强的原有chain
get_history, # 通过会话id获取InMemoryChatMessageHistory类对象
input_messages_key="input", # 表示用户输入在模板中的占位符
history_messages_key="chat_history" # 表示用户输入在模板中的占位符
)
if __name__ == '__main__':
# 固定格式,添加LangChain的配置,为当前程序配置所属的session_id
session_config = {
"configurable": {
"session_id": "user_001"
}
}
res = conversation_chain.invoke({"input": "小明有2个猫"}, session_config)
print("第1次执行:", res)
res = conversation_chain.invoke({"input": "小刚有1只狗"}, session_config)
print("第2次执行:", res)
res = conversation_chain.invoke({"input": "总共有几个宠物"}, session_config)
print("第3次执行:", res)
学习视频:【黑马程序员大模型RAG与Agent智能体项目实战教程,基于主流的LangChain技术从大模型提示词到实战项目】https://www.bilibili.com/video/BV1yjz5BLEoY/?p=38&share_source=copy_web&vd_source=792a2cb63a1882bff4ed856eadc41a71]https://www.bilibili.com/video/BV1yjz5BLEoY/?p=38&share_source=copy_web&vd_source=792a2cb63a1882bff4ed856eadc41a71
【长期会话记忆实现的核心思想步骤】
长期会话记忆的核心思想是通过持久化存储来保存对话历史,主要分为三个步骤:
1. 历史消息的存储
- 将每次对话的消息(用户输入和AI回复)保存到外部存储(如文件、数据库)
- 每个会话有独立的存储标识(如session_id)
2. 历史消息的读取
- 每次新对话时,从存储中读取该会话的历史消息
- 将历史消息作为上下文输入给模型
3. 历史消息的管理
- 管理消息的添加、清理和更新
- 处理消息的序列化和反序列化(转换格式)
【代码实战填空】
以下是需要填写的代码部分:
1. 填空1(FileChatMessageHistory类的初始化方法):
self.storage_path = storage_path # 使用传入的存储路径
2. 填空2(add_messages方法的转换):
new_messages =
3. 填空3(messages方法的异常处理):
return [] # 返回空列表
4. 填空4(clear方法的清空操作):
json.dump([], f) # 写入空列表
5. 填空5(创建prompt模板):
[
("system", "你需要根据会话历史回应用户问题。"),
MessagesPlaceholder(variable_name="chat_history"),
("human", "{input}")
]
【完整代码说明】
这个示例展示了如何实现基于文件存储的长期会话记忆:
工作原理:
1. 每个用户会话(session_id)对应一个独立的文件
2. 每次对话时:
- 从文件读取历史消息
- 将历史消息和当前输入一起传给AI模型
- 将新的对话消息追加到文件中
关键组件:
- FileChatMessageHistory:自定义的存储类,继承自BaseChatMessageHistory
- RunnableWithMessageHistory:自动管理消息历史的链
- message_to_dict 和 messages_from_dict:消息格式转换工具
运行效果:
程序会保存对话历史,因此在第三次提问“总共有几个宠物”时,AI能基于前两次对话(2只猫+1只狗)正确回答“总共3个宠物”。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 学习 不二如是 发表于 2026-3-8 09:36
学习
{:13_450:} 糖逗 发表于 2026-3-8 09:44
加油!
页:
[1]