LangChain 框架中,ConversationBufferMemory 是最基础、最常用的短期记忆(会话记忆)组件之一。它将整个对话历史以原始文本形式保存在内存中,并在每次调用 LLM 时自动将其注入到提示词(prompt)中,从而让模型“记住”之前的对话内容。


一、什么是 ConversationBufferMemory

  • 作用:缓存完整的对话历史(用户输入 + AI 回复),作为上下文传递给大模型。
  • 存储位置内存中(非持久化) → 属于短期记忆,程序重启后丢失。
  • 适用场景:单次会话内的多轮对话(如聊天机器人)。
  • 特点:简单、高效,但随着对话变长,会占用更多 token,可能超出模型上下文长度限制。

二、基本使用方法

步骤概览:

  1. 导入所需模块
  2. 创建 ConversationBufferMemory
  3. 构建 LLMChain 或 ConversationChain
  4. 调用 .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,也可以手动将 ConversationBufferMemoryLLMChain 结合:

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 对象而非字符串(用于高级用途)

 五、注意事项

  1. Token 限制问题

    • ConversationBufferMemory 会把所有历史拼接进 prompt。
    • 如果对话很长,可能超过模型最大上下文(如 Qwen3 最大 32768 tokens)。
    • 解决方案:改用 ConversationSummaryMemory(摘要记忆)或 ConversationBufferWindowMemory(滑动窗口)。
  2. 不支持跨会话

    • 内存中的数据在程序结束后丢失。
    • 如需持久化,请使用 RedisChatMessageHistory + RunnableWithMessageHistory(长期记忆)。
  3. 不适合高并发

    • 每个 ConversationBufferMemory 实例只对应一个会话。
    • Web 应用中需为每个用户创建独立实例。

六、与其他 Memory 类型对比

Memory 类型 存储方式 是否持久化 适合场景
ConversationBufferMemory 完整历史(内存) 短对话、调试
ConversationBufferWindowMemory 最近 N 轮(内存) 控制上下文长度
ConversationSummaryMemory 历史摘要(内存) 长对话,节省 token
RedisChatMessageHistory Redis 存储 多用户、生产环境
SQLChatMessageHistory 数据库存储 需要审计/分析

 总结

ConversationBufferMemory 是 LangChain 中实现短期对话记忆的最简单方式,适用于单次会话内的上下文保持。只需几行代码,就能让 AI 记住你说过的话!

如果你需要:

  • 控制历史长度 → 用 ConversationBufferWindowMemory
  • 节省 token → 用 ConversationSummaryMemory
  • 多用户持久化 → 用 RedisChatMessageHistory + RunnableWithMessageHistory
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐