LangChain 框架-短期记忆能力
是 LangChain 中实现短期对话记忆的最简单方式,适用于单次会话内的上下文保持。只需几行代码,就能让 AI 记住你说过的话!控制历史长度→ 用节省 token→ 用多用户持久化→ 用。
·
在 LangChain 框架中,ConversationBufferMemory 是最基础、最常用的短期记忆(会话记忆)组件之一。它将整个对话历史以原始文本形式保存在内存中,并在每次调用 LLM 时自动将其注入到提示词(prompt)中,从而让模型“记住”之前的对话内容。
一、什么是 ConversationBufferMemory?
- 作用:缓存完整的对话历史(用户输入 + AI 回复),作为上下文传递给大模型。
- 存储位置:内存中(非持久化) → 属于短期记忆,程序重启后丢失。
- 适用场景:单次会话内的多轮对话(如聊天机器人)。
- 特点:简单、高效,但随着对话变长,会占用更多 token,可能超出模型上下文长度限制。
二、基本使用方法
步骤概览:
- 导入所需模块
- 创建
ConversationBufferMemory - 构建
LLMChain或ConversationChain - 调用
.predict()或.invoke()进行多轮对话
示例代码(使用 ConversationChain)
from langchain_community.llms import Ollama
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
# 1. 初始化 LLM(这里以本地 Ollama 的 qwen3 为例)
llm = Ollama(model="qwen3:8b")
# 2. 创建短期记忆对象
memory = ConversationBufferMemory()
# 3. 构建带记忆的对话链
conversation = ConversationChain(
llm=llm,
memory=memory,
verbose=True # 打印内部 prompt,便于调试
)
# 4. 多轮对话
response1 = conversation.predict(input="你好!我叫小明。")
print("AI:", response1)
response2 = conversation.predict(input="你还记得我的名字吗?")
print("AI:", response2)
三、与 LLMChain 手动集成(更灵活)
如果不想用 ConversationChain,也可以手动将 ConversationBufferMemory 与 LLMChain 结合:
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.memory import ConversationBufferMemory
from langchain_community.llms import Ollama
# 初始化 LLM(这里以本地 Ollama 的 qwen3 为例)
llm = Ollama(model="qwen3:8b")
# 自定义提示模板
template = """你是一个友好的助手。
以下是之前的对话记录:
{history}
现在人类说:{input}
请回答:"""
prompt = PromptTemplate(
input_variables=["history", "input"],
template=template
)
# 创建带记忆的 LLMChain
llm_chain = LLMChain(
llm=llm,
prompt=prompt,
memory=ConversationBufferMemory(memory_key="history") # 关键:绑定 memory_key
)
# 对话
print(llm_chain.invoke({"input": "我最喜欢的颜色是蓝色"}))
print(llm_chain.invoke({"input": "我刚才说我喜欢什么颜色?"}))
新版代码(使用 LCEL + RunnableWithMessageHistory + InMemoryChatMessageHistory)
示例1
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_ollama import ChatOllama
# 初始化模型
llm = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434")
# 构建带历史占位符的 prompt
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个助手。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
chain = prompt | llm
# 全局会话存储(仅用于单机测试!)
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = InMemoryChatMessageHistory()
return store[session_id]
# 封装带历史的链
chain_with_history = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="input",
history_messages_key="history",
)
# 测试:使用相同 session_id
config = {"configurable": {"session_id": "user_532"}}
print(chain_with_history.invoke({"input": "我叫小红"}, config).content)
print(chain_with_history.invoke({"input": "我刚才说我叫什么?"}, config).content)
对比:新旧写法差异
| 功能 | 旧写法(已弃用) | 新写法(推荐) |
|---|---|---|
| 链构建 | LLMChain(llm=..., prompt=...) |
prompt | llm |
| 记忆管理 | ConversationBufferMemory() |
RunnableWithMessageHistory(...) |
| 历史存储 | 内存字符串(无结构) | BaseChatMessageHistory(结构化消息) |
| 多用户支持 | ❌ 不支持 | ✅ 原生支持(通过 session_id) |
| 持久化 | 需 hack | ✅ 直接换 RedisChatMessageHistory 即可 |
| 兼容 ChatModel | 有限(需转换) | ✅ 原生支持 |
如果你仍想用 ConversationBufferMemory(临时方案)
虽然不推荐,但如果你只是本地测试、不想改太多代码,可以 暂时忽略警告(在 v1.0 前仍能运行):
import warnings
from langchain._api import LangChainDeprecationWarning
# 忽略弃用警告(仅用于开发/学习)
warnings.filterwarnings("ignore", category=LangChainDeprecationWarning)
# 然后继续使用你的旧代码...
| 问题 | 解决方案 |
|---|---|
LLMChain 弃用 |
改用 prompt | llm(LCEL) |
ConversationBufferMemory 弃用 |
改用 RunnableWithMessageHistory + InMemoryChatMessageHistory(或 Redis/SQL) |
| 想保留短期记忆功能 | 新架构完全支持,且更强大、更清晰 |
示例2
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_ollama import ChatOllama
# 初始化模型
llm = ChatOllama(model="qwen3:8b", base_url="http://localhost:11434")
# 构建带历史占位符的 prompt
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个助手。"),
MessagesPlaceholder(variable_name="history"),
("human", "{input}")
])
chain = prompt | llm
# 全局会话存储(仅用于单机测试!)
store = {}
def get_session_history(session_id: str):
if session_id not in store:
store[session_id] = InMemoryChatMessageHistory()
return store[session_id]
# 封装带历史的链
chain_with_history = RunnableWithMessageHistory(
chain,
get_session_history,
input_messages_key="input",
history_messages_key="history",
)
# 测试:使用相同 session_id
config = {"configurable": {"session_id": "user_532"}}
print(chain_with_history.invoke({"input": "我叫小明"}, config).content)
print(chain_with_history.invoke({"input": "我刚才说我叫什么?"}, config).content)

四、关键参数说明
| 参数 | 说明 |
|---|---|
memory_key |
在 prompt 中引用历史的变量名,默认为 "history" |
input_key |
用户输入字段名,默认为 "input"(通常无需修改) |
return_messages |
若设为 True,返回 BaseMessage 对象而非字符串(用于高级用途) |
五、注意事项
-
Token 限制问题
ConversationBufferMemory会把所有历史拼接进 prompt。- 如果对话很长,可能超过模型最大上下文(如 Qwen3 最大 32768 tokens)。
- 解决方案:改用
ConversationSummaryMemory(摘要记忆)或ConversationBufferWindowMemory(滑动窗口)。
-
不支持跨会话
- 内存中的数据在程序结束后丢失。
- 如需持久化,请使用
RedisChatMessageHistory+RunnableWithMessageHistory(长期记忆)。
-
不适合高并发
- 每个
ConversationBufferMemory实例只对应一个会话。 - Web 应用中需为每个用户创建独立实例。
- 每个
六、与其他 Memory 类型对比
| Memory 类型 | 存储方式 | 是否持久化 | 适合场景 |
|---|---|---|---|
ConversationBufferMemory |
完整历史(内存) | ❌ | 短对话、调试 |
ConversationBufferWindowMemory |
最近 N 轮(内存) | ❌ | 控制上下文长度 |
ConversationSummaryMemory |
历史摘要(内存) | ❌ | 长对话,节省 token |
RedisChatMessageHistory |
Redis 存储 | ✅ | 多用户、生产环境 |
SQLChatMessageHistory |
数据库存储 | ✅ | 需要审计/分析 |
总结
ConversationBufferMemory是 LangChain 中实现短期对话记忆的最简单方式,适用于单次会话内的上下文保持。只需几行代码,就能让 AI 记住你说过的话!
如果你需要:
- 控制历史长度 → 用
ConversationBufferWindowMemory - 节省 token → 用
ConversationSummaryMemory - 多用户持久化 → 用
RedisChatMessageHistory+RunnableWithMessageHistory
更多推荐

所有评论(0)