State 不是变量,是"快照" Messages 是特殊的,自动处理 持久化是"自动驾驶" Short-term memory = Checkpointer + thread_id 配置一次 checkpointer,每次调用带上 thread_id,LangGraph 自动处理状态的保存、恢复、版本管理。就像浏览器给每个网站分配独立的 localStorage,刷新页面数据还在。 一个 thread_id = 一个独立的会话上下文
基于 Short-term memory 文档,按"一个模块 = 一个可独立约束的知识点"原则划分:
| 模块 | 核心知识点 | 为什么独立 |
|---|---|---|
| 1. Checkpointer 基础配置 | checkpointer 参数注入、InMemorySaver(开发)vs PostgresSaver(生产)、thread_id 会话隔离 | 记忆系统的基础,最核心的配置模式 |
| 2. 自定义 Agent State | 继承 AgentState 扩展自定义字段、state_schema 参数、invoke 时传入自定义状态 | State 结构定义是独立的知识点,与 checkpointer 配置分离 |
| 3. 修剪消息(Trim Messages) | @before_model 中间件、RemoveMessage + REMOVE_ALL_MESSAGES、保留最近 N 条消息的策略 | 一种独立的上下文管理策略,有专属的代码模式 |
| 4. 删除消息(Delete Messages) | RemoveMessage(id=m.id) 删除指定消息、REMOVE_ALL_MESSAGES 清空全部、@after_model 中间件 | 与修剪不同的操作模式(指定删除 vs 保留最后 N 条),删除后需验证消息合法性 |
| 5. 摘要消息(Summarize Messages) | SummarizationMiddleware 内置中间件、trigger 和 keep 参数配置 | 使用内置中间件,代码模式与手动修剪/删除完全不同 |
| 6. 工具中访问记忆 | runtime.state 读取、Command(update=...) 写入、ToolRuntime 泛型指定 State 类型 | 工具是独立的访问入口,代码模式不同于中间件 |
| 7. Prompt 中访问记忆 | @dynamic_prompt 读取 context、注入个性化 system prompt | 动态 prompt 是独立的访问入口 |
| 8. Before Model 中访问记忆 | @before_model 中间件、模型调用前处理 State、返回 dict 更新 State | 与 after_model 对称但执行时机不同,策略可不同 |
| 9. After Model 中访问记忆 | @after_model 中间件、模型调用后验证/过滤响应、返回 dict 删除消息 | 执行时机在模型返回之后,典型用途是内容过滤 |
约束:LangChain Checkpointer 基础配置的代码规范
技术边界
- 短期记忆通过
checkpointer参数注入create_agent,在每次invoke时自动持久化 State - 同一
thread_id的消息自动拼接为完整对话历史,不同thread_id完全隔离 - 开发/测试用
InMemorySaver(进程重启即丢失),生产环境必须用数据库 checkpointer PostgresSaver需要langgraph-checkpoint-postgres包,通过from_conn_string(DB_URI)初始化PostgresSaver需调用.setup()自动建表,用完需关闭(推荐用with语句)- checkpoint 在每次
invoke或工具调用完成后自动保存,每次步骤开始时自动读取
生成要求
1. 开发环境
from langgraph.checkpoint.memory import InMemorySaver
from langchain.agents import create_agent
agent = create_agent(
"gpt-5.4",
tools=[get_user_info],
checkpointer=InMemorySaver(),
)
agent.invoke(
{"messages": [{"role": "user", "content": "Hi! My name is Bob."}]},
{"configurable": {"thread_id": "1"}},
)
2. 生产环境
from langgraph.checkpoint.postgres import PostgresSaver
DB_URI = "postgresql://postgres:postgres@localhost:5442/postgres?sslmode=disable"
with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
checkpointer.setup()
agent = create_agent(
"gpt-5.4",
tools=[get_user_info],
checkpointer=checkpointer,
)
3. thread_id 管理
thread_id通过config={"configurable": {"thread_id": "..."}}传入invoke- 同一会话复用相同
thread_id,新会话用新thread_id thread_id字符串不可为空
反例
- ❌ 生产环境用
InMemorySaver- ✅ FIX:替换为
PostgresSaver、SqliteSaver等持久化实现
- ✅ FIX:替换为
- ❌ 同一会话多次调用使用不同
thread_id- ✅ FIX:固定同一
thread_id
- ✅ FIX:固定同一
- ❌
PostgresSaver不调.setup()直接使用- ✅ FIX:调用
.setup()自动建表
- ✅ FIX:调用
- ❌
PostgresSaver不用with语句管理生命周期- ✅ FIX:使用
with PostgresSaver.from_conn_string(...) as checkpointer:
- ✅ FIX:使用
验收标准
-
checkpointer已显式传入create_agent -
invoke的config中包含thread_id - 同一会话复用相同
thread_id - 生产环境使用数据库 checkpointer
约束:LangChain 自定义 Agent State 的代码规范
技术边界
- 默认 State 是
AgentState,只包含messages字段 - 自定义 State 通过继承
AgentState扩展,必须是TypedDict - 通过
create_agent的state_schema参数传入自定义 State - 自定义 State 的字段在
invoke时与messages并列传入 - 自定义字段被持久化到 checkpoint,同一
thread_id后续调用可访问
生成要求
from langchain.agents import create_agent, AgentState
class CustomAgentState(AgentState):
user_id: str
preferences: dict
agent = create_agent(
"gpt-5.4",
tools=[get_user_info],
state_schema=CustomAgentState,
checkpointer=InMemorySaver(),
)
result = agent.invoke(
{
"messages": [{"role": "user", "content": "Hello"}],
"user_id": "user_123",
"preferences": {"theme": "dark"},
},
{"configurable": {"thread_id": "1"}},
)
反例
- ❌ 用 Pydantic
BaseModel或dataclass定义 State- ✅ FIX:必须使用
TypedDict,继承AgentState
- ✅ FIX:必须使用
- ❌ 自定义字段与
messages同名- ✅ FIX:
messages是保留字段,不可覆盖
- ✅ FIX:
- ❌
invoke传入自定义字段但不定义state_schema- ✅ FIX:先定义
CustomAgentState(AgentState)再传入state_schema
- ✅ FIX:先定义