In a standard script, you call function A, get the result, and pass it to function B. In LangGraph, you don’t call functions directly. You place them on a “board” (the Graph) and draw lines between them. The Graph manages the execution.
The 4-Step Recipe
Every LangGraph application follows the exact same 4-step structure:
- Define State: What data are we passing around?
- Define Nodes: What functions will modify that data?
- Build Graph: Add the nodes and connect them with edges.
- Compile & Run: Turn the blueprint into an executable app.
The Code
Here is the simplest possible graph: A “Start” node that passes a message to an “End” node.
from typing import TypedDict
from langgraph.graph import StateGraph, END
# --- STEP 1: Define the State ---
# Think of this as the "Protocol".
# Every node MUST accept this dictionary and return a part of it.
class SimpleState(TypedDict):
message: str
# --- STEP 2: Define the Nodes ---
# Nodes are just Python functions.
# They receive the current State and return an update.
def shout_node(state):
print(f"Node 'Shout' received: {state['message']}")
# We return an update: capitalize the message
return {"message": state['message'].upper()}
def whisper_node(state):
print(f"Node 'Whisper' received: {state['message']}")
# We return an update: add 'shh'
return {"message": state['message'] + " (shh)"}
# --- STEP 3: Build the Graph ---
# We initialize the builder with our State structure
builder = StateGraph(SimpleState)
# Add our workers (Nodes)
builder.add_node("shout", shout_node)
builder.add_node("whisper", whisper_node)
# Create the flow (Edges)
# 1. Start at 'shout'
builder.set_entry_point("shout")
# 2. Go from 'shout' to 'whisper'
builder.add_edge("shout", "whisper")
# 3. Go from 'whisper' to the End (Finish execution)
builder.add_edge("whisper", END)
# --- STEP 4: Compile & Run ---
# Compile freezes the structure
graph = builder.compile()
# Invoke with an initial state
result = graph.invoke({"message": "hello world"})
print("-" * 20)
print(f"Final Result: {result['message']}")Output
Node 'Shout' received: hello world Node 'Whisper' received: HELLO WORLD -------------------- Final Result: HELLO WORLD (shh)
Key Concept: The Graph vs. The Chain
You might look at this and say, “This looks like a lot of boilerplate just to run two functions.”
If you just wanted a linear chain ($A \to B$), you are right. But notice what we didn’t do:
shout_nodedid not callwhisper_node.shout_nodedoesn’t even knowwhisper_nodeexists.
This decoupling is critical. It means later we can easily insert a “Check Safety” node between them without rewriting the shout function. We just change the edge.

I build softwares that solve problems. I also love writing/documenting things I learn/want to learn.