What is LangGraph? How it works and how to evaluate it
LangGraph is LangChain's open-source framework for building long-running, stateful AI agents as graphs of nodes with shared state, persistence and human pauses.
LangGraph is an open-source framework from LangChain for building long-running, stateful AI agents as graphs. You define nodes (steps) that read and update a shared state, and edges (including loops and branches) that decide what runs next. LangChain’s docs call it “a low-level orchestration framework and runtime” (overview).
What a LangGraph app is made of
A graph has three parts (Graph API):
- State: a shared schema. Each key can have a reducer that merges updates, and with no reducer an update replaces the value.
- Nodes: functions that take the state and return an update. A node can call a model, a tool or neither.
- Edges: fixed or conditional transitions. Cycles are allowed, which is how agent loops are built.
Compile the graph with a checkpointer and pass a thread_id, and LangGraph saves state as checkpoints on that thread (persistence). That also enables human-in-the-loop: “The interrupt function pauses graph execution and returns a value to the caller,” and you resume by invoking again with a Command (interrupts).
There is also a Functional API for adding these features to existing procedural code. The docs suggest the Graph API for explicit structure and parallel paths that merge, and the Functional API for minimal changes to existing code (choosing an API).
When to use it
Use LangGraph when you need to control the flow yourself: loops, branches, parallel steps, pauses for a human, or resuming after a failure. The overview describes persistence, human oversight, short and long-term memory, debugging with LangSmith and production deployment (overview). If you only need a standard tool-calling agent, LangChain’s create_agent runs on LangGraph already.
Failure modes in the official docs
| Failure | Cause and fix, per the docs |
|---|---|
GraphRecursionError |
The graph “reached the maximum number of steps before hitting a stop condition,” often an infinite loop; check cycles, or pass a higher recursion_limit for complex graphs (error page) |
| Run hits the limit with no clean exit | Declare remaining_steps: RemainingSteps in state and route to a fallback node before the limit; the docs show this as the approach that finishes without an exception (Graph API) |
Parallel writes to one key (INVALID_CONCURRENT_GRAPH_UPDATE) |
Several nodes wrote one key in the same step and it has no reducer; define a reducer such as operator.add (error page) |
| Invalid node return | A node returned a non-dict, which raises InvalidUpdateError: Expected dict, got ['whoops']; nodes “must return a dict containing one or more keys defined in your state” (error page) |
| Duplicate side effects on resume | After an interrupt or retry, “the affected node runs again from the start of its function,” so code before the pause runs again; make nodes idempotent (Graph API) |
The recursion limit default has changed across versions. The docs say it was 10,000 steps from 1.0.6 to 1.1.3 and is 10,007 from 1.1.4. The limit goes in the run config, not inside configurable (Graph API):
graph.invoke(inputs, config={"recursion_limit": 5}, context={"llm": "anthropic"})
With a default this high, a looping agent keeps running for thousands of steps, so set a limit that fits your task on every run.
How to test and trace a graph
The official testing guide describes three techniques (testing):
- Build the graph and a new checkpointer inside each test, since agents depend on state.
- Test single nodes through
graph.nodes, which bypasses any checkpointer. - Test part of a graph by seeding state with
update_state(..., as_node=...)and invoking withinterrupt_after.
For tracing, LangGraph integrates with LangSmith: set LANGSMITH_TRACING=true and an API key, or trace selected calls with tracing_context (observability). LangSmith Studio adds a local visual debugger. Some failures above are plain exceptions that surface without a trace. Others, such as step counts, branch choices and repeated tool calls, are easier to see in a trace of the run. For more on tracing, see what agent observability is.
How to evaluate a LangGraph agent
LangSmith’s offline evaluation has four steps: create a dataset, define evaluators, run an experiment and analyze results. A dataset can come from curated test cases, production traces or synthetic data, and evaluators are “functions that score how well your application performs” (LangSmith evaluation). For agents, the agentevals package scores the trajectory, meaning the messages and tool calls a run made. Trajectory match compares a run to a reference, and an LLM judge can score a trajectory with or without one (trajectory evals). The match modes:
| Mode | What it checks (source) |
|---|---|
strict |
“Exact match of messages and tool calls in the same order” |
unordered |
“Same tool calls allowed in any order” |
subset |
The agent calls only tools that appear in the reference |
superset |
The trajectory includes “at least all the tool calls in the reference trajectory” |
HoneyHive experiments follow the same shape: “run a function on a curated dataset, score each output with evaluators, and compare runs in the dashboard” (experiments).
Tracing a LangGraph app in HoneyHive
HoneyHive traces LangGraph with the OpenInference LangChain instrumentor, so existing graph code runs unchanged. It captures each graph.invoke(), node transitions, conditional routing, subgraph spans, tool calls, and LLM calls with token usage. Call instrument() before building any StateGraph, and pass tracer_provider. The integration page lists langgraph 1.1.6 as last tested and requires Python 3.11 or later (integration docs):
from honeyhive import HoneyHiveTracer
from openinference.instrumentation.langchain import LangChainInstrumentor
tracer = HoneyHiveTracer.init() # Reads HH_INGESTION_API_KEY from your environment
LangChainInstrumentor().instrument(tracer_provider=tracer.provider)
With a coding agent, install the honeyhive-instrument skill (npx skills add honeyhiveai/skills --skill honeyhive-instrument, see agent skills) and ask it to add tracing to your LangGraph app. Setup details and a multi-agent example are on the HoneyHive LangGraph integration page.
FAQ
Is LangGraph free?
Yes. The langgraph library is MIT licensed and installs with pip install -U langgraph (PyPI, overview). LangSmith, the LangChain platform used for tracing, is a separate product.
What is the difference between LangGraph and LangChain?
LangGraph is the orchestration runtime. LangChain's create_agent is a higher-level agent framework built on it, and the docs say "Deep Agents is built on LangChain agents, which run on LangGraph" (overview).
What is LangGraph Studio?
The docs now call it LangSmith Studio, "a free visual interface for developing and testing your LangChain agents from your local machine." It connects to a local server started with langgraph dev and needs a LangSmith account (Studio).