For a year, choosing an agent framework was a capability checklist. Only the Claude Agent SDK handed the model a real computer. Only LangGraph gave you durable state that survived a multi-day run. The OpenAI Agents SDK was the elegant orchestrator that made you bring your own everything. You could pick on features.

That era ended on April 15, 2026, when OpenAI shipped a major Agents SDK overhaul: a model-native harness, native sandbox execution across Modal, Daytona, Docker and E2B, durable state via externalized snapshotting and rehydration, and subagents. Those were precisely the gaps that used to route you to the other two. The bright lines are gone. All three now do durable, sandboxed, long-running agents.

So the decision is no longer which one can. It is who do you want to own the loop — and that answer is set by each framework's default, not its feature list.

The one-line answer#

Everything below is the reasoning behind those three sentences.

What actually changed in April — and what didn't#

OpenAI's update was real, not cosmetic. Sandboxed execution means an OpenAI agent can now inspect files, run shell commands, and edit code inside an isolated container — the thing the Claude Agent SDK has done since day one via its Bash tool. Durable state means a run whose sandbox container dies is restored in a fresh container and continues from the last checkpoint — the long-running resilience LangGraph built its reputation on. Subagents mean OpenAI now has isolated delegation, not just lateral handoffs.

What did not change is the philosophy each SDK ships with by default. OpenAI still assumes you design the control flow — a graph of specialist agents connected by handoffs, with the model filling each node. Claude still assumes the model designs the control flow — one agent plans, acts with real tools, and verifies. LangGraph still assumes you want to hand-write the state machine and keep every transition inspectable. New features rode on top of those bets; they did not replace them.

That is why "who owns the loop" is the honest axis now. Convergent capability, divergent defaults.

Claude Agent SDK: inherit a tuned loop#

The Claude Agent SDK is Claude Code as a library. Out of the box the model gets eight tools — Read, Write, Edit, Bash, Glob, Grep, WebSearch, WebFetch — plus permissions, hooks, subagents, and automatic context compaction when the window fills. You do not write a loop; you steer Anthropic's.

from claude_agent_sdk import query, ClaudeAgentOptions

async for msg in query(
    prompt="Find and fix the failing test in this repo.",
    options=ClaudeAgentOptions(permission_mode="acceptEdits"),
):
    print(msg)

The cost of that speed is coupling: it runs Claude models only (via the Anthropic API, Bedrock, Vertex, or Azure), and since June 15, 2026 SDK usage draws on a separate monthly Agent SDK credit — $20 on Pro, $100 on Max 5×, $200 on Max 20× — metered per token apart from interactive Claude Code. If your problem is a coding or filesystem agent, that trade is almost always worth it. If it isn't, keep reading. This is the deep-dive we already ran head-to-head in Claude Agent SDK vs LangGraph.

LangGraph: own the graph#

LangGraph is not a harness — it is the substrate you build a harness on. Agents are directed graphs: nodes are steps, edges are routing logic, and state is explicit and yours. Its durability is the strongest of the three by design. A checkpointer persists state at every superstep — InMemorySaver for dev, SqliteSaver for lightweight deploys, PostgresSaver for production — and that one choice buys you fault recovery, state history, time-travel debugging, and human-in-the-loop interrupts you can pause and resume at any node.

from langgraph.graph import StateGraph
from langgraph.checkpoint.postgres import PostgresSaver

graph = StateGraph(State)
# ... add_node(...), add_edge(...) ...
app = graph.compile(checkpointer=PostgresSaver.from_conn_string(DB_URL))
app.invoke(inputs, config={"configurable": {"thread_id": "run-42"}})

The cost is boilerplate: you write the loop, wire the tools, and manage the state you now own. That is the point. When the workflow is long-running, approval-heavy, and must be auditable — the cases where "let the model decide" is the wrong answer — the explicit graph is the feature, not the tax. And because LangGraph is model-agnostic, you are not betting the app on one vendor.

OpenAI Agents SDK: compose the handoffs#

The OpenAI Agents SDK's core primitive is the handoff: agents transfer control to each other explicitly, each defined by instructions, a model, tools, and the peers it can hand off to. It is multi-agent-first — a fixed routing graph of specialists is its native shape.

from agents import Agent, Runner

billing = Agent(name="Billing", instructions="Handle billing questions.")
triage = Agent(name="Triage", instructions="Route the user.", handoffs=[billing])
Runner.run_sync(triage, "I was double-charged.")

A handoff replaces the running agent and carries the whole conversation forward — a lateral transfer of shared context, distinct from a Claude subagent's clean isolated one. After April, you also get native sandboxes and durable state, so the SDK is no longer "orchestration only." Reach for it when you already know the graph of specialists you want and you want the model filling nodes, not inventing the topology. We compared its primitives to Claude's in Claude Agent SDK vs OpenAI Agents SDK.

How to actually decide#

Pick by the shape of your problem, in this order:

  1. Is the job an agent working in a repo, a filesystem, or a shell? Claude Agent SDK. You will not out-engineer the Claude Code loop this quarter, and you inherit it for free.
  2. Do you need to pause, inspect, edit, and resume state — with an audit trail — possibly across models? LangGraph. Own the graph; the checkpointer is the whole reason it exists.
  3. Is your workflow a known set of specialist roles with clear routing between them? OpenAI Agents SDK. Design the handoff graph and let the model fill each node.
  4. Do you need hard provider independence? That removes the Claude Agent SDK from the table before you weigh anything else.

The features converged in April. The philosophies did not. Choose the default you want to live inside, because that default is what your agent becomes when you stop writing code and start shipping.