๐ค Autonomous Agents & Graph Orchestration
LangGraph StateGraph Workflows
Build cyclic, deterministic, multi-agent workflows with state persistence using LangGraph
Standard linear chains (like LCEL or standard LangChain) fail on multi-step reasoning because they cannot loop backward. LangGraph models agent workflows as stateful graphs (`StateGraph`). Nodes are python functions that mutate state, edges route control dynamically, and checkpointers persist state across execution steps โ enabling true autonomous agents that can reflect and correct their own mistakes.
Key Concepts
TypedDict State
The entire graph shares a single `State` object (defined via Python TypedDict). Every node function receives this state, performs work, and returns a dict that updates the state.
Conditional Edges (Loops)
Unlike DAGs (Directed Acyclic Graphs), LangGraph supports cyclic routing. A conditional edge can evaluate the state (e.g., 'is code valid?') and route back to a previous node (e.g., 'Coder') to try again.
Checkpointers (Memory)
MemorySaver or Postgres checkpointers save the graph's state after every node. This allows 'Time Travel' (rewinding to a previous state) and Human-in-the-Loop (pausing for approval).
Multi-Agent Collaboration
Each node can be a completely independent LLM agent with its own system prompt and tools. They collaborate by mutating the shared State (e.g., a 'Researcher' agent passing data to a 'Writer' agent).
โก Interactive Architecture Simulator
LangGraph StateGraph Workflow
agent
Planner Agent
waitingโฆ
โ
tool
Tool: PostgreSQL
waitingโฆ
โ
evaluator
Quality Evaluator
waitingโฆ
โ
end
END / Checkpoint
waitingโฆ
Step: 0 / 7Reflection loops: 0
LangGraph Architecture & Reflection Loop
LangChain vs LangGraph Architecture
| Feature | LangChain (LCEL) | LangGraph |
|---|---|---|
| Execution Path | Linear / DAG (Directed Acyclic) | Cyclic (Loops allowed) |
| Memory / State | Pass-through dicts or external memory | Centralized `TypedDict` Graph State |
| Self-Correction | Difficult (requires external loops) | Native via Conditional Edges |
| Human-in-the-loop | Manual implementation required | Native via Checkpointer pause/resume |
| Best For | RAG pipelines, Chatbots | Multi-Agent workflows, Autonomous Agents |
Production Code 1: StateGraph Core Architecture
langgraph_agent_core.pypython
1import operator
2from typing import TypedDict, Annotated, Sequence
3from langgraph.graph import StateGraph, END
4from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
5
6# โโ 1. Define Agent State Schema โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
7class AgentState(TypedDict):
8 # 'operator.add' means new messages append to the list instead of overwriting
9 messages: Annotated[Sequence[BaseMessage], operator.add]
10 loop_count: int
11 is_valid: bool
12
13# โโ 2. Define Node Functions โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
14def planner_node(state: AgentState):
15 """Generates the plan or code."""
16 # In production, call your LLM here
17 return {
18 "messages": [AIMessage(content="Generated SQL query plan.")],
19 "loop_count": state.get("loop_count", 0) + 1
20 }
21
22def evaluator_node(state: AgentState):
23 """Evaluates the planner's output."""
24 # Mocking evaluation logic: passes only on the 2nd loop
25 is_valid = state["loop_count"] >= 2
26 return {"is_valid": is_valid}
27
28# โโ 3. Define Conditional Routing Logic โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
29def route_quality_check(state: AgentState) -> str:
30 if state["is_valid"]:
31 return END # Output is good, finish graph
32 if state["loop_count"] > 3:
33 return END # Break infinite loops
34 return "planner" # Feedback loop: send back to planner to try again
35
36# โโ 4. Construct StateGraph โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
37workflow = StateGraph(AgentState)
38
39workflow.add_node("planner", planner_node)
40workflow.add_node("evaluator", evaluator_node)
41
42workflow.set_entry_point("planner")
43workflow.add_edge("planner", "evaluator")
44
45# Add Conditional Edge (Cyclic Reflection Loop)
46workflow.add_conditional_edges("evaluator", route_quality_check)
47
48app = workflow.compile()
49Production Code 2: Human-in-the-Loop & Persistence
langgraph_hitl.pypython
1from langgraph.checkpoint.memory import MemorySaver
2# from langgraph.checkpoint.postgres import PostgresSaver # For Production DB
3from langgraph.graph import StateGraph
4# ... (Assuming 'workflow' from previous snippet is defined) ...
5
6# โโ 1. Compile with Checkpointer and Interrupts โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
7# MemorySaver stores state in RAM. PostgresSaver stores it in a DB table.
8checkpointer = MemorySaver()
9
10# 'interrupt_before' pauses execution BEFORE the evaluator node runs,
11# allowing a human to approve or modify the state.
12app = workflow.compile(
13 checkpointer=checkpointer,
14 interrupt_before=["evaluator"]
15)
16
17# โโ 2. First Run (Pauses at interrupt) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
18thread_config = {"configurable": {"thread_id": "user-session-999"}}
19initial_input = {"messages": [HumanMessage(content="Write a React component")]}
20
21print("Running graph...")
22for event in app.stream(initial_input, thread_config):
23 print(event)
24
25# Graph execution pauses here!
26print("Graph state:", app.get_state(thread_config).next) # Returns: ('evaluator',)
27
28# โโ 3. Human Approval (Resume Execution) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
29user_approval = input("Approve the planner's output? (y/n): ")
30if user_approval.lower() == 'y':
31 # Resume graph execution with NO new input (passes None)
32 print("Resuming graph...")
33 for event in app.stream(None, thread_config):
34 print(event)
35๐ก
Senior Architect Insight: To prevent autonomous agents from burning through your API budget in an infinite 'hallucination reflection' loop, ALWAYS add a `loop_count` to your `AgentState` and enforce a hard limit (e.g. max 3 retries) in your conditional edge router.