第6讲:记忆管理(Memory)系统——赋予Agent“灵魂”与“阅历”
欢迎回到《Python + AI Agent 实战开发完全指南》!
在前五讲中,我们构建了一个具备"大脑"(ReAct推理)、“眼睛耳朵”(输入)和"手脚"(Tool Calling)的Agent。但如果你仔细观察它的行为,会发现它有一个致命的弱点:它没有记忆。
一旦对话轮数超过了API的上下文窗口,或者你想让Agent在明天继续昨天的对话,它就会一脸茫然。这就好比一个只有短期记忆的金鱼,永远无法积累"阅历"。
在这一讲中,我们将为Agent装上记忆系统(Memory)。我们将抛弃已被官方弃用的旧版ConversationBufferMemory,全面拥抱LangChain最新的LangGraph Checkpoint(检查点)机制来实现短期记忆,让你的Agent从此具备"人格"和"经验"。
一、核心痛点:为什么你的Agent总是"失忆"?
在第3讲和第5讲的代码中,我们是通过一个简单的messages列表来维持对话的。这种方式存在两个巨大的工程缺陷:
- Token爆炸(Context Length Overflow):大模型的上下文窗口是有限的。如果你把几百轮对话全塞进去,不仅速度慢、费用高,还会直接报错
context length exceeded。 - 状态丢失(Stateless):目前的代码运行完就结束了。重启程序后,Agent完全不记得你是谁,之前聊过什么。
要解决这两个问题,我们需要引入短期记忆和长期记忆的双层架构。
二、筑牢地基:短期记忆(基于LangGraph Checkpoint)
短期记忆对应的是Working Memory,也就是我们常说的"上下文"。在最新的LangChain生态中,官方强烈推荐使用LangGraph提供的Checkpointers来自动管理对话历史。
2.1 什么是Checkpointer?
你可以把它理解为一个"存档点"。每次Agent执行一步操作,Checkpointer就会自动把当前的messages状态保存到内存或数据库中。下次用户提问时,它会通过一个唯一的thread_id(线程ID)自动加载之前的对话历史。
2.2 安装必要的依赖
pip install langgraph langchain-openai
三、实战:基于LangGraph的完整记忆系统
3.1 核心架构设计
我们将采用您提供的代码架构,这是一个非常标准且优雅的LangGraph状态机实现,完美解决了Agent的短期记忆问题。
3.2 完整代码实现
import os
os.environ["PYTHONUTF8"] = "1"
# --- 1. 配置区 ---
# 你的API密钥和模型配置
API_KEY = "sk-***********************" # 请替换为你的实际API密钥
BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"
MODEL = "qwen-turbo"
# --- 2. 初始化大模型 ---
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
api_key=API_KEY,
base_url=BASE_URL,
model=MODEL
)
# --- 3. 构建LangGraph状态机 ---
from langchain_core.messages import HumanMessage, SystemMessage
from langgraph.graph import StateGraph, MessagesState, START
from langgraph.checkpoint.memory import InMemorySaver
def chat_node(state: MessagesState):
"""
核心对话逻辑
state["messages"]: 包含了该会话ID下的所有历史消息
"""
# 1. 构建系统提示词
system_prompt = SystemMessage(content="你是一个友好的聊天助手")
# 2. 拼接消息:系统指令 + 历史对话 + 当前输入
all_msg = [system_prompt] + state["messages"]
# 3. 调用模型
resp = llm.invoke(all_msg)
# 4. 返回新消息,LangGraph会自动将其存入state["messages"]
return {"messages": resp}
# --- 4. 编译图 (Graph Compilation) ---
checkpointer = InMemorySaver() # 使用内存存储检查点(短期记忆)
builder = StateGraph(MessagesState)
builder.add_node("chat", chat_node)
builder.add_edge(START, "chat")
# 编译图,注入记忆机制
chat_graph = builder.compile(checkpointer=checkpointer)
3.3 交互测试
# --- 5. 主交互循环 ---
if __name__ == "__main__":
print(" 智能体已启动!(输入'exit'退出)")
# 会话配置:同一个thread_id共享记忆
cfg = {"configurable": {"thread_id": "session_001"}}
while True:
user_input = input("\n你: ")
if user_input.lower() in ["exit", "quit"]:
break
# 调用图执行
result = chat_graph.invoke(
{"messages": [HumanMessage(content=user_input)]},
config=cfg
)
# 提取并打印回复
ai_response = result["messages"][-1].content
print(f" 助手: {ai_response}")
四、关键特性分析
4.1 会话隔离机制
通过不同的thread_id,Agent可以轻松区分不同用户的会话:
# 用户A的会话
cfg_user_a = {"configurable": {"thread_id": "user_a_123"}}
# 用户B的会话
cfg_user_b = {"configurable": {"thread_id": "user_b_456"}}
4.2 自动上下文管理
LangGraph自动处理对话历史的拼接和存储,开发者无需手动维护消息列表。
4.3 状态持久化
通过Checkpointer机制,对话状态在多次调用间自动保持。
五、工程建议与最佳实践
5.1 生产环境配置
- Checkpointer选择:在生产环境中,建议使用
SqliteSaver或PostgresSaver替代InMemorySaver,实现真正的持久化存储。 - 错误处理:添加适当的异常处理机制,确保系统稳定性。
- 性能优化:对于长对话,考虑实现对话摘要功能,控制上下文长度。
5.2 安全配置
- API密钥管理:将API密钥存储在环境变量或配置文件中,避免硬编码。
- 输入验证:对用户输入进行必要的验证和过滤。
六、本节小结
今天我们成功为Agent构建了完整的短期记忆系统:
- 状态管理:通过LangGraph的
MessagesState,我们实现了自动化的对话历史管理。 - 会话隔离:利用
thread_id机制,确保不同用户的对话相互独立。 - 持久化存储:通过Checkpointer,实现了对话状态的自动保存和恢复。
核心价值:这段代码证明了Agent能够通过thread_id区分不同用户的会话,并在同一个会话中记住用户的信息,实现了真正的个性化对话体验。
七、扩展思考
- 长期记忆:如何结合向量数据库实现跨会话的知识存储和检索?
- 记忆清理:如何实现对话历史的自动清理,防止内存溢出?
- 分布式部署:在微服务架构中,如何实现跨节点的会话状态同步?
八、作业练习
- 实践任务:将本讲的代码部署为一个Web服务,支持多用户同时访问。
- 扩展挑战:为Agent添加对话摘要功能,当对话过长时自动生成摘要。
- 性能测试:测试不同长度对话对系统性能的影响,找出最优的上下文长度。
下一讲预告:
在第7讲《RAG(检索增强生成)实战》中,我们将结合今天搭建的记忆系统,接入企业内部的PDF、Word文档,打造一个真正懂业务的私有知识库问答机器人。
更多推荐


所有评论(0)