# Conditional Edges and Routing — LangGraph Agents & Multi-Agent Systems

Source: https://www.geekswithgeeks.com/en/langgraph-agents/f-cond

> Pick the next node from the state.

## A function chooses the path

`add_conditional_edges(source, router, mapping)` runs `router(state)` after `source` and uses its return value to pick the next node. The router can be ordinary Python (keyword checks, thresholds) or read a label that an earlier **classifier node** produced, often with a small LLM call. Keep routers **pure and cheap**, return only known labels, and always cover the default case. Routing keeps each node simple: the classifier decides, specialised nodes act, and the graph shows the structure at a glance.

## Decide, repeat, hand off, split

Conditional edges, loops with limits, Command hand-offs and Send fan-out cover most agent flows.

![Five tools: branch, loop, limit, command, send.](assets/figures/langgraph-agents/section-2-map.svg) — Figure 2.1 — Branch, loop, limit, command and send.

## Routing by category, run

I ran this offline with langgraph 1.2.12 and langchain-core 1.6.6 in a Python virtual environment. No API key or model is needed because plain Python functions stand in for the model, so the output is repeatable. A `classify` node sets a `route`; the conditional edge sends refund and invoice questions to `billing` and everything else to `other`.

```python
from typing import TypedDict
from langgraph.graph import StateGraph, START, END

class State(TypedDict):
    question: str
    route: str
    answer: str

def classify(state):
    q = state["question"].lower()
    return {"route": "billing" if "refund" in q or "invoice" in q else "other"}

def billing(state): return {"answer": "Routed to the billing team."}
def other(state):   return {"answer": "Routed to general support."}

g = StateGraph(State)
g.add_node("classify", classify); g.add_node("billing", billing); g.add_node("other", other)
g.add_edge(START, "classify")
g.add_conditional_edges("classify", lambda s: s["route"], {"billing": "billing", "other": "other"})
g.add_edge("billing", END); g.add_edge("other", END)
app = g.compile()
for q in ("I want a refund", "Where is your office?"):
    print(q, "->", app.invoke({"question": q})["answer"])

```

Output:

```
I want a refund -> Routed to the billing team.
Where is your office? -> Routed to general support.
```

## Keep routers pure

A router should only read state and return a label. Do the work in nodes so routing stays easy to test.

**Quiz:** What should a router always cover?

- [ ] Only the first label
- [x] A default path for unexpected labels
- [ ] Nothing
- [ ] A GPU

*Answer:* A default path for unexpected labels. Unhandled labels cause errors or dead ends.
