LangGraphLangGraph 1.2 · Python 3.10+
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
37 small wins to finish your pathNext lesson

Choosing a path

So far every run goes the same way. A conditional edge lets the graph look at the state and pick which node runs next.

A support inbox is the obvious case. A billing complaint and a crash report should not get the same reply, and junk mail should not get one at all. Three outcomes, built a few lines at a time.

The state, and the two replies

python
from typing_extensions import TypedDict

class State(TypedDict):
    ticket: str
    reply: str

Then a node for each kind of reply. Neither of them decides anything. Each just writes its own answer.

python
def billing(state):
    return {"reply": "We will refund the double charge."}

def technical(state):
    return {"reply": "Try logging out and back in."}

The part that chooses

This is the new idea. It is a function, but it is not a node. It returns the name of the node that should run next.

python
from langgraph.graph import END

def pick_team(state):
    if "win a prize" in state["ticket"]:
        return END
    return "billing" if "charge" in state["ticket"] else "technical"

Returning a string sends the run to the node with that name. Returning END stops it, which is how junk mail gets no reply at all. This function is never added with add_node and nothing it returns joins the state. It only names a destination.

Wiring it in

python
from langgraph.graph import StateGraph, START

builder = StateGraph(State)
builder.add_node("billing", billing)
builder.add_node("technical", technical)
builder.add_conditional_edges(START, pick_team, ["billing", "technical", END])

Read that last line as: at this point call pick_team and go wherever it says. add_conditional_edges takes the place you are branching from, the function that decides, and the list of places it is allowed to reach. That list is not decoration. It is what lets LangGraph draw the branch, and it catches a name that does not exist.

Three tickets, three different paths

Example
graph = builder.compile()

for ticket in ["charged twice", "app will not open", "win a prize now"]:
    print(repr(graph.invoke({"ticket": ticket, "reply": ""})["reply"]))

The third line is an empty string. Nothing wrote a reply to it, because pick_team sent the run straight to END and neither reply node ever ran.

Lesson 2 said that a node with nothing after it ends the run, and that is still true. Here the run can finish from a branch instead, so you have to name where it goes.

Return a name, not a value
A common first mistake is returning the ticket, or True, or the category. It has to be a string matching a node name, or END.
Try it yourself
  • Add a third team called account for tickets containing password.
  • Make pick_team return a name that does not exist and read the error.
  • Print the graph's edges, from lesson 5, and find the branch.

Little by little, you're building something great.