系列目标:30 天从 LangChain 入门到企业级部署
今日任务:理解 Memory 的作用 → 掌握ConversationBufferMemory→ 构建带上下文记忆的聊天机器人!
💬 一、为什么需要 Memory?
你有没有遇到过这种情况:
用户: “我叫小明。”
AI: “你好,小明!”
用户: “我今年多大了?”
AI: “我不知道你的年龄。” ❌
问题出在哪?AI 没有记住上文!
默认情况下,每次调用 LLM 都是“全新对话”,它看不到历史。
而 Memory 就是 LangChain 提供的“对话记忆”机制,让 AI 能基于上下文连续对话。
✅ 今天,我们就来给 AI 装上“短期记忆”!
🧠 二、LangChain 中的 Memory 类型(入门选这个)
LangChain 提供多种 Memory,新手推荐从 ConversationBufferMemory 开始:
| Memory 类型 | 特点 | 适用场景 |
|---|---|---|
ConversationBufferMemory ✅ | 保存全部对话历史 | 简单聊天、短对话 |
ConversationSummaryMemory | 用 LLM 自动总结历史 | 长对话(节省 token) |
ConversationBufferWindowMemory | 只保留最近 N 轮 | 控制上下文长度 |
VectorStoreRetrieverMemory | 用向量库存长期记忆 | 复杂 Agent(后续讲) |
🔔 Day 5 重点:
ConversationBufferMemory
🛠️ 三、动手实践:构建一个能记住名字的聊天机器人
步骤 1:安装依赖(如果还没装)
pip install langchain-ollama
步骤 2:编写带 Memory 的 Chain
# day5_memory_chatbot.py
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
# 1. 初始化本地模型
llm = ChatOllama(model="qwen:7b", temperature=0.7)
# 2. 创建 Memory(保存对话历史)
memory = ConversationBufferMemory(
memory_key="history", # 在 prompt 中引用的变量名
return_messages=True # 返回 Message 对象(而非字符串)
)
# 3. 定义 Prompt 模板(必须包含 {history} 占位符!)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个友好的聊天助手,会记住用户之前说过的话。"),
MessagesPlaceholder(variable_name="history"), # 插入对话历史
("human", "{input}") # 当前用户输入
])
# 4. 构建 ConversationChain(专为对话设计的 Chain)
chain = ConversationChain(
llm=llm,
memory=memory,
prompt=prompt,
verbose=True # 打印内部过程(调试用)
)
# 5. 多轮对话测试
print("🤖 你好!我是你的 AI 助手,请问怎么称呼你?")
while True:
user_input = input("👤 你:")
if user_input.lower() in ["退出", "quit", "exit"]:
break
response = chain.invoke({"input": user_input})
print(f"🤖 AI:{response['response']}")
▶️ 对话示例:
🤖 你好!我是你的 AI 助手,请问怎么称呼你?
👤 你:我叫小明。
🤖 AI:你好,小明!很高兴认识你 😊
👤 你:我今年 25 岁。
🤖 AI:好的,小明!25 岁正是充满活力的年纪呢!
👤 你:我刚才说了我多大吗?
🤖 AI:说了呀!你说你今年 25 岁 👍
✅ 成功记住上下文!这就是 Memory 的魔力!
🔍 四、关键细节解析
1. MessagesPlaceholder 是什么?
- 它会自动把
memory中的历史消息插入到 prompt 的指定位置 - 必须配合
return_messages=True使用(否则会报错)
2. ConversationChain vs 普通 Chain?
ConversationChain是 LangChain 专门为对话场景封装的 Chain- 内部自动处理
input→history→output→ 更新 memory 的流程
3. verbose=True 有什么用?
- 打印完整的 prompt(含历史),方便调试
- 生产环境记得关掉
🔄 五、切换模型?依然只需一行!
# OpenAI 用户:
# from langchain_openai import ChatOpenAI
# llm = ChatOpenAI(model="gpt-3.5-turbo")
# Ollama 用户(本地免费):
from langchain_ollama import ChatOllama
llm = ChatOllama(model="qwen:7b")
✅ 同一套 Memory 逻辑,无缝切换后端!
⚠️ 六、注意事项 & 优化建议
| 问题 | 建议 |
|---|---|
| 对话越长越慢/越贵 | 改用 ConversationBufferWindowMemory(k=3) 只记最近 3 轮 |
| 上下文超出模型长度 | 监控 token 数,或改用 ConversationSummaryMemory |
| 中文模型记不住细节 | 使用 Qwen、GLM 等中文优化模型;降低 temperature |
| 不想让 AI 记住敏感信息 | 对话结束后清空 memory:memory.clear() |
🔒 安全提示:生产环境中,务必对 memory 做生命周期管理(如按会话 ID 隔离)。
📦 七、配套代码结构
langchain-30-days/
└── day5/
└── memory_chatbot.py # 带记忆的多轮对话机器人
📥 代码仓库:github.com/yourname/la…
📝 八、今日小结
- ✅ 理解了 Memory 的作用:让 AI 记住上下文
- ✅ 学会了
ConversationBufferMemory基础用法 - ✅ 掌握了
ConversationChain构建多轮对话 - ✅ 实现了能记住名字和年龄的聊天机器人
- ✅ 知道了如何控制记忆长度与安全