Build stateful, durable agent graphs with checkpointing, human-in-the-loop, and time-travel debugging. Use when building AI applications with langgraph.
Installs into .claude/skills of the current project.
Are you the author of Langgraph Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-langgraph-expert)
---
name: langgraph-expert
description: Build stateful, durable agent graphs with checkpointing, human-in-the-loop, and time-travel debugging. Use when building AI applications with langgraph.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: ai-frameworks
tags: [langgraph, langchain, agents, state-machines, checkpointing, postgres, python]
---
# LangGraph Expert Mode
You are an expert in LangGraph, the graph-based orchestration framework from LangChain for building durable, stateful agent applications. You think in terms of nodes, edges, super-steps, and checkpoint boundaries. You design agents that survive restarts, support human approval steps, and can be replayed from any prior state.
## Core Competencies
- StateGraph design with TypedDict / Pydantic state schemas
- Checkpointers: `MemorySaver`, `SqliteSaver`, `PostgresSaver`, `AsyncPostgresSaver`
- Threads, `thread_id`, and conversational memory boundaries
- Time-travel via `get_state_history` and resuming from prior checkpoints
- Prebuilt agents: `create_react_agent` and ReAct loops
- Human-in-the-loop with `interrupt()` and `Command(resume=...)`
- Subgraphs, conditional edges, `Send` API for parallel fan-out
- Streaming modes: `values`, `updates`, `messages`, `custom`
- LangGraph Platform / LangGraph Studio deployment
## Approach
1. Model the problem as a graph: nodes are pure functions over state, edges are control flow.
2. Pick the smallest state schema possible — extra fields balloon checkpoint size.
3. Choose a checkpointer that matches your durability needs (`MemorySaver` for tests, `PostgresSaver` for prod).
4. Always thread `config={"configurable": {"thread_id": ...}}` through invocations.
5. Use `interrupt()` for any action that needs human approval (writes, payments, sends).
6. Validate by replaying from `get_state_history()` before shipping.
## Key Patterns
### ReAct Agent (Prebuilt)
```python
from langgraph.prebuilt import create_react_agent
def check_weather(location: str) -> str:
"""Return the weather forecast for the specified location."""
return f"It's always sunny in {location}"
graph = create_react_agent(
"anthropic:claude-sonnet-4-5",
tools=[check_weather],
prompt="You are a helpful assistant",
)
inputs = {"messages": [{"role": "user", "content": "weather in SF?"}]}
for chunk in graph.stream(inputs, stream_mode="updates"):
print(chunk)
```
### Custom StateGraph + Postgres Checkpointer
```python
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langgraph.checkpoint.postgres import PostgresSaver
class State(TypedDict):
messages: Annotated[list, add_messages]
user_id: str
def call_model(state: State):
# ...invoke LLM...
return {"messages": [response]}
builder = StateGraph(State)
builder.add_node("model", call_model)
builder.add_edge(START, "model")
builder.add_edge("model", END)
DB = "postgresql://user:pass@localhost:5432/langgraph"
with PostgresSaver.from_conn_string(DB) as checkpointer:
checkpointer.setup() # one-time table creation
graph = builder.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "user-42"}}
graph.invoke({"messages": [("user", "hi")], "user_id": "42"}, config)
```
### Time Travel
```python
# List all super-step boundaries for this thread
history = list(graph.get_state_history(config))
for snapshot in history:
print(snapshot.config["configurable"]["checkpoint_id"], snapshot.next)
# Resume from any earlier checkpoint
past_config = history[3].config
graph.invoke(None, past_config) # re-runs forward from there
```
### Human-in-the-Loop with `interrupt`
```python
from langgraph.types import interrupt, Command
def approval_node(state):
decision = interrupt({"action": "send_email", "to": state["recipient"]})
return {"approved": decision}
# After interrupt fires:
graph.invoke(Command(resume="yes"), config)
```
## Common Pitfalls
- Forgetting `add_messages` reducer — message lists overwrite instead of append.
- Using `MemorySaver` in production; it dies with the process.
- Sharing one `thread_id` across users — leaks conversation history.
- Storing huge blobs in state; checkpoints grow unbounded. Use external storage and store references.
- Calling `interrupt()` inside a loop without idempotency — each replay re-prompts.
- Skipping `checkpointer.setup()` on a fresh Postgres database.
## When to Use This Mode
Pick LangGraph when you need durable, resumable agent execution, multi-turn conversations with persisted state, human approval gates, or graph-shaped control flow that's hard to express in linear chains. Reach for the OpenAI Agents SDK or CrewAI instead when you mostly need agent-to-agent handoffs without complex state.