Chapter 4 · LangGraph Overview and StateGraph Introduction
Chapter goals:
- Understand LangGraph's positioning: a low-level orchestration runtime, distinct from LangChain agents
- Master the minimal StateGraph example: nodes, edges, state, compilation, and execution
- Understand MessagesState and custom state
- Distinguish the relationship between LangGraph Runtime and Deep Agents Harness
4.1 Why Do We Need LangGraph?
LangChain agents provide out-of-the-box architectures (ReAct, Plan-and-Execute), but lack control over execution flow. For production Agent systems, we need:
- Explicit control flow: Conditional routing based on state
- Cycles and loops: Agent can iteratively refine responses
- Persistence: Checkpoint and restore execution state
- Human-in-the-loop: Pause for approval before action
LangGraph addresses these needs as a state machine for Agent orchestration.
4.2 StateGraph: The Core Abstraction
A LangGraph graph consists of:
- State: A typed dictionary carrying information through the graph
- Nodes: Functions that transform state
- Edges: Transitions between nodes (conditional or normal)
4.2.1 Minimal Example
from langgraph.graph import StateGraph, MessagesState, START, END
from langchain_core.messages import HumanMessage, AIMessage
# Define state
class GraphState(MessagesState):
next_step: str = ""
# Define nodes
def chatbot(state: GraphState) -> dict:
# Simple LLM call
response = "Hello! How can I help?"
return {"messages": [AIMessage(content=response)]}
def classifier(state: GraphState) -> dict:
last_msg = state["messages"][-1]
if "bye" in last_msg.content.lower():
return {"next_step": "end"}
return {"next_step": "chatbot"}
# Build graph
workflow = StateGraph(GraphState)
workflow.add_node("chatbot", chatbot)
workflow.add_node("classifier", classifier)
workflow.add_edge(START, "classifier")
workflow.add_conditional_edges(
"classifier",
lambda x: x["next_step"],
{"chatbot": "chatbot", "end": END}
)
graph = workflow.compile()4.2.2 Execution Flow
START → classifier → chatbot → classifier → ... → END
↑ │
└────────── loop ──────────────┘4.3 MessagesState: Built-in State Type
MessagesState is LangGraph's built-in state type, containing messages field:
from langgraph.graph import MessagesState
# State schema (automatically handled)
{
"messages": [
{"role": "user", "content": "Hello"},
{"role": "assistant", "content": "Hi!"},
]
}4.3.1 Why MessagesState?
- Automatic message appending
- Compatible with LangChain's message format
- Supports streaming updates
4.4 Custom State Types
Extend TypedDict for custom state:
from typing import TypedDict, Annotated
import operator
class AgentState(TypedDict):
# Messages (auto-appended)
messages: Annotated[list, operator.add]
# Custom fields
user_id: str
context: dict
tool_calls: list4.4.1 Annotation Types
| Annotation | Behavior |
|---|---|
operator.add | Append to list (messages) |
lambda a, b: b | Override (last wins) |
lambda a, b: a + b | Concatenate strings |
4.5 LangGraph Runtime vs Deep Agents Harness
| Feature | LangGraph Runtime | Deep Agents Harness |
|---|---|---|
| Level | Low-level orchestration | High-level Agent framework |
| Control | Full control over state/flow | Simplified API |
| Learning Curve | Steeper | Gentler |
| Use Case | Custom Agent workflows | Quick prototyping |
📌 Deep Agents (covered in Chapter 9) builds on LangGraph, providing simplified abstractions for common patterns.
Chapter Summary
- Why LangGraph: Need explicit control flow, cycles, persistence, human-in-the-loop;
- StateGraph: Nodes transform state, edges define transitions;
- MessagesState: Built-in state with automatic message handling;
- Custom State: Extend TypedDict with annotations for list/override behavior;
- Runtime vs Harness: LangGraph is low-level, Deep Agents is high-level abstraction.
🛠️ Hands-on Practice
Build a simple chatbot with StateGraph that classifies user input (greeting/bye/question) and routes to different nodes.
Add a
contextfield to custom state that accumulates information across turns.Implement a loop that repeats until a confidence threshold is met.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What is the main difference between LangGraph Runtime and Deep Agents Harness?
2. What does the operator.add annotation do in LangGraph state?
3. What is the purpose of add_conditional_edges?
4. Which state type is recommended for message-heavy Agent applications?