TL;DR

I built the same small agent three times this month, once in each framework, to stop guessing which one I’d reach for by default. Here’s the short answer. Pick OpenAI Agents SDK if you want a working multi-agent system today and don’t need to think about graph topology. Pick CrewAI when your problem maps cleanly onto a team of specialists with roles. Pick LangGraph when the workflow is branchy, long-running, and has to survive a crash or a human interrupt without losing state. All three are MIT-licensed and free at the library level; you pay for the model calls and, optionally, a managed runtime. None of them is a wrong pick. They’re built for different problems.

Why I bothered writing the same agent three times

Framework comparisons usually get written from the docs. I wanted to write this one from the friction, so I picked a task small enough to finish in each but real enough to expose the seams: a two-step “research then summarize” agent that calls one tool, hands off to a second role, and returns a clean answer.

That exercise sorted the three faster than any feature table could. The OpenAI SDK version was running in about fifteen minutes. CrewAI took slightly longer because I had to think in roles and tasks rather than functions, but the mental model clicked once. LangGraph took the longest by a wide margin, and it was the only one where, an hour in, I actually understood what my agent would do when a node threw halfway through. That tradeoff, speed-to-first-run against control-when-it-matters, is the whole comparison in one sentence.

I’ve been building agent glue for a while now, including a from-scratch tool-calling loop in Go with no framework at all, and that background colors my bias: I like knowing exactly what the loop does. If you share that instinct, you’ll feel the same pull toward LangGraph I did. If you don’t, you’ll be happier and faster somewhere else.

The one-screen comparison

DimensionLangGraphCrewAIOpenAI Agents SDK
Mental modelStateful graph (nodes + edges)Crew of role-based agentsAgents that hand off to agents
Learning curveSteepGentleVery gentle
Control over flowTotal (cycles, branches, routing)Sequential or hierarchicalHandoff chains
Durable / resumableYes, checkpoint per nodeVia Flows, less granularSessions for memory, no built-in checkpointing
Human-in-the-loopFirst-classSupportedSupported
Model flexibilityAny (via LangChain)Any (via LiteLLM)Any (via LiteLLM adapter)
Best forComplex production pipelinesFast role-based prototypesSimple-to-medium multi-agent apps
LicenseMITMITMIT

Those are three answers to the same question. The “winner” column changes the moment your requirements change.

39M+
LangGraph monthly PyPI downloads (reported)
54K+
CrewAI GitHub stars (reported, mid-2026)
100+
Models the OpenAI SDK reaches via LiteLLM

Three philosophies, three shapes of code

The clearest way to feel the difference is to look at the same idea expressed three ways. I’ve trimmed each to the load-bearing lines.

OpenAI Agents SDK: agents that hand off

The OpenAI Agents SDK is the successor to OpenAI’s old Swarm experiment, and it keeps Swarm’s core idea: an agent is an LLM with instructions and tools, and agents delegate to each other through handoffs. The whole surface area is small on purpose.

from agents import Agent, Runner, function_tool

@function_tool
def get_facts(topic: str) -> str:
    return f"Three verified facts about {topic}..."

researcher = Agent(
    name="Researcher",
    instructions="Gather facts. Never guess.",
    tools=[get_facts],
)
writer = Agent(
    name="Writer",
    instructions="Turn the research into a 3-sentence brief.",
)
triage = Agent(
    name="Triage",
    instructions="Send research tasks to the Researcher, writing to the Writer.",
    handoffs=[researcher, writer],
)

result = Runner.run_sync(triage, "Summarize the EU AI Act delay for developers.")
print(result.final_output)

There’s no graph to declare and no orchestration object. The runner owns the loop, the model decides when to hand off, and you read the trace afterward to see what happened. For a team already living inside the OpenAI API, this is the least new vocabulary you can adopt.

CrewAI: a crew with roles and tasks

CrewAI asks you to think like a manager. You describe agents by role, goal, and backstory, hand each a task, and let the crew run them in order. It reads almost like a project brief.

from crewai import Agent, Task, Crew, Process

researcher = Agent(
    role="Researcher",
    goal="Find accurate facts about {topic}",
    backstory="A meticulous analyst who never guesses.",
)
writer = Agent(
    role="Writer",
    goal="Turn research into a tight brief",
    backstory="A former newsroom editor with a hard word limit.",
)

research = Task(description="Research {topic}", agent=researcher,
                expected_output="5 bullet facts")
brief = Task(description="Write the brief", agent=writer,
             expected_output="A 3-sentence summary")

crew = Crew(agents=[researcher, writer], tasks=[research, brief],
            process=Process.sequential)
print(crew.kickoff(inputs={"topic": "the EU AI Act timeline"}))

That backstory field reads like fluff, but it’s prompt scaffolding that measurably shapes the output voice. CrewAI also has a second mode, Flows, for event-driven orchestration when a plain sequential crew isn’t enough. The two-layer design (Crews for autonomy, Flows for control) is how CrewAI answers the “but I need real branching” objection.

LangGraph: a state machine you can pause

LangGraph makes you spell out the graph. You define a shared state, write each step as a node that reads and returns part of that state, and wire the edges yourself, including conditional ones and cycles.

from typing import TypedDict
from langgraph.graph import StateGraph, START, END

class State(TypedDict):
    question: str
    answer: str

def research(state: State) -> dict:
    return {"answer": f"Facts about {state['question']}"}

def review(state: State) -> dict:
    return {"answer": state["answer"] + " — reviewed"}

graph = StateGraph(State)
graph.add_node("research", research)
graph.add_node("review", review)
graph.add_edge(START, "research")
graph.add_edge("research", "review")
graph.add_edge("review", END)

app = graph.compile()
print(app.invoke({"question": "What changed in the EU AI Act?"}))

Running that prints the accumulated state:

{'question': 'What changed in the EU AI Act?',
 'answer': 'Facts about What changed in the EU AI Act? — reviewed'}

More code, yes. But that State and those explicit edges are what let you attach a checkpointer and get resumability for free, which the other two don’t hand you at the same granularity.

Where each one actually wins

Control and durability

LangGraph is alone at the top here. Its checkpointing saves state at every node, so an interrupted run, whether from a crash or a human-review pause, resumes from the last completed node instead of starting over. One caveat worth internalizing before you trust it in production: checkpoints save between nodes, not inside them. If a node makes three tool calls and dies on the fourth, all three run again on resume. Design your nodes small if idempotency matters.

CrewAI reaches similar territory through Flows, but the control is coarser. The OpenAI SDK gives you Sessions for conversation memory, which is a lighter concern than durable execution (and a step below the dedicated agent-memory frameworks if you need memory that persists across runs). If the process dies mid-run, you’re replaying, not resuming.

Time to first working agent

The OpenAI SDK wins this outright. A useful multi-agent handoff fits in well under thirty lines, and if you already know the Chat Completions shape, there’s almost nothing new to learn. CrewAI is close behind for anyone who finds the role metaphor natural. LangGraph comes in last, and its own docs don’t pretend otherwise. The payoff for the extra setup shows up later, in production, once the simpler tools start to creak.

Model flexibility

This one’s closer than the marketing suggests. The OpenAI SDK is provider-agnostic through a LiteLLM adapter, so you can point it at Claude or a local model as easily as at GPT. CrewAI routes through LiteLLM too. LangGraph inherits every integration LangChain has, which is the largest set of the three. In practice all three will happily drive Claude or an open-weight model behind vLLM, so “which providers” rarely decides the choice anymore. If you want the deeper picture on serving those models efficiently, that’s its own rabbit hole covered in the LLM inference efficiency guide.

Observability

LangGraph plugs into LangSmith for step-level tracing and time-travel debugging, which is genuinely ahead of the pack for inspecting a stuck run. The OpenAI SDK ships built-in tracing that’s clean and enough for most apps. CrewAI’s observability improved a lot in 2026 but leans on its Enterprise dashboards for the richest view.

Pricing and getting started

The libraries themselves cost nothing. The bills come from two places: the model API you point them at, and any managed runtime you opt into.

FrameworkLibraryManaged / hosted tier
LangGraphMIT, freeLangGraph Platform: free self-hosted to ~100K node executions/mo, then Plus at $39/user/mo plus usage (reported, July 2026)
CrewAIMIT, freeCrewAI Enterprise: hosted dashboards, SSO, controls (custom pricing)
OpenAI Agents SDKMIT, freeNone of its own; you pay the underlying model API

If you’re prototyping, ignore the managed tiers entirely. Install the library, plug in an API key, and you’re running. The managed platforms only start to matter when you need audit trails, team access control, or someone else to own the deployment.

The honorable mentions I’d still check

Three frameworks can’t cover the whole field, and pretending otherwise would date this piece fast.

  • Pydantic AI — the type-safe option. If you love Pydantic’s validation and want your agent I/O checked the same way, it’s the cleanest fit, and it shows up in the autocomplete right next to these three for a reason.
  • Google ADK and the Microsoft Agent Framework (the merged successor to AutoGen and Semantic Kernel) — both are serious, cloud-aligned entrants. If your infrastructure already lives in GCP or Azure, start there before the three above.
  • AutoGen classic — still around, still in tutorials, but most new Microsoft-stack work now points at the merged Agent Framework.

None of these change my top-line recommendation, but any of them can be the right call inside a specific stack.

The recommendation matrix

Your situationReach for
First multi-agent app, want it running todayOpenAI Agents SDK
Problem is naturally a team of specialistsCrewAI
Branchy, long-running, must survive interruptsLangGraph
Deeply invested in the OpenAI stackOpenAI Agents SDK
Non-technical stakeholders read your agent designCrewAI (roles read like English)
You want type-checked inputs and outputsPydantic AI
Already all-in on GCP or AzureGoogle ADK / Microsoft Agent Framework

My own default, for what it’s worth, has become “start on the OpenAI SDK, and the day I catch myself faking durable state or hand-rolling conditional routing, port to LangGraph.” I’ve never regretted starting simple and I’ve often regretted starting complex.

FAQ

Is LangGraph better than CrewAI?

Not universally. LangGraph is better for complex, stateful, production workflows that need branching, cycles, and crash recovery. CrewAI is better when you want to prototype a role-based team fast without reasoning about graph topology. For a linear “do these steps in order” job, CrewAI gets you there with less code; for a system that has to survive failures and human interrupts, LangGraph is worth its steeper curve.

Is CrewAI built on LangChain?

Not anymore. Early CrewAI used LangChain under the hood, but the project was rebuilt to be an independent, standalone framework with no LangChain dependency. That’s a deliberate selling point for CrewAI today: a leaner core you can reason about without pulling in the full LangChain stack.

Can the OpenAI Agents SDK use non-OpenAI models?

Yes. Despite the name, the SDK is provider-agnostic through a LiteLLM adapter (and MCP for tools), so you can run it against Claude, Gemini, or a local open-weight model. You lose nothing structural by pointing it elsewhere; the agent, handoff, and guardrail primitives work the same.

Which AI agent framework is best for production in 2026?

For durable, observable, controllable production pipelines, LangGraph leads on maturity, and its LangSmith tracing and checkpointing are hard to match. But “best for production” depends on the workload: a well-scoped CrewAI Flow or an OpenAI SDK app with good monitoring is production-viable too. Match the framework to the failure modes you actually need to handle.

Are these frameworks free?

The core libraries are all MIT-licensed and free to use. Your real costs are the model API calls each framework makes on your behalf, plus optional managed runtimes (LangGraph Platform, CrewAI Enterprise) if you want hosted deployment, dashboards, and access controls.

Sources

Bottom line

There’s no framework you’ll regret learning, because the concepts port. Roles, handoffs, and stateful graphs are three lenses on the same job: get a few LLM calls to cooperate without turning your codebase into a pile of if statements. Start with the OpenAI Agents SDK to feel the shape of the problem, adopt CrewAI when your work is genuinely a team of specialists, and graduate to LangGraph the first time you need an agent that can crash, pause, and pick up exactly where it left off. Pick for the failure mode you’ll actually hit in production. Everything else is a preference you can change later.