RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /LangGraph for Local Agents
  6. /Ch. 3
LangGraph for Local Agents

03. Nodes and Edges

Chapter 3 of 18 · 15 min
KEY INSIGHT

Think of edges as explicit routing rules, not as sequential fall-through. Every non-terminal node must have its outgoing path defined at compile time, or the graph refuses to build.

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.

← Chapter 2
StateGraph Basics
Chapter 4 →
State Management