让Agent记住对话
你将学会: 用 checkpointer + thread_id 做多轮对话。
前置: L02。L01 里你已经见过:连续两次 model.invoke 不会记住名字。
短期记忆 = 这一次会话里的消息历史,存在图的 state 里,靠 checkpointer 按 thread_id 存取。
长期记忆 = 跨会话的事实(L11 的 AGENTS.md、LangGraph Store),本课不做。
InMemorySaver 只存在内存,关掉进程就忘。先用它把机制跑通。
完整代码
from dotenv import load_dotenv
load_dotenv()
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langgraph.checkpoint.memory import InMemorySaver
model = init_chat_model(
"deepseek:deepseek-chat",
temperature=0.5,
max_tokens=2500,
timeout=300,
max_retries=6,
)
agent = create_agent(
model=model,
tools=[],
system_prompt="记住用户说过的个人信息,之后直接用,不要说你没记住。",
checkpointer=InMemorySaver(),
)
cfg_a = {"configurable": {"thread_id": "user-a"}}
cfg_b = {"configurable": {"thread_id": "user-b"}}
print("A1 =>", agent.invoke(
{"messages": [{"role": "user", "content": "我叫林舟,住杭州。"}]},
config=cfg_a,
)["messages"][-1].content)
print("A2 =>", agent.invoke(
{"messages": [{"role": "user", "content": "我叫什么?住哪?"}]},
config=cfg_a,
)["messages"][-1].content)
print("B1 =>", agent.invoke(
{"messages": [{"role": "user", "content": "我叫什么?"}]},
config=cfg_b,
)["messages"][-1].content)
A2 应能答出林舟 / 杭州。B1 是另一个会话,不应知道。
常见翻车
| 现象 | 处理 |
|---|---|
| 第二轮仍不知道 | 漏了 checkpointer,或两次 thread_id 不一样 |
| 两个用户串台 | 不要共用一个 thread_id,用 f"{user_id}:{session_id}" |
| 重启程序后忘了 | 正常。本地持久化用 SqliteSaver(L10 / 仓库 Sqlite-checkpointer生产持久化.py) |
长对话会撑满上下文:修剪、删除、摘要在仓库 06-记忆与状态/Short-term-memory短期记忆.py。先掌握 thread,再优化长度。
练习
- 第三轮问 A:「用我住的城市写一句旅游推荐」,确认仍记得杭州。
- 故意把 A2 的
thread_id改成user-a-typo,验证记忆消失。
本章验收
- 能解释
thread_id是干什么的 - 两轮同 thread 能记住,不同 thread 隔离
- 知道 InMemorySaver 不能用于生产
对照仓库:06-记忆与状态/Short-term-memory短期记忆.py、01-快速入门/Quickstart快速入门.py
下一课:结构化输出
JavaWeb
Spring
MyBatis
linux
消息队列
JavaSE
工具
片段
AI
搜索
dy