Lesson 3.2: The Loop (Cycles)

The most powerful feature of LangGraph is that it allows Cycles. You can draw an edge from Node B back to Node A. This creates a loop.

  • Why use this? Self-correction. If an agent writes bad code, the “Reviewer” node can send it back to the “Writer” node to fix it.
  • The Danger: Infinite loops. If the agent never fixes the code, it runs forever. LangGraph protects you with a recursion_limit (default is 25 steps).

The Scenario

A “Coin Flip” game. The agent keeps flipping a coin until it gets “Heads”.

The Code

import random
from typing import TypedDict, Literal
from langgraph.graph import StateGraph, END

# --- 1. State ---
class GameState(TypedDict):
    result: str

# --- 2. Nodes ---
def flip_coin(state):
    print("--- FLIPPING COIN ---")
    # Simulate random flip
    outcome = random.choice(["Heads", "Tails"])
    return {"result": outcome}

# --- 3. The Logic ---
def check_result(state) -> Literal["success", "retry"]:
    if state["result"] == "Heads":
        print(">> Result is Heads. Stopping.")
        return "success"
    else:
        print(">> Result is Tails. Trying again...")
        return "retry"

# --- 4. Build Graph ---
builder = StateGraph(GameState)
builder.add_node("player", flip_coin)

builder.set_entry_point("player")

# The Cycle is defined here:
builder.add_conditional_edges(
    "player", 
    check_result,
    {
        "success": END,     # If heads, end.
        "retry": "player"   # If tails, GO BACK to 'player' node.
    }
)

app = builder.compile()

# --- 5. Run ---
# We invoke it once, but internally it might run the node multiple times.
app.invoke({"result": "Start"})

Output (Randomized)

--- FLIPPING COIN ---
>> Result is Tails. Trying again...
--- FLIPPING COIN ---
>> Result is Tails. Trying again...
--- FLIPPING COIN ---
>> Result is Heads. Stopping.

Key Concept: Recursion Limit

If you ran this and the coin landed on “Tails” 100 times in a row, LangGraph would crash with a GraphRecursionError. This is a safety feature.

You can adjust this limit when you run the graph:

# Allow up to 50 steps instead of the default 25
app.invoke(inputs, config={"recursion_limit": 50})

Leave a Comment