langchain.memory
模块,这是 LangChain 库中用于管理对话记忆(memory)的工具集,旨在存储和检索对话历史或上下文,以支持多轮对话和上下文感知的交互。
本文基于 LangChain 0.3.x,详细介绍 langchain.memory
模块的结构、核心类及其功能,并提供一个独立示例,展示如何使用 ConversationBufferMemory
结合 ChatOpenAI
实现人工智能主题的多轮对话,示例突出模块的对话记忆管理能力。
如果你在运行代码时遇到以下提示信息,代表memory 模块已经弃用,需要迁移到新的技术实现。请按提示中的链接中的内容进行迁移。
LangChainDeprecationWarning:
Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/
langchain.memory
模块概览
langchain.memory
模块是 LangChain 库的核心组成部分,提供一系列记忆类,用于在对话或链(Chain)中存储和检索上下文信息。这些类帮助模型记住之前的交互内容,支持多轮对话、上下文感知的问答和复杂任务的连续性。模块中的记忆类通常与 langchain_core.chat_history.BaseChatMessageHistory
或其他存储后端集成,适用于聊天机器人、问答系统等场景。
核心功能:
- 存储对话历史(用户输入和模型响应)。
- 支持多种记忆类型(如缓冲区、摘要、知识图谱)。
- 提供灵活的上下文注入方式,适配不同链。
- 支持持久化存储(如内存、数据库)。
适用场景:
- 构建多轮对话的聊天机器人,需保留上下文。
- 实现 RAG(Retrieval-Augmented Generation)系统,结合历史和检索内容。
- 管理复杂任务的中间状态或上下文。
- 测试 LLM 的长上下文处理能力。
模块位置:
- 源码路径:
langchain/memory/
- 文档参考:LangChain API
模块中的主要类
以下是 langchain.memory
模块中的核心类(基于 LangChain 0.3.x),包括功能和典型用法。
1. ConversationBufferMemory
- 功能:存储完整的对话历史(用户和 AI 消息),按时间顺序保留所有消息。
- 参数:
memory_key
(str
,默认"history"
):上下文注入的键。input_key
(str
,默认None
):用户输入的键。output_key
(str
,默认None
):模型输出的键。chat_memory
(BaseChatMessageHistory
,默认ChatMessageHistory
):消息存储后端。
- 使用场景:简单的多轮对话,需完整历史。
- 示例:
from langchain.memory import ConversationBufferMemory memory = ConversationBufferMemory(memory_key="history") memory.save_context({"input": "什么是 AI?"}, {"output": "AI 是人工智能的缩写。"})
2. ConversationBufferWindowMemory
- 功能:仅存储最近的
k
条对话消息,限制上下文长度。 - 参数:
k
(int
):保留的消息对数。memory_key
(str
):上下文键。chat_memory
(BaseChatMessageHistory
):存储后端。
- 使用场景:控制上下文长度,节省 tokens。
- 示例:
from langchain.memory import ConversationBufferWindowMemory memory = ConversationBufferWindowMemory(k=2, memory_key="history")
3. ConversationSummaryMemory
- 功能:使用 LLM 总结对话历史,生成简洁的上下文摘要。
- 参数:
llm
(BaseLLM
):用于生成摘要的模型。memory_key
(str
):上下文键。prompt
(PromptTemplate
):摘要生成提示。
- 使用场景:长对话中压缩历史,适合大模型。
- 示例:
from langchain.memory import ConversationSummaryMemory from langchain_openai import ChatOpenAI memory = ConversationSummaryMemory(llm=ChatOpenAI(), memory_key="history")
4. ConversationSummaryBufferMemory
- 功能:结合缓冲区和摘要,保留近期消息并总结早期对话。
- 参数:
llm
(BaseLLM
):摘要模型。max_token_limit
(int
):触发摘要的 token 阈值。memory_key
(str
):上下文键。
- 使用场景:平衡完整性和效率的长对话。
- 示例:
from langchain.memory import ConversationSummaryBufferMemory memory = ConversationSummaryBufferMemory(llm=ChatOpenAI(), max_token_limit=1000)
5. ConversationKGMemory
- 功能:从对话中提取知识图谱(实体和关系),存储结构化上下文。
- 参数:
llm
(BaseLLM
):提取实体的模型。memory_key
(str
):上下文键。
- 使用场景:需要结构化知识的对话(如问答、推理)。
- 示例:
from langchain.memory import ConversationKGMemory memory = ConversationKGMemory(llm=ChatOpenAI())
其他类
VectorStoreRetrieverMemory
:使用向量存储检索相关历史。CombinedMemory
:组合多个记忆类,灵活定制。MotorheadMemory
:基于 Motorhead 的外部记忆服务。
基类:
- 所有记忆类继承自
langchain.memory.BaseMemory
,提供标准接口:save_context
:保存输入和输出。load_memory_variables
:加载上下文。clear
:清除记忆。
使用方式
以下是使用 langchain.memory
模块的通用步骤。
1. 安装依赖
pip install --upgrade langchain langchain-openai langchain-community
2. 设置 OpenAI API 密钥
export OPENAI_API_KEY="your-api-key"
或在代码中:
import os
os.environ["OPENAI_API_KEY"] = "your-api-key"
3. 初始化记忆
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(memory_key="history", return_messages=True)
4. 构建对话链
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
llm = ChatOpenAI(model="gpt-3.5-turbo")
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个人工智能专家,回答用户问题。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
chain = prompt | llm
5. 集成记忆
from langchain_core.runnables import RunnablePassthrough
chain_with_memory = RunnablePassthrough.assign(
history=lambda x: memory.load_memory_variables({})["history"]
) | prompt | llm
6. 调用链并保存历史
response = chain_with_memory.invoke({"input": "什么是人工智能?"})
memory.save_context({"input": "什么是人工智能?"}, {"output": response.content})
print(response.content)
使用 langchain.memory
的示例
以下是一个独立示例,展示如何使用 langchain.memory
模块中的 ConversationBufferMemory
结合 ChatOpenAI
实现人工智能主题的多轮对话,保留完整对话历史。示例使用 LCEL 和 RunnableWithMessageHistory
简化历史管理,突出记忆模块的集成。
准备环境:
- 获取 OpenAI API 密钥:OpenAI Platform。
- 设置环境变量:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai langchain-community
代码:
from langchain.memory import ConversationBufferMemory
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables.history import RunnableWithMessageHistory
# 初始化 ConversationBufferMemory
memory = ConversationBufferMemory(
memory_key="history",
return_messages=True,
chat_memory=ChatMessageHistory()
)
# 定义会话历史获取函数
def get_session_history(session_id: str):
return memory.chat_memory
# 初始化 ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)
# 定义提示模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个人工智能专家,回答用户问题。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
# 定义输出解析器
parser = StrOutputParser()
# 创建对话链
chain = prompt | llm | parser
# 包装链以支持消息历史
chain_with_history = RunnableWithMessageHistory(
runnable=chain,
get_session_history=get_session_history,
input_messages_key="input",
history_messages_key="history"
)
# 测试 ConversationBufferMemory 和对话链
print("测试 ConversationBufferMemory 和对话链:")
try:
session_id = "ai_chat_001"
# 第一轮对话
question1 = "什么是人工智能?"
result1 = chain_with_history.invoke(
{"input": question1},
config={"configurable": {"session_id": session_id}}
)
print(f"问题 1: {question1}")
print(f"回答 1: {result1}")
# 第二轮对话(依赖上下文)
question2 = "它有哪些应用?"
result2 = chain_with_history.invoke(
{"input": question2},
config={"configurable": {"session_id": session_id}}
)
print(f"\n问题 2: {question2}")
print(f"回答 2: {result2}")
# 显示消息历史
print("\n消息历史:")
history = memory.load_memory_variables({})["history"]
for i, msg in enumerate(history):
print(f"消息 {i+1} ({msg.__class__.__name__}): {msg.content}")
except Exception as e:
print(f"错误: {e}")
输出示例(实际输出取决于模型和 API 响应):
测试 ConversationBufferMemory 和对话链:
问题 1: 什么是人工智能?
回答 1: 人工智能(AI)是计算机科学的一个分支,旨在模拟人类智能,如学习、推理和问题解决。
问题 2: 它有哪些应用?
回答 2: 人工智能的应用包括医疗诊断、自动驾驶、语音识别、推荐系统和金融分析等领域。
消息历史:
消息 1 (HumanMessage): 什么是人工智能?
消息 2 (AIMessage): 人工智能(AI)是计算机科学的一个分支,旨在模拟人类智能,如学习、推理和问题解决。
消息 3 (HumanMessage): 它有哪些应用?
消息 4 (AIMessage): 人工智能的应用包括医疗诊断、自动驾驶、语音识别、推荐系统和金融分析等领域。
代码说明
- ConversationBufferMemory:
- 初始化
ConversationBufferMemory
,使用ChatMessageHistory
作为后端。 - 设置
memory_key="history"
和return_messages=True
。
- 初始化
- 会话历史:
- 定义
get_session_history
返回memory.chat_memory
。
- 定义
- LLM 初始化:
- 使用
ChatOpenAI
调用gpt-3.5-turbo
,设置temperature=0.7
。
- 使用
- 提示模板:
ChatPromptTemplate
包含系统消息、历史占位符和用户输入。MessagesPlaceholder
注入历史消息。
- 对话链:
- 使用 LCEL 组合
prompt
、llm
和parser
。 RunnableWithMessageHistory
包装链,自动管理历史。
- 使用 LCEL 组合
- 测试:
- 进行两轮对话:定义 AI 和询问应用。
- 使用
session_id="ai_chat_001"
跟踪会话。 - 显示历史消息,展示上下文保留。
- 错误处理:
- 使用
try-except
捕获 API 或链错误。
- 使用
- 主题:
- 示例聚焦 AI 多轮对话,突出记忆管理。
- 独立性:
- 不涉及
RunnableWithMessageHistory
或其他上下文。
- 不涉及
运行要求:
- 有效的 OpenAI API 密钥:
export OPENAI_API_KEY="your-api-key"
- 安装依赖:
pip install --upgrade langchain langchain-openai langchain-community
- 网络连接:访问
https://api.openai.com
.
注意事项
- API 密钥:
- 确保
OPENAI_API_KEY
已设置:echo $OPENAI_API_KEY
- 或在代码中设置:
llm = ChatOpenAI(api_key="your-api-key")
- 确保
- 记忆选择:
- 完整历史(
ConversationBufferMemory
):适合短对话。memory = ConversationBufferMemory()
- 窗口历史(
ConversationBufferWindowMemory
):控制长度。memory = ConversationBufferWindowMemory(k=2)
- 摘要(
ConversationSummaryMemory
):压缩长对话。memory = ConversationSummaryMemory(llm=ChatOpenAI())
- 完整历史(
- 持久化存储:
- 使用
RedisChatMessageHistory
:from langchain_community.chat_message_histories import RedisChatMessageHistory memory = ConversationBufferMemory( chat_memory=RedisChatMessageHistory(session_id="ai_chat_001", redis_url="redis://localhost:6379/0") )
- 使用
- 性能优化:
- 异步调用:使用
ainvoke
:result = await chain_with_history.ainvoke(input, config)
- 限制历史长度:避免上下文溢出:
max_messages = 10 memory.chat_memory.messages = memory.chat_memory.messages[-max_messages:]
- 缓存摘要:加速
ConversationSummaryMemory
:memory = ConversationSummaryBufferMemory(llm=ChatOpenAI(), max_token_limit=1000)
- 异步调用:使用
- 错误调试:
- 历史未注入:
- 检查
memory_key
:print(memory.memory_key)
- 验证历史:
print(memory.load_memory_variables({}))
- 检查
- API 错误:
- 检查密钥:
print(os.environ.get("OPENAI_API_KEY"))
- 增加超时:
llm = ChatOpenAI(timeout=30)
- 检查密钥:
- 会话错误:
- 检查
session_id
:print(config)
- 验证历史实例:
print(get_session_history("ai_chat_001"))
- 检查
- 历史未注入:
常见问题
Q1:如何选择合适的记忆类?
A:根据需求:
- 短对话:
ConversationBufferMemory
。 - 控制长度:
ConversationBufferWindowMemory
。 - 长对话压缩:
ConversationSummaryMemory
或ConversationSummaryBufferMemory
。 - 结构化知识:
ConversationKGMemory
。
Q2:如何持久化记忆?
A:使用持久化后端:
from langchain_community.chat_message_histories import SQLChatMessageHistory
memory = ConversationBufferMemory(
chat_memory=SQLChatMessageHistory(session_id="ai_chat_001", connection_string="sqlite:///chat_history.db")
)
Q3:如何与 RAG 结合?
A:添加检索上下文:
from langchain.vectorstores import FAISS
vectorstore = FAISS.from_documents(docs, OpenAIEmbeddings())
retriever = vectorstore.as_retriever()
prompt = ChatPromptTemplate.from_messages([
("system", "根据上下文和历史回答:\n{context}"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
chain = {"context": retriever, "history": lambda x: memory.load_memory_variables({})["history"], "input": lambda x: x["input"]} | prompt | llm
Q4:如何支持开源模型?
A:使用 ChatOllama
:
from langchain_ollama import ChatOllama
llm = ChatOllama(model="llama3")
chain = prompt | llm | parser
chain_with_history = RunnableWithMessageHistory(
runnable=chain,
get_session_history=get_session_history,
input_messages_key="input",
history_messages_key="history"
)
总结
langchain.memory
模块是 LangChain 中管理对话上下文的核心工具集,包含以下关键类:
ConversationBufferMemory
:存储完整历史。ConversationBufferWindowMemory
:限制近期消息。ConversationSummaryMemory
:生成历史摘要。ConversationSummaryBufferMemory
:结合缓冲和摘要。ConversationKGMemory
:提取结构化知识。