LangGraph Tutorial: Build State-Machine AI Agents in Python
LangGraph is the LangChain library for building stateful, multi-step AI workflows as graphs. Unlike a simple chain, a LangGraph agent loops through nodes, updates shared state, and decides when to stop. It is ideal for tasks that need planning, tool use, and persistence.
What you will learn
- How LangGraph turns an agent into a state machine
- How to define nodes, edges, and conditional routing
- How to add memory so the agent remembers context
- How to build a customer-support agent that can search a knowledge base and escalate to a human
Prerequisites
- Python 3.10 or later
- An OpenAI API key (or another chat model)
- Basic familiarity with Python and function calling
Install LangGraph
python -m venv .venv
source .venv/bin/activate
pip install langgraph langchain-openaiBuild your first StateGraph
A StateGraph needs three things: a state schema, nodes that read and write state, and edges that connect them.
from typing import TypedDict
from langgraph.graph import StateGraph, END
class AgentState(TypedDict):
question: str
answer: str
steps: list[str]
def understand(state: AgentState):
state["steps"].append("understood question")
return state
def answer(state: AgentState):
state["answer"] = f"Answer for: {state["question"]}"
state["steps"].append("generated answer")
return state
builder = StateGraph(AgentState)
builder.add_node("understand", understand)
builder.add_node("answer", answer)
builder.set_entry_point("understand")
builder.add_edge("understand", "answer")
builder.add_edge("answer", END)
graph = builder.compile()
result = graph.invoke({"question": "What is LangGraph?", "answer": "", "steps": []})
print(result)Add a language model and tools
The real power comes when nodes call an LLM or a tool. Below is a minimal agent that decides whether to answer directly or search a knowledge base.
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
def support_agent(state: AgentState):
messages = [HumanMessage(content=state["question"])]
response = llm.invoke(messages)
state["answer"] = response.content
return stateConditional edges
Conditional edges let the agent choose the next step based on state. Use them to implement loops, retries, or escalation.
def should_escalate(state: AgentState) -> str:
if "refund" in state["question"].lower():
return "human"
return "answer"
builder.add_conditional_edges("understand", should_escalate, {"human": "human", "answer": "answer"})Add memory with persistence
LangGraph supports built-in persistence via checkpointers. Pass a checkpointer when compiling the graph and include a thread_id in the config to resume conversations.
from langgraph.checkpoint.memory import MemorySaver
graph = builder.compile(checkpointer=MemorySaver())
config = {"configurable": {"thread_id": "user-123"}}
graph.invoke({"question": "Hi, I need help."}, config)Next steps
- Add real tools such as web search, a vector store, or an API client
- Explore
langgraph.prebuiltfor ready-made ReAct agents - Deploy the graph behind a FastAPI or Streamlit app
LangGraph gives you the control of a state machine with the reasoning power of an LLM. Start small with one graph, then expand nodes and edges as your agent grows.
Abid Ali Awan
Tim Lu
Filip Schouwenaars