How to add conditional routing to a LangGraph graph

A graph that always follows the same edge cannot send passing and failing results to different handlers. LangGraph conditional edges let state produced by one node select the next node at runtime.

A routing function runs after its source node and returns a label. The add_conditional_edges() mapping translates that label to a destination node, which keeps decision vocabulary separate from node names and makes each branch straightforward to test.

The program uses a TypedDict state, one evaluation node, and two terminal branches without an external model or API key. Invoking the compiled graph with scores above and below the threshold proves that both labels reach their intended nodes.

Steps to add conditional routing to a LangGraph graph:

  1. Create conditional_route.py with the LangGraph imports and typed route state.
    conditional_route.py
    from typing import Literal
    from typing_extensions import NotRequired, TypedDict
     
    from langgraph.graph import END, START, StateGraph
     
     
    class RouteState(TypedDict):
        score: int
        result: NotRequired[str]
        message: NotRequired[str]
  2. Add the evaluation and branch node functions below RouteState.
    def evaluate_score(state: RouteState) -> dict[str, str]:
        result = "passed" if state["score"] >= 70 else "failed"
        return {"result": result}
     
     
    def accept_score(state: RouteState) -> dict[str, str]:
        return {"message": "accepted for review"}
     
     
    def reject_score(state: RouteState) -> dict[str, str]:
        return {"message": "returned for revision"}
  3. Define the route selector below the branch node functions.
    def route_result(state: RouteState) -> Literal["passed", "failed"]:
        return "passed" if state["result"] == "passed" else "failed"

    The return annotation documents every label the selector can emit. Each label must appear in the conditional mapping.

  4. Create a StateGraph builder for RouteState.
    builder = StateGraph(RouteState)
  5. Register the evaluation and branch nodes with the builder.
    builder.add_node("evaluate", evaluate_score)
    builder.add_node("accept", accept_score)
    builder.add_node("reject", reject_score)
  6. Connect the graph entry point to the evaluation node.
    builder.add_edge(START, "evaluate")
  7. Map the route labels from evaluate to their destination nodes.
    builder.add_conditional_edges(
        "evaluate",
        route_result,
        {"passed": "accept", "failed": "reject"},
    )

    A source node should have one routing mechanism because normal and conditional outgoing edges can schedule both paths.

  8. Connect both branch nodes to END.
    builder.add_edge("accept", END)
    builder.add_edge("reject", END)
  9. Compile the graph from the completed builder.
    graph = builder.compile()
  10. Add two invocations below the compiled graph to exercise both route labels.
    for score in (84, 42):
        final_state = graph.invoke({"score": score})
        print(
            f"score={score} route={final_state['result']} "
            f"message={final_state['message']}"
        )
  11. Run conditional_route.py to confirm each score reaches a different branch.
    $ python conditional_route.py
    score=84 route=passed message=accepted for review
    score=42 route=failed message=returned for revision