LangGraph Agents Cheat Sheet

LangGraph agents cheat sheet - Build AI agents with state machines, tool calling, and multi-step workflows. Complete guide to LangGraph for advanced AI applications. Updated December 2025.

Last Updated: December 24, 2025

Installation & Setup

# Install LangGraph
pip install langgraph langchain langchain-openai

# Basic imports
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from typing import TypedDict, Annotated
import operator

Define Agent State

class AgentState(TypedDict):
    # Messages list (accumulates conversation)
    messages: Annotated[list, operator.add]

    # Single values (gets overwritten)
    current_step: str
    tool_result: str

    # Counter (gets incremented)
    iteration_count: Annotated[int, operator.add]

# State is passed between nodes
# Annotations control how values merge

Create Basic Graph

from langgraph.graph import StateGraph, END

# Initialize graph with state type
workflow = StateGraph(AgentState)

# Define node functions
def call_model(state: AgentState):
    llm = ChatOpenAI(model="gpt-4")
    response = llm.invoke(state["messages"])
    return {"messages": [response]}

def should_continue(state: AgentState):
    last_message = state["messages"][-1]
    if last_message.tool_calls:
        return "continue"
    return "end"

# Add nodes
workflow.add_node("agent", call_model)
workflow.add_node("tools", tool_node)

# Add edges
workflow.set_entry_point("agent")
workflow.add_conditional_edges(
    "agent",
    should_continue,
    {
        "continue": "tools",
        "end": END
    }
)
workflow.add_edge("tools", "agent")

# Compile
app = workflow.compile()

Tool Integration

from langchain.tools import tool
from langgraph.prebuilt import ToolNode

@tool
def search_web(query: str) -> str:
    """Search the web for information."""
    # Implementation here
    return f"Results for: {query}"

@tool
def calculator(expression: str) -> str:
    """Calculate mathematical expressions."""
    return str(eval(expression))

# Create tool list
tools = [search_web, calculator]

# Bind tools to LLM
llm = ChatOpenAI(model="gpt-4")
llm_with_tools = llm.bind_tools(tools)

# Create tool execution node
tool_node = ToolNode(tools)

Running the Graph

# Simple invoke
result = app.invoke({
    "messages": [("user", "What's 25 * 4?")]
})

# Stream responses
for output in app.stream({
    "messages": [("user", "Search for AI news")]
}):
    print(output)

# Get final state
final_state = app.get_state()
print(final_state["messages"])

Conditional Routing

def route_by_intent(state: AgentState):
    """Route based on user intent."""
    last_msg = state["messages"][-1].content.lower()

    if "search" in last_msg or "find" in last_msg:
        return "search_node"
    elif "calculate" in last_msg or "math" in last_msg:
        return "calculator_node"
    else:
        return "general_node"

workflow.add_conditional_edges(
    "classifier",
    route_by_intent,
    {
        "search_node": "search",
        "calculator_node": "calc",
        "general_node": "agent"
    }
)

Human-in-the-Loop

from langgraph.checkpoint.sqlite import SqliteSaver

# Add memory/checkpointing
memory = SqliteSaver.from_conn_string(":memory:")

# Compile with checkpointer
app = workflow.compile(
    checkpointer=memory,
    interrupt_before=["human_approval"]
)

# Run until interrupt
config = {"configurable": {"thread_id": "1"}}
for output in app.stream(input_data, config):
    print(output)

# Resume after human input
app.update_state(
    config,
    {"approval": "approved"}
)

# Continue execution
for output in app.stream(None, config):
    print(output)

Multi-Agent Collaboration

class MultiAgentState(TypedDict):
    messages: Annotated[list, operator.add]
    next_agent: str

# Define specialized agents
def researcher_agent(state):
    llm = ChatOpenAI(model="gpt-4")
    prompt = "You are a research specialist..."
    response = llm.invoke(state["messages"])
    return {
        "messages": [response],
        "next_agent": "writer"
    }

def writer_agent(state):
    llm = ChatOpenAI(model="gpt-4")
    prompt = "You are a content writer..."
    response = llm.invoke(state["messages"])
    return {
        "messages": [response],
        "next_agent": "reviewer"
    }

# Build collaboration graph
workflow = StateGraph(MultiAgentState)
workflow.add_node("researcher", researcher_agent)
workflow.add_node("writer", writer_agent)
workflow.add_node("reviewer", reviewer_agent)

# Route between agents
workflow.add_conditional_edges(
    "researcher",
    lambda x: x["next_agent"]
)
workflow.add_conditional_edges(
    "writer",
    lambda x: x["next_agent"]
)

Persistence & Memory

from langgraph.checkpoint.sqlite import SqliteSaver

# SQLite checkpointer
memory = SqliteSaver.from_conn_string("agent_memory.db")

app = workflow.compile(checkpointer=memory)

# Each thread has isolated state
config1 = {"configurable": {"thread_id": "user-1"}}
config2 = {"configurable": {"thread_id": "user-2"}}

# Run separate conversations
app.invoke({"messages": [("user", "Hello")]}, config1)
app.invoke({"messages": [("user", "Hi")]}, config2)

# Get conversation history
history = app.get_state_history(config1)

Error Handling

def safe_tool_execution(state: AgentState):
    try:
        result = execute_tool(state["tool_input"])
        return {
            "tool_result": result,
            "error": None
        }
    except Exception as e:
        return {
            "tool_result": None,
            "error": str(e),
            "messages": [("system", f"Error: {e}")]
        }

def handle_error(state: AgentState):
    if state.get("error"):
        return "retry"
    return "success"

workflow.add_conditional_edges(
    "tool_executor",
    handle_error,
    {
        "retry": "agent",
        "success": "next_step"
    }
)

Streaming Tokens

# Stream individual tokens
async for event in app.astream_events(
    {"messages": [("user", "Tell me a story")]},
    version="v1"
):
    kind = event["event"]

    if kind == "on_chat_model_stream":
        content = event["data"]["chunk"].content
        if content:
            print(content, end="", flush=True)

Common Patterns

ReAct Agent
Reasoning + Acting loop with tools
Plan-Execute
Plan steps, then execute sequentially
Supervisor Pattern
One agent routes to specialized agents
Sequential Chain
Linear pipeline of processing steps
Parallel Execution
Run multiple agents simultaneously

Debugging & Visualization

# Print graph structure
print(app.get_graph().draw_ascii())

# Get current state
state = app.get_state(config)
print("Current node:", state.next)
print("State values:", state.values)

# LangSmith tracing
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your_key"

# View traces in LangSmith dashboard

Best Practices

Keep state minimal
Only store what you need between nodes
Use typed state
TypedDict for type safety and autocomplete
Add error handling
Gracefully handle tool failures
Use checkpointing
Enable persistence for long-running agents
Limit iterations
Prevent infinite loops with max iterations
Test nodes individually
Unit test each node function
💡 Pro Tip: Start with the prebuilt create_react_agent for simple use cases, then build custom graphs as you need more control. Use LangSmith tracing to debug complex agent flows and visualize decision paths.
← Back to Data Science & ML | Browse all categories | View all cheat sheets