03. Nodes and Edges

Chapter 3 of 18 · 15 min

Nodes are plain Python functions (or callable objects—LangChain Runnable instances also work) that receive the current state dict and return a dict of updates. Edges are the routing rules that determine which node executes next. There are three types: normal edges (add_edge("a", "b") means "after 'a' always go to 'b'"), conditional edges (add_conditional_edges routes by calling a routing function), and the special START/END sentinels.

A node that errors should raise an exception for LangGraph to catch in its error-handling layer, or return a special state marker that a conditional edge inspects. Raising exceptions inside a node is the standard pattern—LangGraph does not swallow them silently.

def orchestrator(state: AgentState) -> AgentState:
    query = state["messages"][-1]
    if "research" in query.lower():
        worker = "researcher"
    elif "code" in query.lower():
        worker = "coder"
    else:
        worker = "generalist"
    return {"active_worker": worker}

def researcher(state: AgentState) -> AgentState:
    return {
        "messages": state["messages"] + ["[researcher] gathering sources"],
        "artifact": "mock research data"
    }

builder.add_node("orchestrator", orchestrator)
builder.add_node("researcher", researcher)
builder.add_edge("orchestrator", "researcher")

Edges can also point to END, which terminates execution. Multiple nodes can point to the same node—this is a fan-in pattern. Only one node can point to START.

The failure mode: if two nodes declare an edge to a third node and only one of them has a defined edge leaving that target node, LangGraph raises InvalidEdgeError at compile() time. Every non-END node must have at least one outgoing edge defined (either normal or conditional). There is no implicit fall-through.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Build a graph with three nodes: router, worker_a, and worker_b. Make router inspect the state and return {"active_worker": "worker_a"} or {"active_worker": "worker_b"}. Use a conditional edge to route to the correct worker. Print the final state to confirm routing works for both branches.