Getting Started with LangGraph Low‑Level API: Designing Nodes, Edges, and State
This tutorial explains the design principles of LangGraph's low‑level graph API—nodes, edges, and State—demonstrates a simple addition‑subtraction workflow, shows how to visualize and execute the graph, and introduces Pydantic‑based State validation for more robust agent development.
LangGraph aims to let developers build directed, cyclic graphs that connect large language models, tools, and custom functions. The core concepts are Nodes (executable units), Edges (data or control flow), and a shared State that is updated by each node.
Why learn the low‑level API?
The high‑level pre‑built graph APIs (e.g., create_react_agent) hide the underlying graph mechanics. For scenarios that require human‑in‑the‑loop validation, multi‑agent collaboration, or custom control flow, developers must work directly with the low‑level API.
Manual graph construction
First, create a State type (here a simple dict) and instantiate a StateGraph builder:
from langgraph.graph import StateGraph
builder = StateGraph(dict)Define two simple functions that modify the state:
def addition(state):
print(f'加法节点收到的初始值:{state}')
return {"x": state["x"] + 1}
def subtraction(state):
print(f'减法节点收到的初始值:{state}')
return {"x": state["x"] - 2}Add the functions as nodes and connect them with edges, using the special START and END markers:
from langgraph.graph import START, END
builder.add_node("addition", addition)
builder.add_node("subtraction", subtraction)
builder.add_edge(START, "addition")
builder.add_edge("addition", "subtraction")
builder.add_edge("subtraction", END)Compile the graph and visualize it (requires the grandalf package):
graph = builder.compile()
graph.get_graph().print_ascii()Running the graph
Provide an initial state and invoke the compiled graph:
initial_state = {"x": 10}
result = graph.invoke(initial_state)
print('最后的结果:', result)The output shows the expected flow: 10 → addition → 11 → subtraction → 9.
Making State robust with Pydantic
Using a plain dict for State lacks type safety. By defining a Pydantic BaseModel, the framework can validate keys and types automatically.
from pydantic import BaseModel
class MyState(BaseModel):
x: int
y: str = "default"
state = MyState(x=1)
print(state.x) # 1
print(state.y) # default
# state = MyState(x="abc") # raises validation errorIntegrating the Pydantic model into StateGraph yields a safer workflow:
from pydantic import BaseModel
from langgraph.graph import StateGraph, START, END
class CalcState(BaseModel):
x: int
def addition(state: CalcState) -> CalcState:
print(f"[addition] 初始状态: {state}")
return CalcState(x=state.x + 1)
def subtraction(state: CalcState) -> CalcState:
print(f"[subtraction] 接收到状态: {state}")
return CalcState(x=state.x - 2)
builder = StateGraph(CalcState)
builder.add_node("addition", addition)
builder.add_node("subtraction", subtraction)
builder.add_edge(START, "addition")
builder.add_edge("addition", "subtraction")
builder.add_edge("subtraction", END)
graph = builder.compile()
initial_state = CalcState(x=10)
final_state = graph.invoke(initial_state)
print("
[最终结果] ->", final_state)Summary
The article introduced the design philosophy of LangGraph's low‑level API, walked through a concrete addition‑subtraction graph, showed how to visualize and execute it, and demonstrated how Pydantic can enforce a structured State for more reliable agent development. Future posts will cover conditional and loop constructs.
Fun with Large Models
Master's graduate from Beijing Institute of Technology, published four top‑journal papers, previously worked as a developer at ByteDance and Alibaba. Currently researching large models at a major state‑owned enterprise. Committed to sharing concise, practical AI large‑model development experience, believing that AI large models will become as essential as PCs in the future. Let's start experimenting now!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
