LangChain-之--Memory
Memory 基础概念与应用 Memory是LangChain中存储对话历史与状态的核心组件,主要功能包括: 上下文维护:在多轮对话中保持连贯性 状态管理:记录任务执行进度和中间结果 个性化服务:存储用户偏好实现定制响应 核心操作包括: 通过save_context()保存对话记录 使用load_memory_variables()读取历史信息 调用clear()清除过期数据 典型应用场景: 个性
Memory 基础概念
概述
Memory(记忆)是 LangChain 中用于存储和管理对话历史及状态信息的组件。它使得语言模型能够在多次交互中保持上下文,从而提供更加连贯和个性化的用户体验。
核心概念
什么是 Memory?
Memory 是 LangChain 中的一个抽象概念,用于存储对话历史、用户偏好、中间状态等信息。它允许应用程序在不同的交互之间保持一致性。
为什么需要 Memory?
- 上下文保持: 在多轮对话中维持话题连贯性
- 个性化体验: 根据用户历史行为提供定制化响应
- 状态管理: 跟踪任务执行状态和中间结果
- 知识累积: 积累和利用历史信息优化后续交互
Memory 的工作原理
基本架构
Memory 系统通常包含以下几个核心组件:
- 存储机制: 实际存储数据的方式(内存、数据库等)
- 加载逻辑: 如何从存储中检索相关信息
- 保存逻辑: 如何将新信息保存到存储中
- 清理策略: 何时以及如何清理过期信息
数据流示例
用户输入 → Chain/Agent → Memory保存 → 下次交互时Memory加载 → Chain/Agent处理
Memory 的基本操作
1. 保存信息
from langchain.memory import ConversationBufferMemory
# 创建记忆实例
memory = ConversationBufferMemory()
# 保存人类消息
memory.save_context({"input": "你好"}, {"output": "你好!有什么可以帮助你的吗?"})
# 保存AI消息
memory.save_context({"input": "今天天气怎么样?"}, {"output": "我无法获取实时天气信息,建议你查看天气应用。"})
2. 加载信息
# 加载记忆中的历史记录
history = memory.load_memory_variables({})
print(history)
# 输出: {'history': 'Human: 你好\nAI: 你好!有什么可以帮助你的吗?\nHuman: 今天天气怎么样?\nAI: 我无法获取实时天气信息,建议你查看天气应用。'}
3. 清理信息
# 清空记忆
memory.clear()
Memory 与 Chains 的集成
在 LLMChain 中使用 Memory
from langchain_openai import OpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
# 创建提示词模板
template = """你是一个友好的助手,会记住之前的对话。
对话历史:
{history}
人类: {human_input}
助手:"""
prompt = PromptTemplate(
input_variables=["history", "human_input"],
template=template
)
# 创建记忆
memory = ConversationBufferMemory()
# 创建链
llm = OpenAI(temperature=0.7)
chain = LLMChain(
llm=llm,
prompt=prompt,
memory=memory,
verbose=True
)
# 使用链进行对话
# response1 = chain.run(human_input="我叫小明")
# response2 = chain.run(human_input="我刚才说了什么?")
Memory 与 Agents 的集成
在 Agent 中使用 Memory
from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory
# 创建记忆
memory = ConversationBufferMemory(memory_key="chat_history")
# 创建 Agent
llm = ChatOpenAI(temperature=0.7)
agent = initialize_agent(
tools=[], # 可以添加工具
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=memory,
verbose=True
)
# 使用 Agent 进行对话
# response1 = agent.run("我最喜欢的编程语言是 Python")
# response2 = agent.run("我刚才说了我最喜欢的编程语言是什么?")
Memory 的配置选项
基本配置参数
from langchain.memory import ConversationBufferMemory
# 基本配置
memory = ConversationBufferMemory(
memory_key="chat_history", # 记忆键名
input_key="input", # 输入键名
output_key="output", # 输出键名
return_messages=False # 是否返回消息对象而不是字符串
)
高级配置选项
# 配置返回消息对象
memory_with_messages = ConversationBufferMemory(
return_messages=True, # 返回消息对象列表
output_key="output" # 指定输出键
)
# 配置自定义键名
custom_memory = ConversationBufferMemory(
memory_key="conversation", # 自定义记忆键名
input_key="user_message", # 自定义输入键名
output_key="ai_response" # 自定义输出键名
)
实际应用场景
1. 个性化聊天机器人
from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
# 创建带记忆的对话链
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory()
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# 模拟多轮对话
# response1 = conversation.predict(input="你好,我叫小红")
# response2 = conversation.predict(input="我喜欢画画和音乐")
# response3 = conversation.predict(input="你还记得我的名字吗?")
2. 任务状态跟踪
from langchain.memory import ConversationBufferMemory
# 创建任务跟踪记忆
task_memory = ConversationBufferMemory(
memory_key="task_history"
)
# 保存任务状态
task_memory.save_context(
{"input": "开始任务"},
{"output": "任务已启动,当前进度0%"}
)
task_memory.save_context(
{"input": "执行步骤1"},
{"output": "步骤1完成,当前进度30%"}
)
# 查看任务历史
task_history = task_memory.load_memory_variables({})
print(task_history)
3. 用户偏好存储
from langchain.memory import ConversationBufferMemory
# 创建用户偏好记忆
preference_memory = ConversationBufferMemory(
memory_key="user_preferences"
)
# 保存用户偏好
preference_memory.save_context(
{"input": "用户偏好设置"},
{"output": "偏好已记录:喜欢科技新闻,偏爱简洁回答"}
)
# 在后续交互中使用偏好信息
preferences = preference_memory.load_memory_variables({})
print(preferences)
Memory 的最佳实践
1. 合理选择记忆类型
# 根据使用场景选择合适的记忆类型
from langchain.memory import (
ConversationBufferMemory,
ConversationSummaryMemory,
ConversationBufferWindowMemory
)
# 短对话使用缓冲记忆
short_conversation_memory = ConversationBufferMemory()
# 长对话使用摘要记忆
long_conversation_memory = ConversationSummaryMemory(
llm=ChatOpenAI(temperature=0.3)
)
# 有限窗口使用窗口记忆
window_memory = ConversationBufferWindowMemory(k=5)
2. 内存管理
# 定期清理过期记忆
class ManagedMemory:
"""带管理功能的记忆系统"""
def __init__(self, memory, max_entries=100):
self.memory = memory
self.max_entries = max_entries
def save_context(self, inputs, outputs):
"""保存上下文并管理大小"""
self.memory.save_context(inputs, outputs)
# 检查并清理过期记忆
self._manage_memory_size()
def _manage_memory_size(self):
"""管理记忆大小"""
# 实现记忆清理逻辑
pass
# 使用管理记忆
# managed_memory = ManagedMemory(ConversationBufferMemory())
3. 错误处理
from langchain.memory import ConversationBufferMemory
class RobustMemory:
"""健壮的记忆系统"""
def __init__(self):
self.memory = ConversationBufferMemory()
def safe_save_context(self, inputs, outputs):
"""安全保存上下文"""
try:
self.memory.save_context(inputs, outputs)
except Exception as e:
print(f"保存记忆时出错: {e}")
def safe_load_memory(self):
"""安全加载记忆"""
try:
return self.memory.load_memory_variables({})
except Exception as e:
print(f"加载记忆时出错: {e}")
return {}
# 使用健壮记忆
# robust_memory = RobustMemory()
# robust_memory.safe_save_context({"input": "测试"}, {"output": "结果"})
# history = robust_memory.safe_load_memory()
总结
Memory 是 LangChain 中实现连贯对话和状态管理的关键组件。通过合理使用和配置 Memory,我们可以创建出更加智能和用户友好的应用程序。关键要点包括:
- 理解 Memory 的基本概念和工作原理
- 根据使用场景选择合适的记忆类型
- 正确配置记忆参数以满足应用需求
- 实现适当的错误处理和内存管理
- 在 Chains 和 Agents 中有效集成记忆系统
Memory 类型详解
概述
LangChain 提供了多种不同类型的 Memory,每种都有其特定的用途和优势。了解这些不同类型的特点和适用场景,可以帮助我们为应用程序选择最合适 的记忆系统。
主要记忆类型
1. ConversationBufferMemory (对话缓冲记忆)
特点
- 完整存储: 保存完整的对话历史
- 简单直接: 实现简单,易于理解和使用
- 内存密集: 随着对话增长,内存使用量线性增加
使用场景
- 短对话场景
- 需要完整历史记录的应用
- 简单的聊天机器人
使用示例
from langchain.memory import ConversationBufferMemory
# 创建对话缓冲记忆
memory = ConversationBufferMemory()
# 保存对话
memory.save_context({"input": "你好"}, {"output": "你好!有什么可以帮助你的吗?"})
memory.save_context({"input": "今天天气怎么样?"}, {"output": "我无法获取实时天气信息。"})
# 加载记忆
history = memory.load_memory_variables({})
print(history)
# 输出完整的对话历史
配置选项
# 基本配置
basic_memory = ConversationBufferMemory(
memory_key="chat_history", # 记忆键名
input_key="input", # 输入键名
output_key="output" # 输出键名
)
# 返回消息对象
message_memory = ConversationBufferMemory(
return_messages=True # 返回消息对象列表
)
# 自定义键名
custom_memory = ConversationBufferMemory(
memory_key="conversation_history",
input_key="user_input",
output_key="ai_response"
)
2. ConversationBufferWindowMemory (对话窗口记忆)
特点
- 有限窗口: 只保存最近的K条消息
- 内存友好: 控制内存使用量
- 历史截断: 自动丢弃旧的对话历史
使用场景
- 长时间对话场景
- 内存资源有限的应用
- 只需要近期上下文的场景
使用示例
from langchain.memory import ConversationBufferWindowMemory
# 创建窗口记忆,只保存最近3条消息
window_memory = ConversationBufferWindowMemory(k=3)
# 保存多条消息
for i in range(5):
window_memory.save_context(
{"input": f"问题{i}"},
{"output": f"回答{i}"}
)
# 加载记忆(只会显示最近3条)
history = window_memory.load_memory_variables({})
print(history)
配置选项
# 配置窗口大小
window_memory = ConversationBufferWindowMemory(
k=5, # 保存最近5条消息
memory_key="recent_history", # 自定义键名
return_messages=True # 返回消息对象
)
3. ConversationSummaryMemory (对话摘要记忆)
特点
- 智能摘要: 使用LLM生成对话摘要
- 固定大小: 摘要大小相对固定
- 语义保持: 保留对话的主要语义信息
使用场景
- 非常长的对话历史
- 需要保持对话主旨的场景
- 内存严格受限的应用
使用示例
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
# 创建摘要记忆
summary_memory = ConversationSummaryMemory(
llm=ChatOpenAI(temperature=0.3),
memory_key="chat_summary"
)
# 保存多条对话
summary_memory.save_context(
{"input": "我想了解人工智能"},
{"output": "人工智能是计算机科学的一个分支..."}
)
summary_memory.save_context(
{"input": "它有哪些应用领域?"},
{"output": "人工智能广泛应用于医疗、金融、交通等领域..."}
)
# 加载摘要
summary = summary_memory.load_memory_variables({})
print(summary)
配置选项
# 配置摘要记忆
summary_memory = ConversationSummaryMemory(
llm=ChatOpenAI(temperature=0.3),
memory_key="conversation_summary",
input_key="user_input",
output_key="ai_output",
return_messages=False
)
4. ConversationSummaryBufferMemory (对话摘要缓冲记忆)
特点
- 混合模式: 结合缓冲和摘要的优点
- 近期完整: 保存近期完整对话
- 历史摘要: 对旧对话进行摘要
- 平衡性能: 在内存使用和信息保留之间取得平衡
使用场景
- 中等长度的对话历史
- 需要近期详细信息和历史概要的场景
- 平衡内存使用和信息完整性的应用
使用示例
from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI
# 创建摘要缓冲记忆
summary_buffer_memory = ConversationSummaryBufferMemory(
llm=ChatOpenAI(temperature=0.3),
max_token_limit=500 # 最大令牌限制
)
# 保存对话
for i in range(10):
summary_buffer_memory.save_context(
{"input": f"问题{i}"},
{"output": f"详细回答{i},包含很多信息..."}
)
# 加载记忆
memory_content = summary_buffer_memory.load_memory_variables({})
print(memory_content)
5. VectorStoreRetrieverMemory (向量存储检索记忆)
特点
- 向量检索: 使用向量存储和检索相关信息
- 语义搜索: 基于语义相似性检索记忆
- 可扩展性: 适合大规模记忆存储
使用场景
- 需要从大量历史中检索相关信息
- 基于内容相似性的记忆检索
- 知识库类型的对话系统
使用示例
from langchain.memory import VectorStoreRetrieverMemory
from langchain.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
# 注意:这需要额外的依赖
# pip install faiss-cpu
# 创建向量存储
# embedding = OpenAIEmbeddings()
# vectorstore = FAISS.from_texts(["初始文本"], embedding)
# retriever = vectorstore.as_retriever()
#
# # 创建向量检索记忆
# vector_memory = VectorStoreRetrieverMemory(retriever=retriever)
#
# # 添加记忆
# vector_memory.save_context(
# {"input": "重要信息"},
# {"output": "这是需要记住的重要信息"}
# )
特殊记忆类型
1. CombinedMemory (组合记忆)
特点
- 多重记忆: 同时使用多种记忆类型
- 灵活组合: 可以根据需要组合不同记忆
- 功能丰富: 提供更丰富的记忆管理功能
使用示例
from langchain.memory import CombinedMemory, ConversationBufferMemory, ConversationSummaryMemory
from langchain_openai import ChatOpenAI
# 创建不同类型的记忆
buffer_memory = ConversationBufferMemory(memory_key="chat_history")
summary_memory = ConversationSummaryMemory(
llm=ChatOpenAI(temperature=0.3),
memory_key="chat_summary"
)
# 组合记忆
combined_memory = CombinedMemory(memories=[buffer_memory, summary_memory])
# 使用组合记忆
combined_memory.save_context(
{"input": "你好"},
{"output": "你好!有什么可以帮助你的吗?"}
)
# 加载所有记忆
all_memories = combined_memory.load_memory_variables({})
print(all_memories)
2. ReadOnlySharedMemory (只读共享记忆)
特点
- 只读访问: 提供对其他记忆的只读访问
- 共享机制: 允许多个组件共享同一记忆
- 安全性: 防止意外修改共享记忆
使用示例
from langchain.memory import ConversationBufferMemory, ReadOnlySharedMemory
# 创建基础记忆
base_memory = ConversationBufferMemory()
# 创建只读共享记忆
readonly_memory = ReadOnlySharedMemory(memory=base_memory)
# 可以读取
history = readonly_memory.load_memory_variables({})
print(history)
# 但不能直接保存(需要通过基础记忆)
# readonly_memory.save_context(...) # 这会失败
记忆类型选择指南
选择标准
| 场景 | 推荐记忆类型 | 原因 |
|---|---|---|
| 短对话(<10轮) | ConversationBufferMemory | 简单直接,完整保留历史 |
| 中等对话(10-50轮) | ConversationBufferWindowMemory | 控制内存使用,保留近期历史 |
| 长对话(>50轮) | ConversationSummaryMemory | 固定内存使用,保持语义 |
| 复杂场景 | ConversationSummaryBufferMemory | 平衡近期细节和历史概要 |
| 知识检索 | VectorStoreRetrieverMemory | 基于语义的相关性检索 |
性能对比
import time
from langchain.memory import (
ConversationBufferMemory,
ConversationBufferWindowMemory,
ConversationSummaryMemory
)
from langchain_openai import ChatOpenAI
# 性能测试函数
def test_memory_performance(memory, rounds=100):
start_time = time.time()
for i in range(rounds):
memory.save_context(
{"input": f"测试问题{i}"},
{"output": f"测试回答{i}"}
)
end_time = time.time()
return end_time - start_time
# 测试不同记忆类型的性能
# buffer_time = test_memory_performance(ConversationBufferMemory())
# window_time = test_memory_performance(ConversationBufferWindowMemory(k=10))
# summary_time = test_memory_performance(
# ConversationSummaryMemory(llm=ChatOpenAI(temperature=0.3))
# )
# print(f"缓冲记忆时间: {buffer_time:.2f}秒")
# print(f"窗口记忆时间: {window_time:.2f}秒")
# print(f"摘要记忆时间: {summary_time:.2f}秒")
实际应用场景
1. 客服系统记忆管理
from langchain.memory import ConversationBufferWindowMemory
# 客服系统使用窗口记忆
customer_service_memory = ConversationBufferWindowMemory(
k=10, # 保存最近10轮对话
memory_key="service_history"
)
# 模拟客服对话
customer_service_memory.save_context(
{"input": "我的订单没有收到"},
{"output": "很抱歉听到这个问题,请提供您的订单号。"}
)
customer_service_memory.save_context(
{"input": "订单号是12345"},
{"output": "正在查询订单12345的状态..."}
)
2. 教育辅导系统
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
# 教育系统使用摘要记忆
tutor_memory = ConversationSummaryMemory(
llm=ChatOpenAI(temperature=0.3),
memory_key="learning_history"
)
# 保存学习过程
tutor_memory.save_context(
{"input": "请解释牛顿第一定律"},
{"output": "牛顿第一定律也称为惯性定律..."}
)
tutor_memory.save_context(
{"input": "能给我一个例子吗?"},
{"output": "比如汽车突然刹车时,乘客会向前倾..."}
)
3. 个人助手应用
from langchain.memory import CombinedMemory, ConversationBufferMemory, ConversationSummaryMemory
from langchain_openai import ChatOpenAI
# 个人助手使用组合记忆
# 近期详细记忆
recent_memory = ConversationBufferMemory(
memory_key="recent_conversation"
)
# 长期摘要记忆
long_term_memory = ConversationSummaryMemory(
llm=ChatOpenAI(temperature=0.3),
memory_key="conversation_summary"
)
# 组合记忆
personal_assistant_memory = CombinedMemory(
memories=[recent_memory, long_term_memory]
)
最佳实践
1. 记忆类型选择
def choose_memory_type(conversation_length, memory_limit, importance_of_details):
"""根据需求选择合适的记忆类型"""
if conversation_length < 10 and memory_limit == "unlimited":
return "ConversationBufferMemory"
elif conversation_length < 50 and memory_limit == "limited":
return "ConversationBufferWindowMemory"
elif conversation_length > 50 and importance_of_details == "low":
return "ConversationSummaryMemory"
else:
return "ConversationSummaryBufferMemory"
# 使用示例
recommended_memory = choose_memory_type(30, "limited", "medium")
print(f"推荐的记忆类型: {recommended_memory}")
2. 记忆清理策略
class ManagedMemory:
"""带管理功能的记忆系统"""
def __init__(self, memory, max_size=1000):
self.memory = memory
self.max_size = max_size
self.current_size = 0
def save_context(self, inputs, outputs):
"""保存上下文并管理大小"""
# 保存前检查大小
if self.current_size > self.max_size:
self._cleanup_memory()
self.memory.save_context(inputs, outputs)
self.current_size += 1
def _cleanup_memory(self):
"""清理记忆"""
# 实现清理逻辑
print("执行记忆清理")
3. 错误处理和恢复
from langchain.memory import ConversationBufferMemory
import logging
class RobustMemory:
"""健壮的记忆系统"""
def __init__(self):
self.memory = ConversationBufferMemory()
self.logger = logging.getLogger(__name__)
def safe_save_context(self, inputs, outputs):
"""安全保存上下文"""
try:
self.memory.save_context(inputs, outputs)
return True
except Exception as e:
self.logger.error(f"保存记忆失败: {e}")
return False
def safe_load_memory(self):
"""安全加载记忆"""
try:
return self.memory.load_memory_variables({})
except Exception as e:
self.logger.error(f"加载记忆失败: {e}")
return {"history": ""}
# 使用健壮记忆系统
# robust_memory = RobustMemory()
# success = robust_memory.safe_save_context({"input": "测试"}, {"output": "结果"})
# if success:
# history = robust_memory.safe_load_memory()
# print(history)
总结
LangChain 提供了丰富多样的记忆类型,每种都有其特定的用途和优势。选择合适的记忆类型对于构建高效、可靠的对话系统至关重要:
- 理解各种记忆类型的特点和适用场景
- 根据应用需求选择最合适的记忆类型
- 合理配置记忆参数以优化性能
- 实现适当的错误处理和内存管理
- 在必要时使用组合记忆来满足复杂需求
通过深入理解和正确使用这些记忆类型,我们可以构建出更加智能和用户友好的应用程序。
Memory 集成应用
概述
在实际应用中,Memory 需要与 Chains、Agents 等 LangChain 组件紧密集成,才能发挥其最大价值。本章将详细介绍如何在不同场景下有效地集成和使用 Memory 系统。
在 Chains 中集成 Memory
1. ConversationChain 集成
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
# 创建带记忆的对话链
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory()
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True
)
# 使用对话链
# response1 = conversation.predict(input="你好,我叫小明")
# response2 = conversation.predict(input="我刚才说了什么?")
# print(response2)
2. 自定义 Chain 中集成 Memory
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
from langchain_openai import ChatOpenAI
# 创建自定义提示词模板
template = """你是一个友好的助手,会记住之前的对话。
对话历史:
{chat_history}
用户: {user_input}
助手:"""
prompt = PromptTemplate(
input_variables=["chat_history", "user_input"],
template=template
)
# 创建带记忆的自定义链
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory(memory_key="chat_history")
custom_chain = LLMChain(
llm=llm,
prompt=prompt,
memory=memory,
verbose=True
)
# 使用自定义链
# result = custom_chain.run(user_input="我最喜欢的编程语言是 Python")
# result = custom_chain.run(user_input="我刚才说了什么?")
3. 复杂 Chain 中的 Memory 管理
from langchain.chains import SequentialChain
from langchain.memory import ConversationBufferMemory
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
# 创建多个链
llm = ChatOpenAI(temperature=0.7)
# 第一个链:理解用户需求
understand_template = PromptTemplate(
input_variables=["user_input", "conversation_history"],
template="基于对话历史理解用户需求:\n历史: {conversation_history}\n当前: {user_input}\n需求:"
)
understand_chain = LLMChain(
llm=llm,
prompt=understand_template,
output_key="understood_need"
)
# 第二个链:生成响应
respond_template = PromptTemplate(
input_variables=["understood_need"],
template="基于理解的需求生成友好响应:\n需求: {understood_need}\n响应:"
)
respond_chain = LLMChain(
llm=llm,
prompt=respond_template,
output_key="final_response"
)
# 创建共享记忆
shared_memory = ConversationBufferMemory(memory_key="conversation_history")
# 创建顺序链
sequential_chain = SequentialChain(
chains=[understand_chain, respond_chain],
input_variables=["user_input"],
output_variables=["final_response"],
memory=shared_memory,
verbose=True
)
# 使用顺序链
# result = sequential_chain({"user_input": "我想学习Python编程"})
# print(result["final_response"])
在 Agents 中集成 Memory
1. 基础 Agent Memory 集成
from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.tools import Tool
# 创建工具
def calculator_func(expression):
"""计算器工具"""
try:
result = eval(expression)
return str(result)
except:
return "计算出错"
calculator_tool = Tool(
name="Calculator",
func=calculator_func,
description="用于执行数学计算的工具"
)
# 创建带记忆的 Agent
llm = ChatOpenAI(temperature=0.7)
memory = ConversationBufferMemory(memory_key="chat_history")
agent = initialize_agent(
tools=[calculator_tool],
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=memory,
verbose=True
)
# 使用 Agent
# result = agent.run("我叫小红,15岁,计算一下我的年龄的平方")
# result = agent.run("我刚才说了我叫什么?")
2. 高级 Agent Memory 配置
from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationSummaryMemory
from langchain.tools import Tool
# 创建工具
def web_search(query):
"""网络搜索工具"""
return f"关于'{query}'的搜索结果显示:这是一个示例搜索结果。"
search_tool = Tool(
name="WebSearch",
func=web_search,
description="用于搜索网络信息的工具"
)
# 创建带摘要记忆的高级 Agent
llm = ChatOpenAI(temperature=0.3)
summary_memory = ConversationSummaryMemory(
llm=llm,
memory_key="chat_history",
input_key="input"
)
advanced_agent = initialize_agent(
tools=[search_tool],
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=summary_memory,
verbose=True,
max_iterations=5
)
# 使用高级 Agent
# result = advanced_agent.run("请搜索人工智能的最新发展")
# result = advanced_agent.run("刚才搜索了什么内容?")
3. 多 Agent 协作中的 Memory 共享
from langchain.agents import AgentType, initialize_agent
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.tools import Tool
# 创建共享记忆
shared_memory = ConversationBufferMemory(memory_key="shared_context")
# 创建多个 Agent
llm = ChatOpenAI(temperature=0.7)
# 技术专家 Agent
tech_expert = initialize_agent(
tools=[], # 技术相关工具
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=shared_memory,
verbose=True
)
# 商业专家 Agent
business_expert = initialize_agent(
tools=[], # 商业相关工具
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=shared_memory,
verbose=True
)
# 协调者 Agent
coordinator = initialize_agent(
tools=[], # 可以调用其他 Agent
llm=llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=shared_memory,
verbose=True
)
Memory 与外部系统的集成
1. 数据库存储集成
from langchain.memory import ConversationBufferMemory
import sqlite3
import json
class DatabaseMemory:
"""基于数据库的记忆系统"""
def __init__(self, db_path="memory.db"):
self.db_path = db_path
self._init_db()
def _init_db(self):
"""初始化数据库"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS conversations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT,
role TEXT,
content TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
def save_message(self, session_id, role, content):
"""保存消息到数据库"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute(
"INSERT INTO conversations (session_id, role, content) VALUES (?, ?, ?)",
(session_id, role, content)
)
conn.commit()
conn.close()
def load_conversation(self, session_id):
"""从数据库加载对话历史"""
conn = sqlite3.connect(self.db_path)
cursor = conn.cursor()
cursor.execute(
"SELECT role, content FROM conversations WHERE session_id = ? ORDER BY timestamp",
(session_id,)
)
messages = cursor.fetchall()
conn.close()
# 格式化为对话历史
history = ""
for role, content in messages:
history += f"{role}: {content}\n"
return history
# 使用数据库记忆
# db_memory = DatabaseMemory()
# db_memory.save_message("session_001", "Human", "你好")
# db_memory.save_message("session_001", "AI", "你好!有什么可以帮助你的吗?")
# history = db_memory.load_conversation("session_001")
# print(history)
2. Redis 缓存集成
# 注意:需要安装 redis
# pip install redis
import redis
import json
from langchain.memory import ConversationBufferMemory
class RedisMemory:
"""基于 Redis 的记忆系统"""
def __init__(self, host='localhost', port=6379, db=0):
self.redis_client = redis.Redis(host=host, port=port, db=db)
self.memory_key_prefix = "conversation:"
def save_context(self, session_id, inputs, outputs):
"""保存上下文到 Redis"""
key = f"{self.memory_key_prefix}{session_id}"
# 创建消息记录
message = {
"input": inputs.get("input", ""),
"output": outputs.get("output", ""),
"timestamp": __import__('time').time()
}
# 将消息添加到列表中
self.redis_client.lpush(key, json.dumps(message))
# 限制列表长度(只保留最近100条)
self.redis_client.ltrim(key, 0, 99)
def load_memory_variables(self, session_id):
"""从 Redis 加载记忆"""
key = f"{self.memory_key_prefix}{session_id}"
# 获取所有消息
messages = self.redis_client.lrange(key, 0, -1)
# 构建对话历史
history = ""
for message_json in reversed(messages): # 反向以获得正确顺序
message = json.loads(message_json)
history += f"Human: {message['input']}\nAI: {message['output']}\n"
return {"history": history}
def clear_session(self, session_id):
"""清空会话记忆"""
key = f"{self.memory_key_prefix}{session_id}"
self.redis_client.delete(key)
# 使用 Redis 记忆
# redis_memory = RedisMemory()
# redis_memory.save_context("session_001", {"input": "你好"}, {"output": "你好!"})
# memory_vars = redis_memory.load_memory_variables("session_001")
# print(memory_vars)
多用户记忆管理
1. 会话隔离
from langchain.memory import ConversationBufferMemory
from typing import Dict
class MultiUserMemoryManager:
"""多用户记忆管理器"""
def __init__(self):
self.user_memories: Dict[str, ConversationBufferMemory] = {}
def get_user_memory(self, user_id: str) -> ConversationBufferMemory:
"""获取用户记忆"""
if user_id not in self.user_memories:
self.user_memories[user_id] = ConversationBufferMemory(
memory_key=f"user_{user_id}_history"
)
return self.user_memories[user_id]
def save_user_context(self, user_id: str, inputs: dict, outputs: dict):
"""保存用户上下文"""
memory = self.get_user_memory(user_id)
memory.save_context(inputs, outputs)
def load_user_memory(self, user_id: str) -> dict:
"""加载用户记忆"""
memory = self.get_user_memory(user_id)
return memory.load_memory_variables({})
def clear_user_memory(self, user_id: str):
"""清空用户记忆"""
if user_id in self.user_memories:
self.user_memories[user_id].clear()
del self.user_memories[user_id]
# 使用多用户记忆管理器
# memory_manager = MultiUserMemoryManager()
# memory_manager.save_user_context("user_001", {"input": "你好"}, {"output": "你好!"})
# memory_manager.save_user_context("user_002", {"input": "Hi"}, {"output": "Hi there!"})
#
# user1_memory = memory_manager.load_user_memory("user_001")
# user2_memory = memory_manager.load_user_memory("user_002")
#
# print("用户1记忆:", user1_memory)
# print("用户2记忆:", user2_memory)
2. 用户记忆持久化
import json
import os
from langchain.memory import ConversationBufferMemory
class PersistentUserMemory:
"""持久化用户记忆"""
def __init__(self, storage_dir="./user_memories"):
self.storage_dir = storage_dir
os.makedirs(storage_dir, exist_ok=True)
def _get_memory_file_path(self, user_id: str) -> str:
"""获取用户记忆文件路径"""
return os.path.join(self.storage_dir, f"{user_id}_memory.json")
def save_user_memory(self, user_id: str, memory: ConversationBufferMemory):
"""保存用户记忆到文件"""
file_path = self._get_memory_file_path(user_id)
# 获取记忆内容
memory_content = memory.load_memory_variables({})
# 保存到文件
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(memory_content, f, ensure_ascii=False, indent=2)
def load_user_memory(self, user_id: str) -> ConversationBufferMemory:
"""从文件加载用户记忆"""
file_path = self._get_memory_file_path(user_id)
# 创建新的记忆实例
memory = ConversationBufferMemory()
# 如果文件存在,加载内容
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
memory_content = json.load(f)
# 这里需要根据具体实现恢复记忆状态
# 简化处理:直接设置历史
if "history" in memory_content:
# 注意:这只是一个示例,实际实现可能需要更复杂的逻辑
pass
return memory
def delete_user_memory(self, user_id: str):
"""删除用户记忆文件"""
file_path = self._get_memory_file_path(user_id)
if os.path.exists(file_path):
os.remove(file_path)
# 使用持久化用户记忆
# persistent_memory = PersistentUserMemory()
# user_memory = ConversationBufferMemory()
# user_memory.save_context({"input": "你好"}, {"output": "你好!"})
#
# # 保存记忆
# persistent_memory.save_user_memory("user_001", user_memory)
#
# # 加载记忆
# loaded_memory = persistent_memory.load_user_memory("user_001")
记忆的高级应用
1. 个性化记忆系统
from langchain.memory import ConversationBufferMemory
from typing import Dict, Any
import json
class PersonalizedMemory:
"""个性化记忆系统"""
def __init__(self, user_id: str):
self.user_id = user_id
self.conversation_memory = ConversationBufferMemory()
self.user_preferences = {}
self.user_profile = {}
def save_conversation_context(self, inputs: dict, outputs: dict):
"""保存对话上下文"""
self.conversation_memory.save_context(inputs, outputs)
def update_user_preferences(self, preferences: Dict[str, Any]):
"""更新用户偏好"""
self.user_preferences.update(preferences)
def update_user_profile(self, profile: Dict[str, Any]):
"""更新用户画像"""
self.user_profile.update(profile)
def get_personalized_context(self) -> Dict[str, Any]:
"""获取个性化上下文"""
return {
"conversation_history": self.conversation_memory.load_memory_variables({}),
"user_preferences": self.user_preferences,
"user_profile": self.user_profile
}
def save_to_file(self, file_path: str):
"""保存到文件"""
context = self.get_personalized_context()
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(context, f, ensure_ascii=False, indent=2)
def load_from_file(self, file_path: str):
"""从文件加载"""
if os.path.exists(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
context = json.load(f)
# 恢复各个部分的状态
# 这里需要根据具体实现进行恢复
# 使用个性化记忆系统
# personalized_memory = PersonalizedMemory("user_001")
# personalized_memory.save_conversation_context(
# {"input": "我喜欢科技新闻"},
# {"output": "好的,我会为你推荐更多科技相关内容"}
# )
# personalized_memory.update_user_preferences({
# "news_categories": ["科技", "互联网"],
# "response_style": "简洁"
# })
#
# context = personalized_memory.get_personalized_context()
# print(json.dumps(context, ensure_ascii=False, indent=2))
2. 记忆分析和优化
from langchain.memory import ConversationBufferMemory
from typing import List, Dict
import re
class MemoryAnalyzer:
"""记忆分析器"""
def __init__(self, memory: ConversationBufferMemory):
self.memory = memory
def analyze_conversation_patterns(self) -> Dict[str, Any]:
"""分析对话模式"""
history = self.memory.load_memory_variables({})
history_text = history.get("history", "")
# 统计信息
stats = {
"total_exchanges": 0,
"total_words": 0,
"avg_words_per_exchange": 0,
"most_common_words": [],
"conversation_topics": []
}
# 分析对话交换次数
exchanges = re.findall(r'Human: .*?\nAI: .*?(?=\nHuman: |\Z)', history_text, re.DOTALL)
stats["total_exchanges"] = len(exchanges)
# 分析词汇数量
words = re.findall(r'\b\w+\b', history_text)
stats["total_words"] = len(words)
if stats["total_exchanges"] > 0:
stats["avg_words_per_exchange"] = stats["total_words"] / (stats["total_exchanges"] * 2)
# 简单的关键词提取
common_words = ["你好", "什么", "怎么", "可以", "需要"]
stats["most_common_words"] = [word for word in common_words if word in history_text]
return stats
def suggest_memory_optimization(self) -> List[str]:
"""建议记忆优化策略"""
stats = self.analyze_conversation_patterns()
suggestions = []
if stats["total_exchanges"] > 50:
suggestions.append("考虑使用 ConversationSummaryMemory 来控制内存使用")
if stats["avg_words_per_exchange"] > 100:
suggestions.append("对话内容较长,建议使用窗口记忆限制历史长度")
return suggestions
# 使用记忆分析器
# memory = ConversationBufferMemory()
# memory.save_context({"input": "你好"}, {"output": "你好!有什么可以帮助你的吗?"})
# memory.save_context({"input": "我想了解人工智能"}, {"output": "人工智能是..."})
#
# analyzer = MemoryAnalyzer(memory)
# patterns = analyzer.analyze_conversation_patterns()
# optimizations = analyzer.suggest_memory_optimization()
#
# print("对话模式分析:", patterns)
# print("优化建议:", optimizations)
实际应用场景
1. 智能客服系统
from langchain.memory import ConversationBufferWindowMemory
from langchain_openai import ChatOpenAI
from langchain.agents import AgentType, initialize_agent
class CustomerServiceSystem:
"""智能客服系统"""
def __init__(self):
self.llm = ChatOpenAI(temperature=0.3)
self.memory = ConversationBufferWindowMemory(
k=10, # 保存最近10轮对话
memory_key="service_history"
)
self.agent = initialize_agent(
tools=[], # 客服相关工具
llm=self.llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=self.memory,
verbose=True
)
def handle_customer_inquiry(self, customer_id: str, inquiry: str) -> str:
"""处理客户咨询"""
# 可以在这里集成用户识别和个性化逻辑
response = self.agent.run(inquiry)
return response
# 使用客服系统
#客服系统 = CustomerServiceSystem()
# response1 = 客服系统.handle_customer_inquiry("customer_001", "我的订单状态如何?")
# response2 = 客服系统.handle_customer_inquiry("customer_001", "刚才我问了什么?")
2. 教育辅导系统
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
class TutoringSystem:
"""教育辅导系统"""
def __init__(self):
self.llm = ChatOpenAI(temperature=0.3)
self.memory = ConversationSummaryMemory(
llm=self.llm,
memory_key="learning_history"
)
self.tutor = ConversationChain(
llm=self.llm,
memory=self.memory,
verbose=True
)
def provide_tutoring(self, student_id: str, question: str) -> str:
"""提供辅导"""
# 可以根据学生历史调整教学策略
response = self.tutor.predict(input=question)
return response
def get_learning_summary(self, student_id: str) -> str:
"""获取学习总结"""
history = self.memory.load_memory_variables({})
return history.get("history", "暂无学习记录")
# 使用辅导系统
# 教学系统 = TutoringSystem()
# response1 = 教学系统.provide_tutoring("student_001", "请解释牛顿第二定律")
# response2 = 教学系统.provide_tutoring("student_001", "能再详细说明一下吗?")
# summary = 教学系统.get_learning_summary("student_001")
3. 个人助手应用
from langchain.memory import CombinedMemory, ConversationBufferMemory, ConversationSummaryMemory
from langchain_openai import ChatOpenAI
from langchain.agents import AgentType, initialize_agent
class PersonalAssistant:
"""个人助手"""
def __init__(self):
self.llm = ChatOpenAI(temperature=0.7)
# 组合记忆:近期详细 + 长期摘要
recent_memory = ConversationBufferMemory(
memory_key="recent_conversation"
)
long_term_memory = ConversationSummaryMemory(
llm=ChatOpenAI(temperature=0.3),
memory_key="conversation_summary"
)
self.combined_memory = CombinedMemory(
memories=[recent_memory, long_term_memory]
)
self.agent = initialize_agent(
tools=[], # 个人助手工具
llm=self.llm,
agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION,
memory=self.combined_memory,
verbose=True
)
def assist_user(self, user_id: str, request: str) -> str:
"""协助用户"""
response = self.agent.run(request)
return response
# 使用个人助手
# 助手 = PersonalAssistant()
# response1 = 助手.assist_user("user_001", "提醒我明天下午3点开会")
# response2 = 助手.assist_user("user_001", "我刚才让你提醒我什么?")
最佳实践
1. 记忆系统设计原则
class MemoryDesignPrinciples:
"""记忆系统设计原则"""
@staticmethod
def choose_appropriate_memory_type(conversation_length: int, memory_limit: str) -> str:
"""根据需求选择合适的记忆类型"""
if conversation_length < 10:
return "ConversationBufferMemory"
elif conversation_length < 50:
return "ConversationBufferWindowMemory"
else:
return "ConversationSummaryMemory"
@staticmethod
def implement_error_handling():
"""实现错误处理"""
try:
# 记忆操作
pass
except Exception as e:
print(f"记忆操作出错: {e}")
# 降级处理或恢复机制
@staticmethod
def optimize_memory_usage():
"""优化内存使用"""
# 定期清理过期记忆
# 使用适当的记忆类型
# 实现内存监控
pass
2. 性能监控和优化
import time
from typing import Callable
class MemoryPerformanceMonitor:
"""记忆性能监控器"""
def __init__(self):
self.performance_metrics = {
"save_operations": [],
"load_operations": [],
"memory_usage": []
}
def monitor_operation(self, operation_name: str):
"""监控操作性能"""
def decorator(func: Callable):
def wrapper(*args, **kwargs):
start_time = time.time()
try:
result = func(*args, **kwargs)
end_time = time.time()
duration = end_time - start_time
# 记录性能指标
self.performance_metrics[operation_name].append(duration)
return result
except Exception as e:
end_time = time.time()
duration = end_time - start_time
self.performance_metrics[operation_name].append(duration)
raise e
return wrapper
return decorator
def get_performance_report(self) -> dict:
"""获取性能报告"""
report = {}
for operation, times in self.performance_metrics.items():
if times:
report[operation] = {
"total_calls": len(times),
"avg_duration": sum(times) / len(times),
"min_duration": min(times),
"max_duration": max(times)
}
return report
# 使用性能监控器
# monitor = MemoryPerformanceMonitor()
#
# @monitor.monitor_operation("save_context")
# def save_context_with_monitoring(memory, inputs, outputs):
# memory.save_context(inputs, outputs)
#
# # 使用监控函数
# memory = ConversationBufferMemory()
# save_context_with_monitoring(memory, {"input": "测试"}, {"output": "结果"})
#
# # 获取性能报告
# report = monitor.get_performance_report()
# print(report)
3. 安全和隐私考虑
from langchain.memory import ConversationBufferMemory
import hashlib
class SecureMemory:
"""安全记忆系统"""
def __init__(self, encryption_key: str = None):
self.memory = ConversationBufferMemory()
self.encryption_key = encryption_key
def _encrypt_data(self, data: str) -> str:
"""加密数据"""
if self.encryption_key:
# 简化的加密示例(实际应用中应使用强加密算法)
return hashlib.sha256((data + self.encryption_key).encode()).hexdigest()
return data
def _decrypt_data(self, encrypted_data: str) -> str:
"""解密数据(简化示例)"""
# 实际应用中需要实现真正的解密逻辑
return encrypted_data
def save_secure_context(self, inputs: dict, outputs: dict):
"""安全保存上下文"""
# 加密敏感信息
encrypted_inputs = {k: self._encrypt_data(str(v)) for k, v in inputs.items()}
encrypted_outputs = {k: self._encrypt_data(str(v)) for k, v in outputs.items()}
self.memory.save_context(encrypted_inputs, encrypted_outputs)
def load_secure_memory(self) -> dict:
"""安全加载记忆"""
# 注意:这里返回的是加密数据,实际应用中需要解密
return self.memory.load_memory_variables({})
# 使用安全记忆系统
# secure_memory = SecureMemory(encryption_key="my_secret_key")
# secure_memory.save_secure_context({"input": "敏感信息"}, {"output": "机密回复"})
# secure_data = secure_memory.load_secure_memory()
总结
Memory 在 LangChain 应用中的集成是构建智能对话系统的关键环节。通过本章的学习,我们了解了:
- 在 Chains 和 Agents 中正确集成 Memory 的方法
- 与外部存储系统(数据库、Redis等)的集成方式
- 多用户记忆管理和个性化记忆系统的设计
- 记忆系统的高级应用和优化策略
- 实际应用场景中的最佳实践
关键要点包括:
- 根据应用需求选择合适的记忆类型
- 实现适当的错误处理和恢复机制
- 考虑性能优化和内存管理
- 关注安全和隐私保护
- 建立监控和分析机制
通过合理设计和实现记忆系统,我们可以创建出更加智能、个性化和用户友好的应用程序。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)