大家好,我是链上杯子(CSDN:链上杯子)。

失业一年了,天天想着怎么翻身。上节课用 Chains 串起多步生成后,我最想解决的就是:怎么让 AI 记住前面说了什么?手动传 messages 列表虽然能行,但代码一长就乱。LangChain 的 Memory 组件把这件事彻底简化,几行代码就能让对话有上下文。第一次看到模型接上上轮话题继续聊,感觉像真的在和一个有记忆的伙伴互动。

本课目标
学会使用 LangChain 的 Memory 机制(尤其是 ConversationBufferMemory 和 ConversationBufferWindowMemory),结合 ConversationChain 实现真正的多轮连续对话。
学完这节课,你就能轻松构建“有记忆的聊天机器人”,AI 会自动记住历史,不用手动管理列表。

核心代码实战

1. 最基础 ConversationChain + ConversationBufferMemory
from langchain_openai import ChatOpenAI
from langchain_classic.chains import ConversationChain
from langchain_classic.memory import ConversationBufferMemory

# 初始化模型(替换成你的真实 Key)
llm = ChatOpenAI(
    openai_api_key="",   # ←←← 这里替换成你的 DeepSeek API Key
    openai_api_base="https://api.deepseek.com/v1",
    model="deepseek-chat",
    temperature=0.7
)

# 创建记忆(ConversationBufferMemory 是最简单的一种,完整保存所有历史)
memory = ConversationBufferMemory()

# 创建带记忆的对话链
conversation = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True   # 打开 verbose 会打印内部思考过程,便于调试
)

# 第一轮对话
print("第一轮:")
response1 = conversation.predict(input="我最喜欢的电影是《盗梦空间》")
print("AI:", response1)

# 第二轮(会自动记住上一轮)
print("\n第二轮:")
response2 = conversation.predict(input="你觉得它最震撼的点是什么?")
print("AI:", response2)

# 第三轮(继续接上)
print("\n第三轮:")
response3 = conversation.predict(input="那你能帮我脑暴一个类似风格的短故事开头吗?")
print("AI:", response3)

运行后会看到模型在第二、三轮自动引用《盗梦空间》,上下文连贯。

小知识点

  • ConversationBufferMemory:最基础记忆类型,完整保存所有对话历史(适合短对话)。
  • ConversationChain:内置了“Human: {input} \n AI:” 的模板 + 自动记忆管理。
  • predict(input=...):直接输入用户消息,返回 AI 回复,同时自动更新记忆。
2. 限制记忆长度(防止 token 超限)—— ConversationBufferWindowMemory
from langchain_classic.memory import ConversationBufferWindowMemory

# 只记住最近 3 轮对话(k=3 表示窗口大小)
memory_window = ConversationBufferWindowMemory(k=3)

conversation_window = ConversationChain(
    llm=llm,
    memory=memory_window,
    verbose=True
)

# 连续问 5 轮,看是否只记住最近 3 轮
for i in range(1, 6):
    user_msg = f"这是第 {i} 轮,我在测试记忆窗口。你记得前面说了什么吗?"
    print(f"\n第 {i} 轮输入:{user_msg}")
    reply = conversation_window.predict(input=user_msg)
    print("AI:", reply)

效果:到第 4、5 轮时,AI 只会记住第 2-4 轮(窗口滑动),早期内容被自动遗忘,节省 token。

3. 互动版 + 保存/加载记忆(结合文件)
import json
import os
from langchain_core.messages import HumanMessage, AIMessage
from langchain_classic.memory import ConversationBufferMemory

# 文件路径
MEMORY_FILE = "conversation_memory.json"

# 加载记忆(如果存在)
memory = ConversationBufferMemory()
if os.path.exists(MEMORY_FILE):
    try:
        with open(MEMORY_FILE, "r", encoding="utf-8") as f:
            saved = json.load(f)
        # 恢复历史
        restored_messages = []
        for msg in saved:
            if msg["type"] == "human":
                restored_messages.append(HumanMessage(content=msg["content"]))
            elif msg["type"] == "ai":
                restored_messages.append(AIMessage(content=msg["content"]))
        memory.chat_memory.add_messages(restored_messages)
        print("已加载上次对话记忆,继续聊~")
    except Exception as e:
        print(f"加载记忆失败:{e},从新开始。")

# 创建链
conversation = ConversationChain(llm=llm, memory=memory, verbose=False)

print("=== 带记忆的多轮聊天(输入 'quit' 退出,'save' 保存记忆) ===")

while True:
    user_input = input("你:").strip()
    if user_input.lower() == "quit":
        break
    if user_input.lower() == "save":
        # 保存当前记忆到文件
        messages = memory.chat_memory.messages
        saved_data = [
            {"type": "human" if isinstance(msg, HumanMessage) else "ai", "content": msg.content}
            for msg in messages
        ]
        with open(MEMORY_FILE, "w", encoding="utf-8") as f:
            json.dump(saved_data, f, ensure_ascii=False, indent=2)
        print("记忆已保存到", MEMORY_FILE)
        continue
    
    reply = conversation.predict(input=user_input)
    print("AI:", reply)

print("\n聊天结束。")

运行多次,输入 “save” 后退出,再次运行就能继续上次话题。

小练习(2 道)

练习1(基础)
复制第1段代码,在 ConversationChain 中自定义 prompt:

  • ConversationChain(llm=llm, memory=memory, prompt=...)
  • 自定义 prompt 为:“你是一个幽默风趣的聊天伙伴,用 emoji 回复。\n当前对话:{history}\nHuman: {input}\nAI:”
    连续问 3–5 轮,看风格是否一致。

练习2(进阶)
替换为 ConversationSummaryMemory(import ConversationSummaryMemory from langchain_classic.memory):
它会自动总结历史而不是完整保存,适合长对话。
运行 6–8 轮测试,看总结是否有效(verbose=True 可看到总结过程)。
对比 BufferMemory 和 SummaryMemory 的 token 消耗差异。

本课小结

本课学习了 Memory 机制(ConversationBufferMemory、WindowMemory)和 ConversationChain,实现自动管理对话历史的多轮交互。
相比手动维护 messages 列表,Memory 更简洁、开箱即用,是构建聊天机器人必备组件。后续 Agent、RAG 也会大量用到 Memory。

下节预告

下一课:Agents 基础 —— 让 AI 自己决定下一步做什么,实现 ReAct 风格的智能代理。

欢迎在评论区贴出你的多轮对话截图、记忆保存效果,或任何问题~
如果觉得这篇有用,欢迎点赞或关注,一起玩转 LangChain!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐