1. 概述
LangChain 中的 Memory 系统用于在对话和链式调用中维护状态。Memory 可以存储关于过去执行的信息,并将这些信息注入到未来执行的输入中。这对于构建连贯的对话系统尤其重要。
需要注意的是,当前版本的 Memory 系统已被标记为废弃,将在 LangChain 1.0.0 版本中移除。官方推荐使用新的状态管理方式。
2. Memory 类型层次结构
graph TD
A[BaseMemory] --> B[BaseChatMemory]
B --> C[ConversationBufferMemory]
B --> D[ConversationBufferWindowMemory]
E[BaseMemory] --> F[VectorStoreRetrieverMemory]
B --> G[ConversationSummaryMemory]
G --> H[ConversationSummaryBufferMemory]
A --> I[其他Memory实现]
3. 各 Memory 类型详细对比
3.1 BaseMemory (基础内存类)
文件路径: libs/core/langchain_core/memory.py
特性
说明
类型
抽象基类
状态
已废弃 (since 0.3.3)
主要方法
memory_variables, load_memory_variables, save_context, clear
用途
所有 Memory 类型的基类
核心抽象方法:
memory_variables: 返回内存变量的键列表
load_memory_variables: 加载内存变量
save_context: 保存上下文
clear: 清除内存内容
3.2 BaseChatMemory (基础聊天内存类)
文件路径: libs/langchain/langchain/memory/chat_memory.py
特性
说明
类型
抽象基类
状态
已废弃 (since 0.3.1)
继承
BaseMemory
主要属性
chat_memory, output_key, input_key, return_messages
用途
聊天相关 Memory 的基类
核心特性:
使用 BaseChatMessageHistory 存储消息历史
提供 _get_input_output 方法来提取输入输出
实现了 save_context 和 clear 方法
3.3 ConversationBufferMemory (对话缓冲内存)
文件路径: libs/langchain/langchain/memory/buffer.py
特性
说明
类型
具体实现类
状态
已废弃 (since 0.3.1)
继承
BaseChatMemory
主要属性
human_prefix, ai_prefix, memory_key
缓冲区
存储完整对话历史
核心特性:
存储完整的对话历史(所有消息)
可以以字符串或消息列表形式返回历史
通过 buffer, buffer_as_str, buffer_as_messages 属性访问历史
使用示例:
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.save_context({"input": "你好"}, {"output": "你好!有什么我可以帮你的吗?"})
memory.save_context({"input": "我想了解LangChain"}, {"output": "LangChain是一个用于构建LLM应用的框架"})
print(memory.load_memory_variables({}))
# 输出包含所有对话历史
图示说明:
sequenceDiagram
participant U as 用户
participant M as ConversationBufferMemory
participant H as InMemoryChatMessageHistory
U->>M: save_context({"input": "你好"}, {"output": "你好!"})
M->>M: _get_input_output()
M->>H: add_messages([HumanMessage("你好"), AIMessage("你好!")])
U->>M: save_context({"input": "介绍一下LangChain"}, {"output": "LangChain是LLM应用框架"})
M->>M: _get_input_output()
M->>H: add_messages([HumanMessage("介绍一下LangChain"), AIMessage("LangChain是LLM应用框架")])
U->>M: load_memory_variables({})
M->>H: messages
H-->>M: [HumanMessage("你好"), AIMessage("你好!"), HumanMessage("介绍一下LangChain"), AIMessage("LangChain是LLM应用框架")]
M-->>U: {"history": "Human: 你好\nAI: 你好!\nHuman: 介绍一下LangChain\nAI: LangChain是LLM应用框架"}
3.4 ConversationBufferWindowMemory (窗口对话缓冲内存)
文件路径: libs/langchain/langchain/memory/buffer_window.py
特性
说明
类型
具体实现类
状态
已废弃 (since 0.3.1)
继承
BaseChatMemory
主要属性
human_prefix, ai_prefix, memory_key, k
缓冲区
存储最近 k 轮对话
核心特性:
仅存储最近 k 轮对话(默认 5 轮)
通过 k 参数控制窗口大小
自动丢弃超出窗口的历史消息
使用示例:
from langchain.memory import ConversationBufferWindowMemory
memory = ConversationBufferWindowMemory(k=2) # 只保留最近2轮对话
memory.save_context({"input": "你好"}, {"output": "你好!"})
memory.save_context({"input": "介绍一下LangChain"}, {"output": "LangChain是LLM应用框架"})
memory.save_context({"input": "它有什么特性"}, {"output": "它提供了组件化、链式调用等功能"})
print(memory.load_memory_variables({}))
# 只输出最近2轮对话
图示说明:
sequenceDiagram
participant U as 用户
participant M as ConversationBufferWindowMemory (k=2)
participant H as InMemoryChatMessageHistory
U->>M: save_context({"input": "你好"}, {"output": "你好!"})
M->>H: add_messages([HumanMessage("你好"), AIMessage("你好!")])
U->>M: save_context({"input": "介绍一下LangChain"}, {"output": "LangChain是LLM应用框架"})
M->>H: add_messages([HumanMessage("介绍一下LangChain"), AIMessage("LangChain是LLM应用框架")])
U->>M: save_context({"input": "它有什么特性"}, {"output": "它提供了组件化、链式调用等功能"})
M->>H: add_messages([HumanMessage("它有什么特性"), AIMessage("它提供了组件化、链式调用等功能")])
U->>M: load_memory_variables({})
M->>H: messages[-4:] # 只取最近2轮(4条消息)
H-->>M: [HumanMessage("介绍一下LangChain"), AIMessage("LangChain是LLM应用框架"), HumanMessage("它有什么特性"), AIMessage("它提供了组件化、链式调用等功能")]
M-->>U: {"history": "Human: 介绍一下LangChain\nAI: LangChain是LLM应用框架\nHuman: 它有什么特性\nAI: 它提供了组件化、链式调用等功能"}
3.5 ConversationSummaryMemory (对话摘要内存)
文件路径: libs/langchain/langchain/memory/summary.py
特性
说明
类型
具体实现类
状态
已废弃 (since 0.3.1)
继承
BaseChatMemory, SummarizerMixin
主要属性
buffer, memory_key, llm, prompt
缓冲区
存储对话摘要而非完整历史
核心特性:
使用 LLM 生成对话摘要
每次新增对话时更新摘要
节省内存和上下文长度
需要传入 LLM 实例用于生成摘要
使用示例:
from langchain.memory import ConversationSummaryMemory
from langchain_openai import OpenAI
llm = OpenAI()
memory = ConversationSummaryMemory(llm=llm)
memory.save_context({"input": "你好"}, {"output": "你好!"})
memory.save_context({"input": "介绍一下LangChain"}, {"output": "LangChain是LLM应用框架"})
print(memory.load_memory_variables({}))
# 输出对话摘要而非完整历史
图示说明:
sequenceDiagram
participant U as 用户
participant M as ConversationSummaryMemory
participant H as InMemoryChatMessageHistory
participant L as LLM
U->>M: save_context({"input": "你好"}, {"output": "你好!"})
M->>H: add_messages([HumanMessage("你好"), AIMessage("你好!")])
M->>L: predict_new_summary(["Human: 你好", "AI: 你好!"], "")
L-->>M: "用户问候,AI回应问候"
M->>M: buffer = "用户问候,AI回应问候"
U->>M: save_context({"input": "介绍一下LangChain"}, {"output": "LangChain是LLM应用框架"})
M->>H: add_messages([HumanMessage("介绍一下LangChain"), AIMessage("LangChain是LLM应用框架")])
M->>L: predict_new_summary(["Human: 介绍一下LangChain", "AI: LangChain是LLM应用框架"], "用户问候,AI回应问候")
L-->>M: "用户问候,AI回应问候。用户询问LangChain介绍,AI解释LangChain是LLM应用框架"
M->>M: buffer = "用户问候,AI回应问候。用户询问LangChain介绍,AI解释LangChain是LLM应用框架"
U->>M: load_memory_variables({})
M-->>U: {"history": "用户问候,AI回应问候。用户询问LangChain介绍,AI解释LangChain是LLM应用框架"}
3.6 ConversationSummaryBufferMemory (摘要缓冲内存)
文件路径: libs/langchain/langchain/memory/summary_buffer.py
特性
说明
类型
具体实现类
状态
已废弃 (since 0.3.1)
继承
BaseChatMemory, SummarizerMixin
主要属性
buffer, memory_key, llm, prompt, max_token_limit
缓冲区
结合完整历史和摘要
核心特性:
结合了缓冲和摘要的优点
保留最近的完整消息,对旧消息进行摘要
通过 max_token_limit 控制内存使用
在内存和信息完整性之间取得平衡
使用示例:
from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import OpenAI
llm = OpenAI()
memory = ConversationSummaryBufferMemory(llm=llm, max_token_limit=100)
# 使用方式与其它Memory类型类似
图示说明:
sequenceDiagram
participant U as 用户
participant M as ConversationSummaryBufferMemory
participant H as InMemoryChatMessageHistory
participant L as LLM
Note over M,H: 初始状态:buffer="", messages=[]
U->>M: save_context({"input": "你好"}, {"output": "你好!"})
M->>H: add_messages([HumanMessage("你好"), AIMessage("你好!")])
Note over M,H: buffer="", messages=[HumanMessage("你好"), AIMessage("你好!")]
U->>M: save_context({"input": "介绍一下LangChain"}, {"output": "LangChain是LLM应用框架"})
M->>H: add_messages([HumanMessage("介绍一下LangChain"), AIMessage("LangChain是LLM应用框架")])
Note over M,H: buffer="", messages=[HumanMessage("你好"), AIMessage("你好!"), HumanMessage("介绍一下LangChain"), AIMessage("LangChain是LLM应用框架")]
U->>M: save_context({"input": "它有什么特性"}, {"output": "它提供了组件化、链式调用等功能"})
M->>H: add_messages([HumanMessage("它有什么特性"), AIMessage("它提供了组件化、链式调用等功能")])
Note over M,L: 检查token数量,如果超过max_token_limit
alt 如果超过token限制
M->>L: predict_new_summary(较旧消息, buffer)
L-->>M: 更新buffer摘要
M->>M: 移除已摘要的消息
end
U->>M: load_memory_variables({})
M-->>U: {"history": "摘要内容 + 最近完整消息"}
3.7 VectorStoreRetrieverMemory (向量存储检索内存)
文件路径: libs/langchain/langchain/memory/vectorstore.py
特性
说明
类型
具体实现类
状态
已废弃 (since 0.3.1)
继承
BaseMemory
主要属性
retriever, memory_key, input_key, return_docs
缓冲区
使用向量存储和检索机制
核心特性:
使用向量存储保存对话历史
根据输入内容检索相关历史
适用于大规模对话历史场景
需要传入 VectorStoreRetriever 实例
使用示例:
from langchain.memory import VectorStoreRetrieverMemory
from langchain.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
embedding = OpenAIEmbeddings()
vectorstore = Chroma("langchain_store", embedding)
retriever = vectorstore.as_retriever()
memory = VectorStoreRetrieverMemory(retriever=retriever)
图示说明:
sequenceDiagram
participant U as 用户
participant M as VectorStoreRetrieverMemory
participant R as VectorStoreRetriever
participant V as VectorStore
U->>M: save_context({"input": "你好"}, {"output": "你好!"})
M->>M: _form_documents()
M->>R: add_documents([Document("input: 你好\noutput: 你好!")])
R->>V: 存储文档向量化表示
U->>M: save_context({"input": "介绍一下LangChain"}, {"output": "LangChain是LLM应用框架"})
M->>M: _form_documents()
M->>R: add_documents([Document("input: 介绍一下LangChain\noutput: LangChain是LLM应用框架")])
R->>V: 存储文档向量化表示
U->>M: load_memory_variables({"input": "什么是LangChain"})
M->>R: invoke("什么是LangChain")
R->>V: 相似度检索相关历史
V-->>R: 相关文档
R-->>M: [Document("input: 介绍一下LangChain\noutput: LangChain是LLM应用框架")]
M-->>U: {"history": "input: 介绍一下LangChain\noutput: LangChain是LLM应用框架"}
4. Memory 类型对比表
特性
ConversationBufferMemory
ConversationBufferWindowMemory
ConversationSummaryMemory
ConversationSummaryBufferMemory
VectorStoreRetrieverMemory
存储方式
完整历史
固定窗口
摘要
混合(近期完整+历史摘要)
向量存储
内存使用
高
中等
低
中等
取决于向量存储
上下文相关性
全部
最近 K 轮
摘要
混合
基于相似度检索
实现复杂度
简单
简单
复杂(需要 LLM)
复杂(需要 LLM)
复杂(需要向量存储)
适用场景
短对话
中等长度对话
长对话
长对话
大规模对话历史
需要 LLM
否
否
是
是
否
需要向量存储
否
否
否
否
是
5. Memory 使用流程对比
5.1 ConversationBufferMemory 流程
graph LR
A[保存上下文] --> B[添加到消息历史]
C[加载内存变量] --> D[返回完整历史]
5.2 ConversationBufferWindowMemory 流程
graph LR
A[保存上下文] --> B[添加到消息历史]
C[加载内存变量] --> D[截取最近K轮消息]
D --> E[返回截取的历史]
5.3 ConversationSummaryMemory 流程
graph LR
A[保存上下文] --> B[添加到消息历史]
B --> C[使用LLM生成新摘要]
C --> D[更新摘要缓冲区]
E[加载内存变量] --> F[返回摘要]
5.4 ConversationSummaryBufferMemory 流程
graph LR
A[保存上下文] --> B[添加到消息历史]
B --> C{消息长度是否超过限制}
C -->|是| D[使用LLM摘要旧消息]
D --> E[更新摘要缓冲区]
E --> F[移除已摘要消息]
C -->|否| G[保持原状]
H[加载内存变量] --> I[返回摘要+近期完整消息]
5.5 VectorStoreRetrieverMemory 流程
graph LR
A[保存上下文] --> B[格式化为文档]
B --> C[存储到向量数据库]
D[加载内存变量] --> E[根据输入检索相关历史]
E --> F[返回相关历史]
6. 使用建议
6.1 根据对话长度选择
短对话 (< 10 轮) - 使用 ConversationBufferMemory
简单直接
保持完整的上下文信息
中等长度对话 (10-50 轮) - 使用 ConversationBufferWindowMemory
限制历史长度,节省内存
保持近期上下文的完整性
长对话 (> 50 轮) - 使用 ConversationSummaryBufferMemory
平衡内存使用和上下文完整性
保持近期完整信息和历史摘要
6.2 根据应用场景选择
精确上下文要求 - 使用 ConversationBufferMemory 或 ConversationBufferWindowMemory
适用于需要精确引用历史对话的场景
大规模历史存储 - 使用 VectorStoreRetrieverMemory
适用于需要存储大量历史且基于相关性检索的场景
内存受限环境 - 使用 ConversationSummaryMemory
适用于内存有限但需要保持长期记忆的场景
7. 迁移建议
由于所有 Memory 类型都已被标记为废弃,建议按照官方迁移指南进行迁移:
查看迁移指南: https://python.langchain.com/docs/versions/migrating_memory/
考虑使用 LangGraph 进行状态管理
使用新的聊天历史接口
新的推荐方式:
# 使用新的聊天历史接口
from langchain_core.messages import HumanMessage, AIMessage
from langchain_core.chat_history import InMemoryChatMessageHistory
chat_history = InMemoryChatMessageHistory()
chat_history.add_message(HumanMessage(content="你好"))
chat_history.add_message(AIMessage(content="你好!有什么我可以帮你的吗?"))
8. 总结
LangChain 的 Memory 系统提供了多种管理对话历史的方式,每种方式都有其适用场景。虽然这些功能已被标记为废弃,但在当前版本中仍然可以使用。在新项目中,建议直接使用官方推荐的新方式来管理对话状态。
通过以上图示对比,可以更直观地理解各种 Memory 类型的工作原理和适用场景,有助于在实际项目中做出合适的选择。