Cet article est publié en anglais.
LangGraph Conditional Edges: Routing a Graph With State and Decisions
Learn how LangGraph conditional edges work: write a router that stores its decision in state, map outcomes to nodes and send each path where it should go.
A quick refresher on the first part of this LangGraph series helps before adding decisions. LangGraph is essentially a set of connected functions, each handling one job. Three pieces carry the idea.
State is the object that moves through the graph holding all the information. Any node can read from it and write to it.
state = {
'a': 2,
'b': 3,
'sum': None
}
Nodes are plain functions. A node receives the state, does some work, and returns only the values it wants to change.
def add(state):
total = state['a'] + state['b']
return {'sum': total}
Edges decide which node runs next, for instance:
add → multiply → final
The state travels along that path while the nodes run in turn. A node doesn't have to be an ordinary Python function, either, since it can wrap an LLM call. So far, though, every graph has followed one fixed route. The next question is how to let a graph choose between routes, and the answer is conditional edges.
The idea behind a conditional edge
Software gets much of its usefulness from making choices: yes or no, this or that. Graphs need that too, so some functions exist purely to decide.
Suppose a graph greets someone according to the time of day. In the morning, the output is:
Good Morning
At night, it is:
Good Night
The shape of the graph changes as a result. It is no longer the straight line
A → B → C
but a fork:
→ Morning → Good Morning
/
User → Router
\
→ Night → Good Night
A Router picks the branch. That, in a nutshell, is a conditional edge.
Trying it in plain Python first
Before bringing LangGraph in, here's the same idea as an ordinary function. It needs the current time:
from datetime import datetime
And the function itself:
def router(): hour = datetime.now().hour
if 5 <= hour < 12:
return "Morning"
else:
return "Night"
Notice how little this function does. It performs no big operation. It decides. A current hour from 5 AM up to noon gives back
Morning
and anything else gives back
Night
Placed inside a graph, that return value can choose the next node. There's a second trick as well: the decision can be saved in the state. Add a field for it:
state = {
'time_per': None
}
Now the router can write its choice into the state. It takes the state as an argument:
def router(state):
And inside it computes the hour and records the result:
hour = datetime.now().hour
if 5 <= hour < 12:
return {'time_per': 'Morning'}
else:
return {'time_per': 'Night'}
Afterward the state holds the decision:
{
'time_per': 'Morning'
}
That's the key point. State stores information, and the conditional edge reads that information to steer the graph. Two things happen in sequence:
Router
↓
updates state
↓
time_per = "Morning"
↓
conditional edge checks it
↓
Morning node
This is where State and Edges begin to cooperate.
The same thing in LangGraph
First, the state needs a typed definition. Import TypedDict:
from typing import TypedDict
Then declare the schema:
class State(TypedDict):
time_per: str
Next come the nodes. The router decides whether it's morning or night, and it needs the clock:
from datetime import datetime
The router node itself:
def router(state): hour = datetime.now().hour if 5 <= hour < 12:
return {'time_per': 'Morning'}
else:
return {'time_per': 'Night'}
Two further nodes handle each outcome. One covers the morning:
def morning(state):
return {'time_per': 'Good Morning'}
The other covers the night:
def night(state):
return {'time_per': 'Good Night'}
Now for the important part. LangGraph needs a function that says which path to follow. It receives the state:
def decide_time(state):
and simply hands back the stored decision:
return state['time_per']
So it returns either
Morning
or
Night
That function plugs into a conditional edge:
graph.add_conditional_edges(
"router",
decide_time,
{
"Morning": "morning",
"Night": "night"
}
)
Here's what each piece means. The opening of the call is
graph.add_conditional_edges(
"router",
which tells LangGraph that once the router node finishes, the graph shouldn't jump to one fixed node. A decision takes over. The next argument is
decide_time,
the function that makes the decision. The last argument is
{
"Morning": "morning",
"Night": "night"
}
a mapping from each possible decision to the node that should follow. If decide_time() returns
Morning
the graph follows
router → morning
and if it returns
Night
the graph follows
router → night
The full graph now looks like this:
→ morning → END
/
START → router
\
→ night → END
That's the difference between the two kinds of edge. A normal edge always says
A → B
with no exceptions, while a conditional edge says
A → ?
and lets the decision fill in the question mark.
Why this matters
Here's where LangGraph gets interesting. The flow works like a cycle of dependencies:
updates
State
↑
|
Router
|
↓
Conditional Edge
↙ ↘
Morning Night
A node can update the state. The routing function can read that state. And the routing function then decides which node runs next. The graph stops being a pile of connected functions and turns into one where the current state can change its own path. Complex workflows need exactly that.
A realistic case is a question router:
User Question
↓
Classifier
↓
State
↓
┌────┴─────┐
↓ ↓
Coding General
↓ ↓
Code Normal
Answer Answer
The classifier might write something like this into the state:
{
'type': 'coding'
}
The conditional edge reads that value and asks whether to send the request to the coding node or to the general one. At this point the workflow is no longer a simple sequence. It's a graph that makes decisions. The next step is loops, where a graph goes back, repeats a step and tries again.