Chapter 7 · Persistence: Checkpointer and Thread
Chapter goals:
- Understand the importance of persistence in Agent services
- Master three Checkpointer implementations and their applicable scenarios
- Learn to use thread_id for multi-session management
- Implement checkpoint resume and time travel
7.1 Why Do We Need Persistence?
Agent applications typically require:
- Session continuity: Multi-turn conversations maintain context
- Checkpoint resume: Recover execution after service restart
- Human-in-the-loop: Pause for manual approval
- Time travel: Look back to any historical state
7.2 Checkpointer Types
python
from langgraph.checkpoint.memory import MemorySaver
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.checkpoint.postgres import PostgresSaver
# In-memory (development only)
memory_saver = MemorySaver()
# SQLite (simple deployment)
sqlite_saver = SqliteSaver.from_conn_string("checkpoints.db")
# PostgreSQL (production)
postgres_saver = PostgresSaver.from_conn_string(
"postgresql://user:pass@localhost:5432/agent"
)7.2.1 Checkpointer Comparison
| Checkpointer | Use Case | Persistence | Scalability |
|---|---|---|---|
| MemorySaver | Development/testing | In-memory | Single process |
| SqliteSaver | Small production | File-based | Single node |
| PostgresSaver | Large production | Database | Distributed |
7.3 Thread Management
thread_id identifies separate conversation sessions:
python
# Different threads = different conversations
config = {"configurable": {"thread_id": "user_123"}}
result = graph.invoke({"messages": [HumanMessage("Hello")]}, config=config)
# Same thread = continuous conversation
result = graph.invoke({"messages": [HumanMessage("Tell me more")]}, config=config)7.3.1 Thread Lifecycle
python
# Get thread history
history = list(graph.list_threads())
# Get specific thread checkpoints
checkpoints = list(graph.list_checkpoints(thread_id="user_123"))
# Get specific checkpoint
checkpoint = graph.get_tuple(Config({"configurable": {"thread_id": "user_123", "checkpoint_id": "123"}}))7.4 Human-in-the-Loop
Pause execution for human approval:
python
from langgraph.types import interrupt
def human_review_node(state: AgentState) -> dict:
# Pause and wait for approval
approval = interrupt({
"question": "Approve this response?",
"proposal": state["messages"][-1].content
})
if approval.get("approved"):
return {"approved": True}
else:
return {"approved": False, "feedback": approval.get("feedback")}7.4.1 Resume from Checkpoint
python
# Save current state
checkpoint = graph.invoke(current_state, config)
# Later, resume with modifications
updated_config = Config({
"configurable": {
"thread_id": "user_123",
"checkpoint_id": checkpoint["config"]["configurable"]["checkpoint_id"]
}
})
# Resume with human input
result = graph.invoke(
{"approval": True},
config=updated_config
)7.5 Time Travel
Look back to any historical state:
python
# Get all checkpoints for a thread
checkpoints = list(graph.list_checkpoints(
config={"configurable": {"thread_id": "user_123"}}
))
# Replay from specific checkpoint
replayed_state = graph.get_state(
Config({
"configurable": {
"thread_id": "user_123",
"checkpoint_id": checkpoints[2]["checkpoint_id"]
}
})
)Chapter Summary
- Persistence: Essential for session continuity and checkpoint resume;
- Checkpointer Types: Memory (dev), SQLite (small prod), PostgreSQL (large prod);
- Thread Management:
thread_idseparates conversations; - Human-in-the-Loop:
interrupt()pauses for approval; - Time Travel: Replay from any historical checkpoint.
🛠️ Hands-on Practice
Implement SQLite persistence and verify conversation continuity across process restarts.
Add human approval checkpoint before sending messages to external APIs.
Build a "undo" feature that replays from previous checkpoints.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. Which checkpointer is suitable for production deployment?
2. What does thread_id separate?
3. How do you pause execution for human approval?
4. What is time travel in LangGraph?