TL;DR — LangGraph is the low-level runtime underneath LangChain's create_agent(). Where LangChain gives you a one-liner agent, LangGraph lets you define the agent as an explicit graph — nodes are functions, edges are conditional transitions, state is typed and checkpointed. Use it when you need branching, parallelism, human-in-the-loop gates, or multi-agent coordination that a linear loop can't express.
What it is
LangGraph is a framework for building stateful, multi-step AI applications as directed graphs. Each node is a Python function (or coroutine); edges carry typed state between them; conditional edges let the model's output decide where to go next. The runtime handles persistence, streaming, fault tolerance, and time-travel debugging.
It sits in AI Agent › Agent Framework — the layer where you design the control flow of an agent, deciding exactly which steps happen, in what order, and under what conditions.
Fig 1 — A basic ReAct agent as a LangGraph: call model → conditional branch → tools or respond.
Why it exists
Simple agents follow a loop: call model → run tools → repeat. But real-world agents need more: parallel tool execution, human approval before dangerous actions, sub-agents that coordinate, error recovery with fallback paths. A flat loop can't express these. LangGraph gives you a graph so every branch, gate, and retry is an explicit, visible node — not hidden inside callbacks.
Core concepts
- State — a typed dict (usually a
TypedDictor Pydantic model) that flows between nodes. The graph's "memory" for the current run. - Node — a function
(state) → partial state update. Does one thing: calls a model, runs tools, formats output. - Edge — connects nodes. Normal edges always fire; conditional edges call a router function to pick the next node.
- Checkpointer — persists state after each node, enabling conversation memory, time-travel, and human-in-the-loop interrupts.
Install & setup
pip install langgraph langchain-openai
export OPENAI_API_KEY=sk-...
Building a basic agent
from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI
from langchain.tools import tool
# 1. Define state
class State(TypedDict):
messages: Annotated[list, add_messages]
# 2. Define tools
@tool
def search(query: str) -> str:
"""Search the web."""
return f"Results for: {query}"
# 3. Define nodes
model = ChatOpenAI(model="gpt-4o").bind_tools([search])
def call_model(state: State):
response = model.invoke(state["messages"])
return {"messages": [response]}
def run_tools(state: State):
tool_map = {"search": search}
last = state["messages"][-1]
results = []
for tc in last.tool_calls:
result = tool_map[tc["name"]].invoke(tc["args"])
results.append({"role": "tool", "content": result,
"tool_call_id": tc["id"]})
return {"messages": results}
# 4. Build graph
def should_continue(state: State):
if state["messages"][-1].tool_calls:
return "tools"
return END
graph = StateGraph(State)
graph.add_node("model", call_model)
graph.add_node("tools", run_tools)
graph.add_edge(START, "model")
graph.add_conditional_edges("model", should_continue, {"tools": "tools", END: END})
graph.add_edge("tools", "model")
agent = graph.compile()
result = agent.invoke({"messages": [("user", "Search for vLLM news")]})
Persistence & memory
Add a checkpointer and every node's output is saved. Pass a thread_id to maintain conversation history across calls:
from langgraph.checkpoint.memory import MemorySaver
agent = graph.compile(checkpointer=MemorySaver())
config = {"configurable": {"thread_id": "user-42"}}
agent.invoke({"messages": [("user", "My name is Shivam")]}, config=config)
r = agent.invoke({"messages": [("user", "What's my name?")]}, config=config)
# -> "Your name is Shivam"
Human-in-the-loop
Interrupt the graph before a dangerous node. The runtime pauses, waits for approval, then resumes from the checkpoint:
agent = graph.compile(
checkpointer=MemorySaver(),
interrupt_before=["tools"] # pause before running tools
)
result = agent.invoke({"messages": [("user", "Delete old records")]}, config=config)
# graph pauses — inspect result, approve, then:
agent.invoke(None, config=config) # resume from checkpoint
Subgraphs & multi-agent
A node can itself be a compiled graph. This is how you build multi-agent systems — each sub-agent is a subgraph with its own state, and a parent graph coordinates them:
researcher = build_researcher_graph().compile()
writer = build_writer_graph().compile()
parent = StateGraph(ParentState)
parent.add_node("research", researcher)
parent.add_node("write", writer)
parent.add_edge(START, "research")
parent.add_edge("research", "write")
parent.add_edge("write", END)
app = parent.compile()
Streaming
for event in agent.stream({"messages": [("user", "Search AI news")]},
stream_mode="updates"):
for node_name, update in event.items():
print(f"[{node_name}]", update)
LangGraph Platform
For production deployment, LangGraph Platform (formerly LangGraph Cloud) gives you a managed runtime with built-in task queues, cron jobs, a REST API, and LangSmith integration. You deploy your graph; it handles scaling, persistence, and long-running background agents. Self-hosted option available.
When to use, when to skip
Use it when your agent needs branching logic, parallel paths, human gates, sub-agents, or any control flow that a linear tool-calling loop can't express. Also when you want full visibility into exactly what path the agent took.
Skip it for simple agents — create_agent() from LangChain wraps LangGraph and is simpler. If you don't need LangChain's ecosystem at all, consider lighter alternatives like Pydantic AI or raw provider SDKs.
vs the alternatives
| Tool | Best for | Trade-off |
|---|---|---|
| LangGraph | Custom graphs, branching, multi-agent, max control | More wiring; steeper learning curve |
LangChain create_agent | Simple tool-calling agents, quick start | Less control over flow |
| AutoGen | Multi-agent conversations, research | Different paradigm (chat-based) |
| CrewAI | Role-based agent teams | Opinionated, less low-level |
| Temporal / Hatchet | Durable workflow orchestration | Not AI-specific |
Verified against the LangGraph docs (langchain-ai.github.io/langgraph), May 2026.