2、短期记忆
LangChain1.x 的短期记忆是三者的组合:
State(会话内部状态) + Checkpointer(持久化机制) + Thread ID(会话作用域)
- State :默认 存储历史消息列表messages ,通过State 管理历史消息
- Checkpointer :负责将State 作为检查点持久化保存,检查点是某个时刻的State 快照
- Thread ID :用于唯一标识State ,LangChain运行时会按照 thread_id 读写State快照
这就像玩 RPG 游戏时的"自动存档":你不需要手动保存,系统在关键节点自动记录,下次进入游 戏随时可以从上次的存档点继续。
1 基于内存的持久化器
这是最便捷的使用方式,适合快速测试或调试。
举例1:没有记忆
from langchain.agents import create_agent
from langchain.messages import HumanMessage
from dotenv import load_dotenv
load_dotenv(verbose=True)
agent = create_agent(
model="deepseek:deepseek-v4-pro",
tools=[]
)
print("\n第一轮对话:")
response1 = agent.invoke({
"messages": [
HumanMessage("我叫张三")
]
})
print(f"Agent: {response1['messages'][-1].content}")
print("\n第二轮对话:")
response2 = agent.invoke({
"messages": [
HumanMessage("我叫什么?")
]
})
print(f"Agent: {response2['messages'][-1].content}")
第一轮对话:
Agent: 你好,张三!有什么我可以帮你的吗?
第二轮对话:
Agent: 我目前不知道您的名字,因为我看不到您的个人信息。您可以告诉我您叫什么,我会记住并在对话中称呼您。
举例2:拥有记忆
步骤1:第一二轮对话
from langchain.agents import create_agent
from langchain.messages import HumanMessage
from dotenv import load_dotenv
from langgraph.checkpoint.memory import InMemorySaver
load_dotenv(verbose=True)
checkpointer = InMemorySaver() # 1.创建了内存级别的会话记忆
agent = create_agent(
model="deepseek:deepseek-v4-pro",
tools=[],
checkpointer=checkpointer, # 2.让agent具备了存储的能力
)
#3.同一个thread_id共享记忆的
config={
"configurable":{
"thread_id":"1"
}
}
print("\n第一轮对话:")
response1 = agent.invoke({
"messages": [
HumanMessage("我叫张三")
]
},
config=config)
print(f"Agent: {response1['messages'][-1].content}")
print("\n第二轮对话:")
response2 = agent.invoke({
"messages": [
HumanMessage("我叫什么?")
]
},
config=config)
print(f"Agent: {response2['messages'][-1].content}")
第一轮对话:
Agent: 你好,张三!有什么可以帮你的吗?
第二轮对话:
Agent: 你叫张三。
说明:你只需传入 checkpointer 和 config,Agent 就能自然具备连续对话能力
步骤2:第三轮对话
print("\n第三轮对话:")
response3 = agent.invoke({
"messages": [
HumanMessage("我叫啥?")
]
},
config=config1)
print(f"Agent: {response4['messages'][-1].content}")
说明:第三轮对话中的 "我刚才问了什么问题?" 就能在第二轮存储的消息历史中找到答案。所有消息 历史都会自动追加到 AgentState 的 messages 字段中,无需手动维护。
步骤3:更新线程ID
而如果更新线程ID,则会重新开启对话:
config1={
"configurable":{
"thread_id":"2"
}
}
print("\n第三轮对话:")
response3 = agent.invoke({
"messages": [
HumanMessage("我叫啥?")
]
},
config=config1)
print(f"Agent: {response4['messages'][-1].content}")
Agent: 我不知道你的名字哦,你可以告诉我,我就可以用名字称呼你啦。
说明:thread_id 隔离不同会话空间。
关键步骤说明
第1步:初始化记忆引擎: checkpointer = InMemorySaver() ------创建一个内存级的记忆存储
注意:InMemorySaver内存中保存,进程结束就丢失数据,适合测试。生产环境可换成数据库持 久化的 SqliteSaver 、 PostgresSaver 等
第2步:绑定 Agent:在 create_agent 时传入 checkpointer ,让 Agent 具备状态存储能力。
第3步:设定会话 ID:通过 config = {"configurable": {"thread_id": "1"}} 为每次调用指定线程标识。 同一个 thread_id 共享记忆,不同 thread_id 完全隔离。
# 会话 1
config1 = {"configurable": {"thread_id": "1"}}
agent.invoke({...}, config=config1)
# 会话 2
config2 = {"configurable": {"thread_id": "2"}}
agent.invoke({...}, config=config2)
# 两个会话完全独立
thread_id 是记忆管理的核心开关:在会话2里询问会话1的会话信息,Agent 会表示不知道------因为双 方记忆空间完全隔离。
生产环境中:
场景1:多用户聊天
不同 thread_id = 不同会话,Agent 能正确记住每个会话的内容
agent = create_agent(
model=model,
tools=[],
checkpointer=InMemorySaver()
)
# 用户 Alice
config_alice = {
"configurable": {
"thread_id": "user_alice"
}
}
agent.invoke(
{"messages": [...]},
config_alice
)
# 用户 Bob
config_bob = {
"configurable": {
"thread_id": "user_bob"
}
}
agent.invoke(
{"messages": [...]},
config_bob
)
# 两个会话完全独立
场景2:同一用户的不同任务
# 任务 1:写代码
config_task1 = {
"configurable": {
"thread_id": "task_coding"
}
}
agent.invoke(
{"messages": [...]},
config_task1
)
# 任务 2:写文档
config_task2 = {
"configurable": {
"thread_id": "task_docs"
}
}
agent.invoke(
{"messages": [...]},
config_task2
)
工作原理
内存保存了什么?
agent.invoke(
{
"messages": [
{
"role": "user",
"content": "你好"
}
]
},
config
)
# InMemorySaver 保存:
# {
# "thread_id": "xxx",
# "messages": [
# HumanMessage("你好"),
# AIMessage("你好!有什么可以帮助你的吗?")
# ]
# }
agent.invoke(
{
"messages": [
{
"role": "user",
"content": "天气"
}
]
},
config
)
# InMemorySaver 更新:
# {
# "thread_id": "xxx",
# "messages": [
# HumanMessage("你好"),
# AIMessage("你好!有什么可以帮助你的吗?"),
# HumanMessage("天气"),
# AIMessage("...")
# ]
# }
自动追加历史
# 你只需要传新消息
agent.invoke(
{"messages": [{"role": "user", "content": "新问题"}]},
config
)
此时,checkpointer 自动:
① 读取之前的历史
② 追加新消息
③ 调用模型(传入完整历史)
④ 保存新的历史
说明:checkpointer 会自动管理历史
常见问题
为什么 Agent 不记得?
✅ 是否添加了 checkpointer=InMemorySaver() ?
✅ 是否传入了 config 参数?
✅ 两次调用的 thread_id 是否相同?
# ❌ 错误:没有 checkpointer
agent = create_agent(
model=model,
tools=[]
)
agent.invoke({...}) # 不会记住
# ❌ 错误:没有 config
agent = create_agent(
model=model,
tools=[],
checkpointer=InMemorySaver()
)
agent.invoke({...}) # 不会记住
# ❌ 错误:thread_id 不同
agent.invoke(
{...},
config={
"configurable": {
"thread_id": "1"
}
}
)
agent.invoke(
{...},
config={
"configurable": {
"thread_id": "2"
}
}
) # 不同会话
# ✅ 正确
agent = create_agent(
model=model,
tools=[],
checkpointer=InMemorySaver()
)
config = {
"configurable": {
"thread_id": "1"
}
}
agent.invoke({...}, config)
agent.invoke({...}, config) # 记得!
2、InMemorySaver 会丢失数据吗?
会! InMemorySaver 只保存在内存中
- ✅ 同一进程内有效(不支持跨进程共享)
- ❌ 程序重启后丢失(或进程重启后丢失)
- ❌ 不同进程无法共享
解决方案:持久化(SQLite、PostgreSQL)
3、内存会无限增长吗?
会! 默认情况下,InMemorySaver 会保存所有消息
问题:
- 消息越来越多(无限增长,需要管理上下文)
- token消耗增加,甚至会超过模型的 token 限制
- 响应速度变慢、成本增加
解决方案:上下文管理(修剪、摘要)
4、如何清空某个会话的历史?
目前 InMemorySaver 没有提供删除 API。
临时方案:
- 使用新的 thread_id
- 或重新创建 Agent