Memory 记忆
Memory(记忆)系统让 LangChain 应用能够记住对话历史和上下文。本章将详细介绍各种记忆组件及其使用方法。
什么是 Memory?
Memory 是 LangChain 中用于存储和检索对话历史的组件。它让 AI 应用能够记住之前的交互,提供更连贯的对话体验。
Memory 的作用
- 短期记忆:记住当前对话的上下文
- 长期记忆:跨会话存储用户偏好和历史
- 上下文管理:为 LLM 提供完整的对话背景
Memory 工作原理
Memory 类型
1. ConversationBufferMemory
最常用的对话记忆,保存完整对话历史:
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories.in_memory import ChatMessageHistory
# 创建记忆
memory = ConversationBufferMemory(
memory_key="chat_history", # 在 prompt 中引用的键名
return_messages=True # 返回消息对象而非字符串
)
# 添加对话
memory.chat_memory.add_user_message("你好,我叫张三")
memory.chat_memory.add_ai_message("你好张三!很高兴认识你")
# 查看历史
history = memory.load_memory_variables({"chat_history": []})
print(history)
2. ConversationTokenBufferMemory
基于 token 数量的记忆,限制内存占用:
from langchain.memory import ConversationTokenBufferMemory
memory = ConversationTokenBufferMemory(
llm=model, # 用于计算 token 数
max_token_limit=2000, # 最大 token 数
return_messages=True
)
适用场景:处理长对话时控制 token 消耗
3. ConversationSummaryMemory
自动生成对话摘要,适合超长对话:
from langchain.memory import ConversationSummaryMemory
memory = ConversationSummaryMemory(
llm=model, # 用于生成摘要
return_messages=True
)
# 添加长对话
memory.chat_memory.add_user_message("...")
memory.chat_memory.add_ai_message("...")
# 加载时返回摘要
summary = memory.load_memory_variables({})
4. BufferWindowMemory
只保留最近 k 轮对话:
from langchain.memory import BufferWindowMemory
memory = BufferWindowMemory(
k=3, # 保留最近3轮
return_messages=True
)
在 Chain 中使用 Memory
基本用法
from langchain.chat_models import init_chat_model
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
# 创建记忆
memory = ConversationBufferMemory(
memory_key="history",
return_messages=True
)
# 创建 prompt
prompt = PromptTemplate.from_template("""
你是一个对话助手。
对话历史:
{history}
用户:{input}
助手:
""")
# 创建 Chain(带记忆)
chain = LLMChain(
llm=model,
prompt=prompt,
memory=memory
)
# 对话
response1 = chain.invoke({"input": "我叫李四"})
print(response1["text"])
response2 = chain.invoke({"input": "你还记得我叫什么吗?"})
print(response2["text"])
使用 LCEL
from langchain.schema import MessagesPlaceholder
from langchain.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个有帮助的助手"),
MessagesPlaceholder(variable_name="history", optional=True),
("user", "{input}")
])
chain = (
{"input": lambda x: x["input"], "history": memory.load_memory_variables}
| prompt
| model
)
在 Agent 中使用 Memory
创建带记忆的 Agent
from langchain.agents import create_agent
from langchain.memory import ConversationBufferMemory
from langchain.tools import tool
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
@tool
def get_weather(city: str) -> str:
"""获取城市天气"""
return f"{city}天气晴朗"
# 创建记忆
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
# Agent 的 prompt 需要包含历史
system_prompt = """你是一个有帮助的助手。
历史对话:
{chat_history}
可用工具:
- get_weather: 获取天气"""
# 创建 Agent
agent = create_agent(
model=model,
tools=[get_weather],
prompt={
"system_prompt": system_prompt,
"input": "{input}",
"chat_history": "{chat_history}"
}
)
# 对话
result1 = agent.invoke({"messages": [{"role": "user", "content": "北京天气怎么样?"}]})
result2 = agent.invoke({"messages": [{"role": "user", "content": "上海呢?"}]})
消息类型
消息对象
from langchain.schema import HumanMessage, AIMessage, SystemMessage
# 人类消息
msg = HumanMessage(content="你好")
print(msg.type) # "human"
print(msg.content) # "你好"
# AI 消息
msg = AIMessage(content="你好,有什么可以帮您?")
print(msg.type) # "ai"
# 系统消息
msg = SystemMessage(content="你是一个有帮助的助手")
print(msg.type) # "system"
消息历史存储
from langchain.memory.chat_message_histories.in_memory import ChatMessageHistory
# 创建消息历史
history = ChatMessageHistory()
# 添加消息
history.add_user_message("第一个问题")
history.add_ai_message("第一个回答")
history.add_user_message("第二个问题")
history.add_ai_message("第二个回答")
# 查看所有消息
for msg in history.messages:
print(f"{msg.type}: {msg.content}")
持久化记忆
文件存储
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories import FileChatMessageHistory
# 使用文件存储消息
history = FileChatMessageHistory("chat_history.json")
memory = ConversationBufferMemory(
chat_memory=history,
memory_key="history",
return_messages=True
)
Redis 存储
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories.redis import RedisChatMessageHistory
# 创建 Redis 消息历史
history = RedisChatMessageHistory(
session_id="user_123",
url="redis://localhost:6379"
)
memory = ConversationBufferMemory(
chat_memory=history,
memory_key="history"
)
自定义存储
from langchain.memory import ChatMessageHistory
from langchain.schema import BaseChatMessageHistory
class MyCustomHistory(BaseChatMessageHistory):
def __init__(self):
self.messages = []
def add_user_message(self, message):
self.messages.append(HumanMessage(content=message))
def add_ai_message(self, message):
self.messages.append(AIMessage(content=message))
def clear(self):
self.messages = []
# 使用
history = MyCustomHistory()
memory = ConversationBufferMemory(
chat_memory=history,
memory_key="history"
)
多用户记忆管理
会话隔离
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories import RedisChatMessageHistory
def get_memory_for_user(user_id: str):
"""为每个用户创建独立的记忆"""
history = RedisChatMessageHistory(
session_id=f"user_{user_id}",
url="redis://localhost:6379"
)
return ConversationBufferMemory(
chat_memory=history,
memory_key="history"
)
# 为不同用户创建独立记忆
memory_user1 = get_memory_for_user("user_001")
memory_user2 = get_memory_for_user("user_002")
SQLite 存储
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories import SQLiteChatMessageHistory
# 使用 SQLite 存储
history = SQLiteChatMessageHistory("conversations.db")
memory = ConversationBufferMemory(
chat_memory=history,
memory_key="history"
)
高级用法
摘要式记忆
from langchain.memory import ConversationSummaryMemory
from langchain.chat_models import init_chat_model
model = init_chat_model(model="gpt-4o-mini", model_provider="openai")
memory = ConversationSummaryMemory(
llm=model,
memory_key="summary"
)
# 添加很多对话后,memory 会自动生成摘要
for i in range(10):
memory.chat_memory.add_user_message(f"问题{i}")
memory.chat_memory.add_ai_message(f"回答{i}")
# 查看摘要
summary = memory.load_memory_variables({})
print(summary["summary"])
组合多种记忆
from langchain.memory import CombinedMemory
# 短期记忆(最近几轮)
short_memory = ConversationBufferMemory(
memory_key="recent",
k=3
)
# 长期记忆(用户偏好)
long_memory = ConversationBufferMemory(
memory_key="preferences"
)
# 组合
combined = CombinedMemory(memories=[short_memory, long_memory])
实体记忆
from langchain.memory import EntityMemory
memory = EntityMemory(
llm=model,
memory_key="entities"
)
# 添加对话
memory.save_context(
{"input": "我叫张三,我住在北京"},
{"output": "好的,我记住你叫张三,住在北京"}
)
# 查看实体
entities = memory.load_memory_variables({})
print(entities["entities"])
# {'张三': '住在这里...', '北京': '居住地...'}
实际应用示例
1. 客服系统
from langchain.memory import ConversationBufferMemory
from langchain.memory.chat_message_histories import FileChatMessageHistory
# 为每个用户创建独立记忆
def get_customer_memory(customer_id: str):
history = FileChatMessageHistory(f"customer_{customer_id}.json")
return ConversationBufferMemory(
chat_memory=history,
memory_key="history"
)
# 创建对话链
memory = get_customer_memory("customer_001")
chain = LLMChain(llm=model, prompt=prompt, memory=memory)
# 处理对话
chain.invoke({"input": "我想查询订单"})
chain.invoke({"input": "订单号是12345"})
2. 多轮问答系统
from langchain.memory import BufferWindowMemory
memory = BufferWindowMemory(k=5) # 保留最近5轮
# 问答链
qa_prompt = PromptTemplate.from_template("""
基于以下对话历史,回答用户问题。如果历史信息不相关,只根据常识回答。
历史:
{history}
问题:{question}
回答:
""")
chain = LLMChain(llm=model, prompt=qa_prompt, memory=memory)
# 多轮问答
questions = [
"Python 是什么?",
"它主要用来做什么?",
"学Python需要什么基础?",
"学多久能入门?",
"找不到工作怎么办?"
]
for q in questions:
result = chain.invoke({"question": q})
print(f"Q: {q}")
print(f"A: {result['text']}\n")
3. 个性化推荐
from langchain.memory import ConversationBufferMemory
from langchain.tools import tool
# 保存用户偏好
preference_memory = ConversationBufferMemory(
memory_key="preferences"
)
@tool
def recommend_movies(genre: str) -> list:
"""推荐电影"""
return ["电影A", "电影B", "电影C"]
# 收集偏好
preference_memory.chat_memory.add_user_message("我喜欢科幻电影")
preference_memory.chat_memory.add_ai_message("好的,我记住你喜欢科幻类型")
# 使用偏好推荐
def get_recommendations():
prefs = preference_memory.load_memory_variables({})
# 从偏好中提取信息并推荐
return recommend_movies.invoke("科幻")
最佳实践
1. 合理设置记忆长度
# 短对话
memory = ConversationBufferMemory()
# 长对话,控制 token
memory = ConversationTokenBufferMemory(
llm=model,
max_token_limit=2000
)
# 只保留最近几轮
memory = BufferWindowMemory(k=3)
2. 定期清理记忆
# 定期清理旧记忆
def cleanup_old_sessions(days=30):
import time
cutoff = time.time() - days * 86400
# 清理逻辑...
3. 敏感信息处理
# 不存储敏感信息
class SensitiveFilterMemory(ConversationBufferMemory):
def save_context(self, inputs, outputs):
# 过滤敏感信息
filtered = {k: v for k, v in inputs.items() if not is_sensitive(k, v)}
super().save_context(filtered, outputs)
下一步
现在你已经掌握了 Memory 的使用方法,接下来学习: