jnachi
Learning Hub
Python Development9 min readAdvanced

Building State Machines & AI Agents with LangGraph & LangChain

Build robust, multi-actor AI agents using LangGraph: Graph-based state machines, cyclical reasoning loops (ReAct), conditional edges, and human-in-the-loop approvals.

Works with:LangGraphLangChain CoreStateGraphMemorySaver

Key Takeaways

  • Simple linear LLM chains fail on complex tasks; LangGraph models agentic workflows as cyclical state graphs (Nodes, Edges, State)
  • State objects (`TypedDict` / Pydantic) persist conversation memory, tool results, and execution history across multi-turn reasoning loops
  • Conditional edges route execution dynamically based on model decisions (e.g., execute tool vs respond to user vs seek human approval)
  • Checkpointers provide persistent state persistence, enabling Human-in-the-Loop workflows (pausing for human approval before financial/database actions)

The Diagnostic Context

Traditional LangChain linear pipelines break down when tasks require loops, error recovery, and tool iteration. LangGraph treats agentic applications as stateful directed graphs, giving developers precise programmatic control over agent cycles and decision boundaries.

The Core Technique

The LangGraph State Machine Pattern

DIAGRAM / WORKFLOW
graph TD
    Start([__start__]) --> AgentNode["Agent Node (LLM Decision)"]
    
    AgentNode --> Decision{"Model Decided: Call Tool or Finish?"}
    
    Decision -->|Has Tool Calls| ToolNode["Tool Execution Node<br/>(SQL Query / API Call)"]
    Decision -->|No Tool Calls| FinalNode["Generate Final Answer"]
    
    ToolNode --> AgentNode
    FinalNode --> End([__end__])

Building an Agent with LangGraph in Python

PYTHON
from typing import TypedDict, Annotated, Sequence
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, ToolMessage
from langgraph.graph import StateGraph, END
from langgraph.graph.message import add_messages

# 1. Define Graph State Schema:
class AgentState(TypedDict):
    # 'add_messages' reducer appends new messages to history instead of overwriting
    messages: Annotated[Sequence[BaseMessage], add_messages]
    iterations_count: int

# 2. Define Node Functions:
def agent_reasoner_node(state: AgentState) -> dict:
    messages = state["messages"]
    # Simulated model decision:
    print(f"Reasoner step {state.get('iterations_count', 0)} with {len(messages)} messages")
    # In real code: response = llm_with_tools.invoke(messages)
    return {"iterations_count": state.get("iterations_count", 0) + 1}

def tool_execution_node(state: AgentState) -> dict:
    print("Executing requested tool action...")
    return {"messages": [ToolMessage(content="Tool execution success result", tool_call_id="call_123")]}

# 3. Define Conditional Routing Edge:
def should_continue(state: AgentState) -> str:
    if state.get("iterations_count", 0) >= 3:
        return "end_workflow"
    # Inspect if last message has tool calls:
    return "execute_tools"

# 4. Assemble the Graph:
workflow = StateGraph(AgentState)
workflow.add_node("agent", agent_reasoner_node)
workflow.add_node("tools", tool_execution_node)

workflow.set_entry_point("agent")
workflow.add_conditional_edges(
    "agent",
    should_continue,
    {
        "execute_tools": "tools",
        "end_workflow": END
    }
)
workflow.add_edge("tools", "agent")  # Loop back to agent

app = workflow.compile()
5-Minute Activation Challenge

Try This Right Now

In a LangGraph project, configure a `MemorySaver` checkpointer and add a breakpoint before an "execute_payment" node to simulate a Human-in-the-Loop workflow where the user must approve the action in the UI before execution resumes.

Tip: Knowledge only becomes capability once you run the prompt yourself.

Comprehension Check

Test Your Instincts (3 Questions)

1

Why does LangGraph use state graphs rather than traditional linear DAG chains for agentic workflows?

2

In LangGraph, what is the function of a State Reducer (such as `Annotated[list, add_messages]`)?

3

What capability in LangGraph enables "Human-in-the-Loop" validation (e.g., pausing an agent for manager approval before sending an email)?