Skip to the page

LangGraph vs CrewAI vs Claude Agent SDK: which AI agent framework to use

Pick LangGraph when you want to draw the agent's steps yourself as a graph, with saved state you can pause and resume; CrewAI when the job splits into roles, such as a checker and a writer, that hand work to each other; and the Claude Agent SDK when you want Claude Code's own loop, tools and permission controls inside your program and are happy to use Claude models. All 3 run the same loop underneath - the model asks for a tool, code runs it, and the result goes back to the model.

Take this page into your AI

Open in ChatGPT (new tab)Open in Claude (new tab)
  • LangGraphLangChainA low-level framework for agents as graphs. You write each step as a node and the moves between steps as edges, and its runtime saves the state as it goes.pip install -U langgraph langchain langchain-anthropicDocumentation
  • CrewAICrewAIA framework for teams of agents. Each agent has a role, a goal and tools, a crew runs their tasks in order or under a manager, and a Flow wraps crews in steps you control.uv add "crewai[anthropic]"Documentation
  • Claude Agent SDKAnthropicClaude Code as a library. The same agent loop, built-in tools, permission rules, hooks and sessions, run from your own Python or TypeScript code.pip install claude-agent-sdkDocumentation

All 3 are ways to build an agentAgentA model that uses tools in a loop, deciding each next step from what the last one returned, until the task is done.: a program where a model decides the next step, asks for a toolTool UseGiving a model a list of things it can ask to have done, such as search the web or read a file. The model asks; the program around it does the work and hands back the result., reads what the tool returned and goes again until the job is done. They differ in how much of that loop you write, how many agents you can run together and what they give you for the parts that go wrong, such as an action a person must approve first.

What each one is

LangGraph, from LangChain, is the lowest level of the 3. You describe the agent as a graph: each step is a node, a plain Python function, and the moves between steps are edges. A loop exists only because you draw an edge from the tools node back to the model node. Its runtime saves the graph's state as it runs, which is what lets it pause for a person and carry on later. LangGraph does not need LangChain, but its examples use LangChain for the model and the tools.

CrewAI starts from people, not steps. You describe agents the way you would describe staff, with a role, a goal and a backstory, give each one the tools its job needs, and write tasks that say what to do and what to hand back. A crew runs the tasks in order, passing each answer on, or puts a manager agent in charge of handing them out. For the parts that must not be left to a model, CrewAI has Flows: plain steps in Python, with state, that run crews where they need judgment.

The Claude Agent SDK, from Anthropic, is Claude Code as a library. The loop, the handling of the context windowContext WindowEverything a model can see at once while it writes an answer, counted in tokens. When the window is full, something has to be left out., the tools for files, the shell and the web, the permission rules, subagentsSubagentAn agent started by another agent for one part of a task. It works in its own fresh context and returns only its findings., hooks and sessions are all already written. You call it with options and your own tools, and it runs the same agent that runs in the Claude Code terminal. The catch is that it runs Claude models only.

Side by side

LangGraph vs CrewAI vs Claude Agent SDK, side by side
What you writeLangGraphThe graph itself - a node that calls the model, a node that runs tools, and the edges that loop between them.CrewAIAgents (role, goal, backstory, tools) and tasks (what to do, what to hand back), then a crew that runs them.Claude Agent SDKThe options for a run - the prompt, which tools are allowed, your own tools and hooks. The loop is already written.
Who runs the loopLangGraphYour graph. Nothing repeats unless you draw an edge back to the model.CrewAICrewAI runs each agent's loop, up to max_iter steps (20 unless you set it).Claude Agent SDKThe SDK, with the loop that runs Claude Code. max_turns caps it; there is no cap unless you set one.
More than 1 agentLangGraphSubgraphs, each a graph of its own placed inside another.CrewAIThe core idea. A crew runs its tasks in order (sequential) or a manager agent hands them out (hierarchical).Claude Agent SDKSubagents, which Claude starts for focused jobs, each with its own context, prompt and tools.
A person's approvalLangGraphinterrupt() pauses the graph and saves its state; Command(resume=...) carries on from the same thread, even much later.CrewAI@human_feedback on a Flow step pauses for a person. human_input=True on a task asks for a review of its answer once the task is done.Claude Agent SDKA PreToolUse hook or the canUseTool callback allows, denies or changes each tool call before it runs.
Memory and stateLangGraphCheckpointers save a thread's state at every step; stores keep facts across threads.CrewAIA memory system for agents and crews, and state that a Flow carries from step to step.Claude Agent SDKSessions keep the conversation, to continue, resume or fork later. CLAUDE.md and skills load from the project.
ModelsLangGraphAny provider with a LangChain integration, such as Anthropic, OpenAI or Google.CrewAINative for OpenAI, Anthropic, Google, Azure, Bedrock and Snowflake Cortex; others through LiteLLM.Claude Agent SDKClaude only, through the Claude API, Amazon Bedrock, Google Cloud or Microsoft Foundry.
Tools it bringsLangGraphNone of its own. Tools come from your code or from LangChain.CrewAIA toolkit of ready tools, such as web search and code sandboxes, and LangChain's tools.Claude Agent SDKClaude Code's own - read, write and edit files, run commands, search the web. tools=[] turns them off.
LanguagesLangGraphPython and JavaScript.CrewAIPython 3.10 to 3.13.Claude Agent SDKPython 3.10 and later, and TypeScript on Node.js 18 and later.
LicenceLangGraphMIT.CrewAIMIT.Claude Agent SDKUse is under Anthropic's Commercial Terms of Service.
Best atLangGraphFixed processes with branches and pauses, where you decide every step and can test the path.CrewAIWork that splits into roles that hand results to each other.Claude Agent SDKAgents that work on files and run commands, as a coding agent does, with Claude Code's safety controls.

Which one fits

What you need

A fixed process with branches

LangGraph

You draw each step and each branch, so the path is yours to test and audit. Steps you write by hand and steps the model decides sit in the same graph.

The same agent in each

A shop's refund agent - look up order A-1042, then refund it, with a person approving any refund over 100. The order data is made up so each file stands alone; set ANTHROPIC_API_KEY to run it.

refund_agent.py
from langchain.chat_models import init_chat_model
from langchain.messages import SystemMessage, ToolMessage
from langchain.tools import tool
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, MessagesState, StateGraph
from langgraph.types import Command, interrupt

ORDERS = {"A-1042": "total 140.00, delivered 6 days late"}


@tool
def get_order(order_id: str) -> str:
    """Look up an order: its total and how it was delivered."""
    return ORDERS.get(order_id, "no such order")


@tool
def refund(order_id: str, amount: float) -> str:
    """Refund an amount on an order."""
    # Over 100, the graph stops here and waits for a person.
    if amount > 100 and not interrupt({"refund": order_id, "amount": amount}):
        return "A person declined this refund."
    return f"Refunded {amount:.2f} on {order_id}."


TOOLS = {t.name: t for t in (get_order, refund)}
model = init_chat_model("anthropic:claude-sonnet-5-5").bind_tools(list(TOOLS.values()))


def call_model(state: MessagesState):
    rules = SystemMessage("You handle refunds for a shop. Look up the order before you refund it.")
    return {"messages": [model.invoke([rules, *state["messages"]])]}


def run_tools(state: MessagesState):
    calls = state["messages"][-1].tool_calls
    return {"messages": [ToolMessage(TOOLS[c["name"]].invoke(c["args"]), tool_call_id=c["id"]) for c in calls]}


def next_step(state: MessagesState):
    return "tools" if state["messages"][-1].tool_calls else END


graph = StateGraph(MessagesState)
graph.add_node("model", call_model)
graph.add_node("tools", run_tools)
graph.add_edge(START, "model")
graph.add_conditional_edges("model", next_step, ["tools", END])
graph.add_edge("tools", "model")
agent = graph.compile(checkpointer=InMemorySaver())

run = {"configurable": {"thread_id": "order-A-1042"}}
result = agent.invoke({"messages": [("user", "Order A-1042 came late. Please refund it.")]}, run)
if "__interrupt__" in result:  # paused before the refund, its state saved
    result = agent.invoke(Command(resume=True), run)  # a person said yes
print(result["messages"][-1].content)

The loop is the edge from tools back to model. interrupt() saves the state and stops the run; the second invoke, with Command(resume=True) and the same thread_id, carries on where it stopped.

Put side by side, the files show where each one puts the work. The LangGraph file is the longest because the loop is written out: a node for the model, a node for the tools and the edge back. In return, every step is a function you can test, and the pause before the refund is part of the graph's saved state.

The CrewAI file reads like a job description. There is no loop in it at all; CrewAI runs each agent's loop for you. What it does not show is the approval, because a crew on its own has no step that waits for a person before a tool runs. That belongs in a Flow around the crew.

The Agent SDK file is mostly your own tools. The loop is Claude Code's, and the approval is a hook, the same kind of hook that guards a Claude Code session. Its human-in-the-loopHuman in the LoopA person approves, corrects or stops an AI system at set points, such as before an agent sends, pays or deletes something. step waits in the running program; to stop the program and resume the next day, a hook can defer the call instead.

Pausing for a person

Any agent that spends money, sends messages or deletes data needs a point where a person says yes. This is where the 3 differ most.

  • LangGraph saves the whole state at the pause. interrupt() stops the run, the state goes to the checkpointer, and the run carries on only when you call it again with Command(resume=...) and the same thread id. With a checkpointer that writes to a database, the wait can last as long as you like.
  • CrewAI pauses in a Flow. The @human_feedback decorator stops at a step, collects what the person says and can route the flow to an approved or a declined step.
  • The Agent SDK decides per tool call. A PreToolUse hook or the canUseTool callback sees each call's input before it runs and can allow it, deny it with a reason Claude reads, or change it.

Things that trip people up

  • LangGraph runs the paused step again. On resume, the node that called interrupt() starts again from its first line, so anything before the pause runs twice. Keep side effects, such as the refund itself, after it.
  • CrewAI falls back to an OpenAI model. An agent with no llm uses the model named in OPENAI_MODEL_NAME, so set llm on each agent. Claude models also need the extra in crewai[anthropic].
  • CrewAI's human_input is a review, not a gate. It asks a person about a task's answer after the task's tools have already run.
  • The Agent SDK's allowed_tools does not limit Claude. It approves the tools it lists without asking; other tools are still there and go through the permission rules. To remove Claude Code's own tools, pass tools=[] or name them in disallowed_tools.
  • The Agent SDK is not for claude.ai sign-in. A product built on it signs in with an API key, keeps its own name and must not look like Claude Code.

When you need none of them

A framework earns its place when you need saved state, pauses for a person, several agents or ready tools. For a model call with 1 or 2 tools, send the tool definitions with the request and write the loop yourself: it is a short while loop. MCP vs function calling shows that loop in full, and How AI agents work follows one request through every step of it.

Questions

Is LangGraph better than CrewAI?
Neither is better in general; they suit different work. LangGraph gives you control of every step as a graph, with saved state, pauses and resumes, so it suits fixed processes you need to test. CrewAI starts from roles and tasks, so a team of agents that hand work to each other takes less code. For a long-running process with approvals, LangGraph's checkpoints help; for a research-then-write pipeline, CrewAI's crews fit naturally.
Can I use the Claude Agent SDK with OpenAI or other models?
No. The Claude Agent SDK runs Claude models only, through the Claude API, Amazon Bedrock, Google Cloud or Microsoft Foundry. If you need models from several makers, LangGraph and CrewAI both work with most providers.
Do I need a framework to build an AI agent?
Not always. An agent is a loop - send the model your tools, run the tool it asks for, send back the result, repeat until it answers. For 1 or 2 tools that loop is a few lines against the model's API. A framework earns its place when you need saved state, pauses for a person, several agents or ready tools.
What is the difference between LangChain and LangGraph?
LangChain is the agent framework, with integrations for models and tools and ready-made agent loops. LangGraph is the lower-level runtime underneath, for graphs with saved state, pauses for a person and streaming. You can use LangGraph without LangChain, though its examples use LangChain for models and tools.
Is the Claude Agent SDK the same as Claude Code?
It is Claude Code as a library. The Agent SDK runs Claude Code, with its agent loop, built-in tools, permissions, hooks and sessions, from your own Python or TypeScript program. Products built on it must keep their own name and not present themselves as Claude Code.
Which framework is best for multi-agent systems?
CrewAI is built around several agents from the start, run in order or under a manager. LangGraph puts agents in subgraphs you connect yourself, which takes more code but gives more control. The Claude Agent SDK lets Claude hand focused jobs to subagents, each with its own context and tools.

Sources

Where each fact comes from

  1. 1LangGraph overview
  2. 2LangGraph quickstart
  3. 3Interrupts
  4. 4Persistence
  5. 5LangGraph overview (JavaScript)
  6. 6Install LangGraph
  7. 7langchain-ai/langgraph
  8. 8CrewAI introduction
  9. 9Agents
  10. 10Tasks
  11. 11Processes
  12. 12Flows
  13. 13LLMs
  14. 14Tools
  15. 15Installation
  16. 16crewAIInc/crewAI
  17. 17Agent SDK overview
  18. 18Agent SDK quickstart
  19. 19How the agent loop works
  20. 20Give Claude custom tools
  21. 21Intercept and control agent behavior with hooks
  22. 22Handle approvals and user input
  23. 23Work with sessions
  24. 24Subagents in the SDK