前言
上一篇学习了 LangChain 框架的基础知识和核心组件 Prompts 和 Chains,这篇文章将继续学习 LangChain 框架的核心组件 Memory(记忆)
记忆(Memory)
记忆(Memory)的作用就是在对话过程中,记录之前的对话历史,以便后续的对话可以基于之前的对话历史进行生成或回答
例如我们日常在豆包之类的应用中对话,它会记录之前的对话内容,并根据对话内容和之前的记录不断调整自己的回答
对话缓冲记忆(Conversation Buffer Memory)
类似微信的聊天记录,把每一句话都完整保存下来,什么时候想看都能翻到
例如下面创建对话历史后,将聊天内容都保存到了 chat_history 中
# 创建对话历史
chat_history = InMemoryChatMessageHistory()
# 添加对话历史
chat_history.add_user_message("你好")
chat_history.add_ai_message("你好!我是Qwen,很高兴见到你!")
chat_history.add_user_message("你叫什么名字?")
chat_history.add_ai_message("我是Qwen,一个由阿里云开发的大语言模型。")
查看的时候,遍历 chat_history.messages 打印出所有的对话历史
# 查看记忆中的对话历史
print("当前对话历史:")
for msg in chat_history.messages:
print(f"{type(msg).__name__}: {msg.content}")
对话窗口记忆(Conversation Buffer Window Memory)
对话窗口记忆是一种只保留最近N轮对话的记忆机制,就像一个只能装固定数量消息的"滑动窗口",当新的消息进来时,旧的消息会被挤出窗口,新的消息会进入窗口
这种方式的优势是有效控制内存,只记录最近的消息,更符合实际情况,处理消息数量固定,响应更快
如下面通过设置 window_size 为 4,就可以只保留最近的 2 轮对话(4 条消息)
def demo_conversation_window():
"""演示滑动窗口记忆"""
print("\n=== 滑动窗口记忆 ===")
# 创建对话历史
chat_history = InMemoryChatMessageHistory()
# 添加多轮对话
conversations = [
("我的名字是张三", "你好,张三!很高兴认识你。"),
("我今年25岁", "25岁是个很好的年纪!"),
("我住在北京", "北京是个美丽的城市!")
]
for user_msg, ai_msg in conversations:
chat_history.add_user_message(user_msg)
chat_history.add_ai_message(ai_msg)
# 实现滑动窗口 - 只保留最近的2轮对话(4条消息)
window_size = 4 # 2轮对话 = 4条消息
if len(chat_history.messages) > window_size:
# 保留最后window_size条消息
recent_messages = chat_history.messages[-window_size:]
chat_history.clear()
for msg in recent_messages:
if isinstance(msg, HumanMessage):
chat_history.add_user_message(msg.content)
else:
chat_history.add_ai_message(msg.content)
# 查看当前记忆中的对话(应该只保留最近2轮)
print("当前对话历史(滑动窗口):")
for msg in chat_history.messages:
print(f"{type(msg).__name__}: {msg.content}")
对话摘要记忆(Conversation Summary Memory)
对话摘要记忆是一种将长对话压缩成简洁摘要的记忆机制,就像给对话写"读书笔记"一样,只记录重要信息
def demo_conversation_summary():
"""演示对话摘要记忆"""
print("\n=== 对话摘要记忆 ===")
# 创建对话历史
chat_history = InMemoryChatMessageHistory()
# 添加多轮对话
conversations = [
("我最近在学习人工智能", "太棒了!人工智能是一个很有前景的领域。"),
("特别是大语言模型让我很感兴趣", "是的,大语言模型正在改变我们与技术交互的方式。")
]
for user_msg, ai_msg in conversations:
chat_history.add_user_message(user_msg)
chat_history.add_ai_message(ai_msg)
# 生成摘要
summary_prompt = ChatPromptTemplate.from_template(
"请总结以下对话的主要内容:\n{conversation}"
)
conversation_text = "\n".join([
f"用户: {msg.content}" if isinstance(msg, HumanMessage) else f"AI: {msg.content}"
for msg in chat_history.messages
])
summary_chain = summary_prompt | chat_llm | StrOutputParser()
summary = summary_chain.invoke({"conversation": conversation_text})
print(f"当前对话摘要: {summary}")
# 使用摘要进行对话
prompt = ChatPromptTemplate.from_messages([
("system", f"你是一个乐于助人的AI助手。以下是我们对话的摘要:{summary}"),
("human", "{input}"),
])
chain = prompt | chat_llm | StrOutputParser()
response = chain.invoke({"input": "我刚才提到了什么内容?"})
print(f"\nAI回复: {response}")
摘要记忆的流程:完整对话 → AI分析总结 → 简洁摘要 → 存储摘要
看下原始对话(长):
用户: 我最近在学习人工智能
AI: 太棒了!人工智能是一个很有前景的领域。
用户: 特别是大语言模型让我很感兴趣
AI: 是的,大语言模型正在改变我们与技术交互的方式。
生成的摘要(短)
用户最近开始学习人工智能,特别是对大语言模型很感兴趣。AI对此表示支持,并指出大语言模型在改变技术交互方式方面的重要性。
组合记忆(Combined Memory)
组合记忆是将滑动窗口记忆和对话摘要记忆结合起来,实现更灵活的记忆管理。就像同时拥有"详细日记"和"重点摘要"两种记录方式,既能保留详细的对话内容,又能快速总结重要信息
例如一个学习好的学生记笔记,详细记录每次学习内容,每个例子;总结学习的章节重点;专门记录学习中遇到的问题和解决方法等
例如下面的代码分别使用 conv_history 和 summary_history 来存储对话历史和摘要历史
def demo_combined_memory():
"""演示组合记忆"""
print("\n=== 组合记忆 ===")
# 创建不同类型的对话历史
conv_history = InMemoryChatMessageHistory()
summary_history = InMemoryChatMessageHistory()
# 添加对话
conversations = [
("我计划下周去上海旅游", "上海是个很棒的城市!"),
("有什么推荐的地方吗?", "外滩、东方明珠、城隍庙都很值得一去。")
]
for user_msg, ai_msg in conversations:
conv_history.add_user_message(user_msg)
conv_history.add_ai_message(ai_msg)
# 生成摘要
conversation_text = "\n".join([
f"用户: {msg.content}" if isinstance(msg, HumanMessage) else f"AI: {msg.content}"
for msg in conv_history.messages
])
summary_prompt = ChatPromptTemplate.from_template(
"请总结以下对话的主要内容:\n{conversation}"
)
summary_chain = summary_prompt | chat_llm | StrOutputParser()
summary = summary_chain.invoke({"conversation": conversation_text})
summary_history.add_ai_message(summary)
# 查看组合记忆
print("对话记忆内容:")
for msg in conv_history.messages:
print(f"{type(msg).__name__}: {msg.content}")
print(f"\n摘要记忆内容: {summary}")
组合记忆适合那种即需要详细记录有需要快速响应的场景,例如销售客服之类的,客户的问题需要及时响应,也需要详细记录聊天过程,用于后续的分析
小结
直接看官网文档相关内容看的云里雾里的,还是需要结合代码和实际例子去看,在本地运行代码看看输出结果,起码我们现在是日常经常用AI工具,结合日常使用中遇到的一些场景分析,相对会更好理解一点
AI转型长路漫漫,加油!