How to Build an AI Agent with LangGraph and Claude
Learn how to build a robust, multi-step AI agent using LangGraph and the Claude API, complete with tool use and human-in-the-loop approvals.
By AI Mastermind Lab · Published 2 Mar 2026
LangGraph is quickly becoming the industry standard orchestration framework for multi-agent workflows. In this tutorial, we will build a robust AI researcher using Anthropic's Claude 3.5 Sonnet.
The Paradigm: State Machines
LangGraph represents agents as state machines (graphs). You define:
- State: The schema representing the state of your application.
- Nodes: Python functions representing agents or tools.
- Edges: The conditional logic connecting the nodes.
1. Defining the State
We define a dictionary-like state containing the conversation history.
from typing import TypedDict, Annotated
from langgraph.graph.message import add_messages
class AgentState(TypedDict):
messages: Annotated[list, add_messages]
2. Defining Tools and the LLM
We bind a mathematical calculator tool to Claude.
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_anthropic import ChatAnthropic
# An internet search tool
search_tool = TavilySearchResults(max_results=2)
tools = [search_tool]
# Initialize Claude and bind the tools to it
llm = ChatAnthropic(model="claude-3-5-sonnet-20240620")
llm_with_tools = llm.bind_tools(tools)
3. Creating the Graph Nodes
The two primary nodes: the LLM making choices, and the environment executing tools.
from langgraph.prebuilt import ToolNode
# Node 1: Executing the LLM
def invoke_agent(state: AgentState):
response = llm_with_tools.invoke(state["messages"])
return {"messages": [response]}
# Node 2: The pre-built tool executor
tool_node = ToolNode(tools)
4. Wiring the Graph
We define the control flow. If Claude calls a tool, go to the tool node. Otherwise, end.
from langgraph.graph import StateGraph, END
from langgraph.prebuilt import tools_condition
graph_builder = StateGraph(AgentState)
# Add nodes
graph_builder.add_node("agent", invoke_agent)
graph_builder.add_node("tools", tool_node)
# Add edges
graph_builder.set_entry_point("agent")
# If the agent calls a tool -> go to tools. Otherwise -> END.
graph_builder.add_conditional_edges("agent", tools_condition)
graph_builder.add_edge("tools", "agent")
# Compile the final graph
agent_executor = graph_builder.compile()
5. Execution
response = agent_executor.invoke({
"messages": [("user", "Search the web for the latest developments in LK-99 superconductors and summarize them.")]
})
print(response["messages"][-1].content)
Claude will now iteratively plan searches, read the results from Tavily, and synthesize a final report.