What is Langgraph-
Imagin You are running a Lemonade Stand
Without Langgraph-
Customer → You → Lemonade → Customer
Simple, but what if you need to:
Ask parent for help?
Go buy more lemons?
Handle multiple customers?
With Langgraph-
Customer → [STAND] → Check lemons?
↓
Enough? → [MAKE] → Serve
↓
Not enough? → [BUY] → [MAKE] → Serve
In this LangGraph flow, the process starts when a customer places a request. The system first stands by to check the available lemons. If there are enough lemons, it directly moves to the make step and serves the result. If lemons are not sufficient, the workflow automatically goes to buy, then returns to make, and finally serves the customer. LangGraph enables this kind of conditional, decision-based flow in a clean and structured way.
Terminology-
Nodes: Each Node does one job . its nothing a simple function
def squeeze_lemons(lemons):
return "lemon juice"
def add_sugar(juice):
return "sweet juice"
State: State is the information that flows through each step of the LangGraph workflow. It carries data like current inventory status, decisions made, and intermediate results, allowing every node to read, update, and pass the context forward so the system can act consistently at each stage.
recipe = {
"lemons": 5,
"sugar_cups": 2,
"juice": "",
"glasses_served": 0
}
Edges: Edges define what to do next in the workflow. They act as instructions that connect one step to another, guiding the flow such as squeeze lemons → add sugar → stir → serve, ensuring each action happens in the correct order.
Squeeze lemons → Add sugar → Stir → Serve
Lest Setup Our First Graph:
Step 1: install LangGraph
pip install langgraph
Step 2: Make Your First Graph (Lemon Squeezer)
from langgraph.graph import StateGraph, MessagesState, START, END
from typing import TypedDict
class LemonadeState(TypedDict):
messages: list
lemons: int
enough_lemons: bool
action: str
Step 3: Complete Lemonade Stand-
from langgraph.graph import StateGraph, START, END
from typing import TypedDict, List, Literal
# Define State (Docs Style)
class LemonadeState(TypedDict):
messages: List[dict] # Chat history
lemons: int # Available lemons
money: float # Available money
action: str # Current action
glasses_made: int # Total glasses made
enough_lemons: bool
# ===== NODES ===== (Workers)
def check_inventory(state: LemonadeState):
"""Check if we have enough lemons"""
if state["lemons"] >= 2:
return {
"messages": [{"role": "system", "content": "✅ Enough lemons!"}],
"enough_lemons": True,
"action": "make_lemonade"
}
else:
return {
"messages": [{"role": "system", "content": "❌ Need more lemons!"}],
"enough_lemons": False,
"action": "buy_lemons"
}
def make_lemonade(state: LemonadeState):
"""Make lemonade from lemons"""
lemons_needed = 2
glasses = state["glasses_made"] + 1
return {
"messages": [{"role": "system", "content": f"🍋 Made glass #{glasses} of lemonade!"}],
"lemons": state["lemons"] - lemons_needed,
"glasses_made": glasses,
"action": "serve"
}
def buy_lemons(state: LemonadeState):
"""Buy more lemons"""
cost = 5.0
lemons_bought = 10
return {
"messages": [{"role": "system", "content": f"🛒 Bought {lemons_bought} lemons for ${cost}"}],
"lemons": state["lemons"] + lemons_bought,
"money": state["money"] - cost,
"action": "make_lemonade"
}
def serve_customer(state: LemonadeState):
"""Serve lemonade to customer"""
return {
"messages": [{"role": "system", "content": "👨🍳 Served customer!"}],
"action": "done"
}
# ===== BUILD GRAPH =====
# Create graph with our state definition
graph = StateGraph(LemonadeState)
# Add nodes (workers)
graph.add_node("check_inventory", check_inventory)
graph.add_node("make_lemonade", make_lemonade)
graph.add_node("buy_lemons", buy_lemons)
graph.add_node("serve", serve_customer)
# ===== CONNECT NODES =====
# Start with checking inventory
graph.add_edge(START, "check_inventory")
# Conditional routing: based on enough_lemons
def route_based_on_supply(state: LemonadeState):
"""Decide: make lemonade or buy lemons?"""
if state.get("enough_lemons", False):
return "make_lemonade"
else:
return "buy_lemons"
# After checking, route based on decision
graph.add_conditional_edges(
"check_inventory",
route_based_on_supply,
{
"make_lemonade": "make_lemonade",
"buy_lemons": "buy_lemons"
}
)
# Connect: make_lemonade → serve
graph.add_edge("make_lemonade", "serve")
# Connect: buy_lemons → make_lemonade (after buying)
graph.add_edge("buy_lemons", "make_lemonade")
# Finish: serve → END
graph.add_edge("serve", END)
# ===== COMPILE & RUN =====
# Compile the graph (make it executable)
lemonade_stand = graph.compile()
# Initial state
initial_state = {
"messages": [{"role": "user", "content": "I want lemonade!"}],
"lemons": 1, # Only 1 lemon left
"money": 20.0, # $20 in cash
"action": "",
"glasses_made": 0
}
# Run the lemonade stand!
result = lemonade_stand.invoke(initial_state)
print("=== LEMONADE STAND FINAL STATE ===")
print(f"Lemons left: {result['lemons']}")
print(f"Money left: ${result['money']}")
print(f"Glasses made: {result['glasses_made']}")
print(f"Last action: {result['action']}")
print("\n=== MESSAGE LOG ===")
for msg in result["messages"]:
print(f"{msg['role']}: {msg['content']}")
Note: In this example, we focused on understanding core LangGraph concepts like nodes, state, and edges. Advanced topics such as checkpoints, persistence, retries, and LLM-based responses will be covered in upcoming blogs, where we’ll build more realistic, production-ready agent workflows.
