The sub-agent / handoff / agent-as-tool distinctions from three frameworks map onto one underlying question — who owns the trajectory — and answering it decides which shape you want.
LangGraph has supervisor, hierarchical, and collaborative graphs. OpenAI Agents SDK ships "handoffs" and "agents-as-tools." deepagents has subagents. Each vendor's vocabulary hides the same underlying distinction: who owns the trajectory once control transfers. Handoffs give it away completely; agents-as-tools keep it; supervisor delegates and reclaims. Pick the wrong shape for the task and you get either lost context (handoff into a specialist that never returns) or a blown context budget (agent-as-tool that dumps its full transcript back). This essay maps the vocabularies onto the one axis that matters, then walks the failure mode each shape hides.
Three vendors, three vocabularies, the same primitives underneath.
The vocabulary confusion is the first tax. LangGraph's supervisor graph is a coordinator node that dispatches to worker nodes and reclaims control on their return; its hierarchical graph nests supervisors; its collaborative graph lets peers route to each other without a central owner. OpenAI's Agents SDK reduces the space to two primitives: handoffs — control transfers to another agent that continues the user-facing conversation — and agents-as-tools — one agent invokes another the way it would call any tool, then receives the return value and keeps going. deepagents packages sub-agents as delegated context-isolated workers dispatched from a "main" agent that stays in charge of the plan.
vocabulary map trajectory ownership return semantics
─────────────────────────────────────────────────────────────────────────────
LangGraph supervisor → caller keeps it structured worker result
LangGraph hierarchical → per-subtree owner summary up each level
LangGraph collaborative → transfers on each hop whichever peer holds it
OpenAI SDK handoff → callee takes it conversation continues there
OpenAI SDK agent-as-tool → caller keeps it tool-shaped return value
deepagents sub-agent → main agent keeps it filtered artifact only
Once you overlay the three vocabularies you can see it: LangGraph supervisor, OpenAI agent-as-tool, and deepagents sub-agent are the same primitive at three names — a caller-retained delegation. LangGraph collaborative and OpenAI handoff are the same primitive at two names — a full trajectory transfer. LangGraph hierarchical is the same primitive as supervisor/worker nested one level, and the essay on multi-agent topologies already covers when the extra hop earns its lossy summarization. The distinction that actually varies across the six words is who holds the trajectory next turn.
Trajectory ownership is the axis; every other trade-off follows from it.
"Trajectory" means the ongoing conversation state, the pending user expectation, and the responsibility to produce the next user-visible response. If the caller keeps the trajectory, the callee is a subroutine: it runs in its own scope, returns a value, and the caller resumes composing its answer. If the callee takes the trajectory, the caller is done — its context is not consulted again this turn (and often not at all), and any thread of reasoning it was maintaining is gone unless it was written down explicitly.
Everything else that people argue about — context sharing, tool visibility, budget accounting, tracing — is downstream of ownership. Caller-retained delegation lets the caller filter what the sub-agent sees on the way in and filter what it sees on the way out; the sub-agent's own reasoning trace stays inside its scope. Trajectory-transfer delegation gives the callee whatever the caller had (or a copy of it) and expects nothing back — the callee is now the one talking to the user. Which one you want is the same question as which failure you can absorb: losing the caller's plan or losing the callee's specialized reasoning.
Handoff hides a return-path problem: control that transfers cleanly rarely returns cleanly.
The tempting shape of a handoff is "route to the specialist agent that knows how to handle this." Refund questions go to the refund agent; billing questions go to billing. In a scripted flow this works. In an agentic flow it fails on the first ambiguous case: the specialist finishes its work and now needs to hand control back to someone, but "back" is under-specified. Does the router re-evaluate? Does the specialist return a status object the router parses? Does the conversation just end on the specialist's turn? Each framework picks a default and each default breaks a different case — OpenAI's SDK ends the conversation on the receiving agent unless the receiving agent itself hands off again, which produces "stuck at the specialist" transcripts where the user asks a follow-up unrelated to refunds and gets a refund answer anyway.
The other handoff failure is context inheritance. If the receiving agent inherits the full conversation, its own system prompt competes with everything the router already established — persona drift, tool-selection drift, and the confusing UX of a persona change mid-turn. If it inherits none of the conversation, the user has to restate context. Neither is comfortable. The 2026 discipline for handoff is to pass a compact handoff message — the routing agent's summary of what the user wants and what has already been established — and to define an explicit escalation path back, not to rely on the receiving agent to notice it should transfer again.
Agent-as-tool hides a context-budget problem: the return value is bigger than a tool return has any right to be.
Agent-as-tool feels safer because the caller keeps the trajectory. The failure mode is what the callee returns. A specialist agent that spent 30k tokens researching a topic wants to hand back what it learned; the naive return is the full transcript, which the caller then merges into its own context. Two calls like this and the caller's context is full of sub-agent transcripts rather than the plan it was executing. The "context overflows at run 3" pattern is what teams discover after shipping a demo that worked at run 1.
The mitigation is a hard interface between caller and callee. Sub-agent inputs are a scoped instruction and only the context the sub-agent needs (not the caller's full state); sub-agent outputs are a structured artifact — a summary, a set of findings, a decision — not a transcript. deepagents makes this the default: the main agent sees only the filtered artifact the sub-agent returns, not its intermediate work. LangGraph's supervisor graph achieves the same effect by defining the worker return type explicitly. OpenAI's agent-as-tool default returns whatever the callee's last message was, which is why teams building on it end up writing wrappers that summarize before returning. The general context-budgeting rule — pass compact structured artifacts up, raw transcripts stay in scope — is what makes agent-as-tool survive fan-out.
# Three shapes, one task: research a topic and write a summary. # 1. Handoff (OpenAI SDK): trajectory transfers, no return. @agent.handoff_to(research_agent) def route(query): return handoff_message(intent="research", brief=query) # 2. Agent-as-tool (OpenAI SDK / LangGraph supervisor): # caller keeps trajectory, callee returns a structured artifact. @tool def research(query: str) -> Findings: result = research_agent.run(query, budget=15_000) return result.to_artifact() # NOT the full transcript # 3. Sub-agent (deepagents): main agent dispatches with a scoped brief; # filtered artifact returns, intermediate reasoning stays isolated. main.dispatch(sub="researcher", brief=query, success="3-bullet summary")
Supervisor delegation is the shape that ships; its ceiling is the supervisor itself.
LangGraph supervisor, deepagents sub-agents, and OpenAI agent-as-tool converge on the same operational pattern: a caller that owns the plan, dispatches scoped subtasks to workers, and reconciles the workers' returns into one coherent answer. That is the pattern the supervisor/worker essay treats in depth, and it is the one production multi-agent systems keep landing on. The ceiling is universal: the supervisor's context has to hold the plan plus every worker's structured result at aggregation time, and its own reasoning is on the critical path twice. When fan-out exceeds what one supervisor can reconcile, you go hierarchical — a supervisor whose workers are themselves supervisors — accepting the extra lossy summarization hop deliberately.
The three vocabularies converge here because caller-retained delegation is the shape that survives real workloads. Handoffs are useful for the narrow case where the trajectory legitimately belongs to a specialist for the rest of the conversation (routing into a domain specialist that stays for the session); agent-as-tool with structured artifacts is what you reach for when the task is "do this specialist thing and give me back a result." Everything else is a variant.
Choosing the shape: two questions decide it.
Question one: does the callee's work continue the user-facing conversation, or does it produce a result for the caller to use? Continue the conversation → handoff (LangGraph collaborative, OpenAI handoff). Produce a result → caller-retained delegation (supervisor, agent-as-tool, sub-agent). Question two, only if you picked caller-retained: can the callee's return fit in a structured artifact the caller reads in one turn, or does the caller need to interact with the callee across multiple turns? One-shot artifact → agent-as-tool with an explicit return schema. Multi-turn → supervisor graph with checkpointed intermediate state. If you cannot answer either question in one sentence, the decomposition is wrong before the framework choice matters. Whether to split at all is upstream — see the single-vs-multi-agent essay for the price of adding the second agent in the first place. Once you have decided to split, the shape is chosen by trajectory ownership, and everything else follows.