Skip to content

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 ​

CheckpointerUse CasePersistenceScalability
MemorySaverDevelopment/testingIn-memorySingle process
SqliteSaverSmall productionFile-basedSingle node
PostgresSaverLarge productionDatabaseDistributed

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 ​

  1. Persistence: Essential for session continuity and checkpoint resume;
  2. Checkpointer Types: Memory (dev), SQLite (small prod), PostgreSQL (large prod);
  3. Thread Management: thread_id separates conversations;
  4. Human-in-the-Loop: interrupt() pauses for approval;
  5. Time Travel: Replay from any historical checkpoint.

🛠️ Hands-on Practice ​

  1. Implement SQLite persistence and verify conversation continuity across process restarts.

  2. Add human approval checkpoint before sending messages to external APIs.

  3. 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?