Complete LangGraph Tutorial: Building Complex AI Agents
LangGraph is a library from LangChain for building stateful, multi-actor applications with Large Language Models (LLMs). With LangGraph, you can create complex AI agents with flexible control flow, state management, and the ability to run multiple agents simultaneously.
What is LangGraph?
LangGraph extends LangChain by providing:
- Stateful graphs: Store and manage state between steps
- Cyclic flows: Support for loops and conditionals
- Human-in-the-loop: Manual interaction during workflow
- Persistence: Save state for resume later
- Streaming: Real-time streaming responses
- Building AI agents with multi-step reasoning
- Workflows requiring conditionals and loops
- Applications needing human approval
- Multi-agent systems
- Complex RAG pipelines
Installation
pip install langgraph langchain langchain-openai
Basic Concepts
1. Graph Components
LangGraph consists of:
- State: Data managed throughout execution
- Nodes: Functions that process and modify state
- Edges: Connections between nodes (conditional or fixed)
2. Basic Graph Structure
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, START, END
Define state
class State(TypedDict):
messages: list
currentstep: str
Define nodes
def nodea(state: State) -> State:
state["messages"].append("Processed by Node A")
state["currentstep"] = "a"
return state
def nodeb(state: State) -> State:
state["messages"].append("Processed by Node B")
state["currentstep"] = "b"
return state
Build graph
graph = StateGraph(State)
graph.addnode("nodea", nodea)
graph.addnode("nodeb", nodeb)
Add edges
graph.addedge(START, "nodea")
graph.addedge("nodea", "nodeb")
graph.addedge("nodeb", END)
Compile
app = graph.compile()
Run
result = app.invoke({"messages": [], "currentstep": ""})
print(result)
Building a Simple Chatbot
1. Basic Chatbot with Memory
from typing import Annotated
from typingextensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import addmessages
from langchainopenai import ChatOpenAI
from langchaincore.messages import HumanMessage, AIMessage
State with message history
class ChatState(TypedDict):
messages: Annotated[list, addmessages]
Initialize LLM
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)
Chatbot node
def chatbot(state: ChatState) -> ChatState:
response = llm.invoke(state["messages"])
return {"messages": [response]}
Build graph
graph = StateGraph(ChatState)
graph.addnode("chatbot", chatbot)
graph.addedge(START, "chatbot")
graph.addedge("chatbot", END)
app = graph.compile()
Interactive chat
def chat(userinput: str, history: list = None):
if history is None:
history = []
history.append(HumanMessage(content=userinput))
result = app.invoke({"messages": history})
return result["messages"]
Usage
messages = chat("Hello, who are you?")
print(messages[-1].content)
messages = chat("What can you do?", messages)
print(messages[-1].content)
2. Chatbot with Tools
from typing import Annotated
from typingextensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import addmessages
from langgraph.prebuilt import ToolNode, toolscondition
from langchainopenai import ChatOpenAI
from langchaincore.tools import tool
Define tools
@tool
def searchweb(query: str) -> str:
"""Search the web for information."""
# Simulate web search
return f"Search results for: {query}"
@tool