The quickest way to make an agent system sound impressive is to draw a tiny org chart.
One agent is the planner. One is the researcher. One writes code. One reviews. One watches the budget. Another sits nearby with a clipboard and the quiet energy of someone who has scheduled a meeting about scheduling meetings.
It feels natural because human teams work by delegation. The problem is that software agents are not coworkers in the human sense. They do not carry shared history, implicit team norms, hallway context, or that one Slack thread everyone pretends they read. When you split work across agents, you are not just assigning tasks. You are creating boundaries where context, assumptions, validation, and responsibility can leak.
That does not mean delegation is bad. Current agent frameworks expose it because it is useful. OpenAI’s Agents SDK has handoffs. Claude Code has custom subagents. LangChain documents subagents, handoffs, skills, and routers as different patterns with different performance and context tradeoffs.
The useful mental model is not an org chart. It is an API.
Every agent delegation point is an interface. Design it like one.
The Espresso Shot: A Handoff Is A Boundary
OpenAI’s Agents SDK describes handoffs as a way for one agent to delegate to another. The interesting detail is how they are represented: a handoff is exposed to the model as a tool. A specialist agent called “Refund Agent” becomes something like transfer_to_refund_agent.
That is a very practical clue. A handoff is not mystical teamwork. It is a model-visible call with a name, description, optional structured metadata, callback behavior, and rules about what the next agent sees.
If you squint, it looks less like “ask Sarah from refunds” and more like:
transfer_to_refund_agent({
reason: "duplicate_charge",
priority: "high",
summary: "User reports two charges for one order"
})
That shape should feel familiar to software engineers. The hard parts are the same hard parts you already know from APIs:
- What is this endpoint for?
- What input does it require?
- What state and permissions does it assume?
- What logs prove it behaved correctly?
- Who owns the result?
Agent delegation gets messy when those questions are replaced by a job title. “Researcher agent” is not a contract. “Find the three most relevant current docs, ignore marketing pages, return source URLs and claim notes, do not edit files” is closer.
Context Does Not Teleport
The most common delegation mistake is assuming context moves like vibes.
It does not.
A subagent may receive a task description, some conversation history, selected files, a tool list, or a filtered summary. It may not receive the chain of small decisions that led to the task. It may not know why one approach was already rejected. It may not see the failure output that made a tiny detail important.
Cognition’s “Don’t Build Multi-Agents” makes this point sharply: actions carry implicit decisions. If two agents work in parallel without enough shared context, they can make incompatible assumptions. One agent chooses a schema shape, another writes API code against a slightly different one, and the final integration step becomes the part of the heist movie where everyone realizes the map was upside down.
This is why delegation often feels great in demos and weird in production. The subtask is clear until it touches another subtask.
For software work, the invisible decisions are often the real work: which compatibility constraint matters, which failing test is signal, which public behavior must not change, which migration path was rejected. If those decisions matter, either keep the work in one continuous agent trace or make the boundary carry them explicitly.
Pick The Pattern By The Shape Of The Work
LangChain’s multi-agent docs are useful because they do not treat every delegation pattern as the same thing. Subagents, handoffs, skills, and routers trade off control, state, parallelism, token use, and context isolation.
Here is the Coffee With Humans version:
Use a single agent when continuity matters more than parallelism. Hard debugging, architecture decisions, tricky refactors, and security-sensitive changes often benefit from one coherent trace. The agent can still use tools, write notes, and ask for help, but the main decision path stays intact.
Use a handoff when control should move to a specialist. This fits workflows where the user or conversation naturally continues with the new agent: triage to billing, support to escalation, planning to execution. Handoffs can be stateful and efficient for repeated specialist interactions, but they are usually sequential. Good handoffs need clear descriptions, typed metadata when useful, and careful input filtering.
Use a subagent when you want bounded work with context isolation. Claude Code’s subagent docs describe patterns such as isolating high-volume operations, running parallel research, and chaining specialists. That is useful when the main conversation should not absorb every search result, log line, or exploratory dead end. The tradeoff is that the subagent may start fresh, repeat context, or miss implicit decisions unless you package the task well.
Use a router when the real problem is dispatch. If a request needs classification before it goes to the right specialist, a router can keep the main flow simple. Routers still need clear categories and ownership for misroutes.
Use a skill when the reusable thing is not an agent identity but a procedure. A skill is often better than a specialist persona when you want the same agent to follow a known workflow: review this kind of file, generate this kind of report, validate this package, format this artifact.
The question is not “how many agents can we use?” It is:
What boundary gives us more reliability, speed, clarity, or isolation than it costs?
If the boundary does not buy something concrete, it is probably just architecture confetti.
Barista’s Tip: The Five-Question Boundary Review
Before adding a handoff, subagent, router, or skill, run a small boundary review.
1. Why Does This Boundary Exist?
Name the benefit. Parallelism, context isolation, specialist tools, safer permissions, reusable procedure, simpler dispatch, or user-facing ownership are all reasonable answers.
“Because agents should collaborate” is not.
2. What Context Crosses It?
Decide what the receiving agent needs:
- task objective
- constraints and non-goals
- decisions already made
- failure outputs or trace snippets
- expected output format
- permissions and forbidden actions
OpenAI handoffs support input filters that can change what history the receiving agent sees. Treat context filtering as design, not cleanup.
3. Who Owns The Decision?
Delegation should not make responsibility disappear.
If a subagent researches options, who chooses? If parallel agents disagree, who resolves the conflict? The answer can be the main agent, the receiving specialist, a deterministic validator, or the human. It just cannot be “the system, somehow.”
4. Which Checks Run Where Risk Happens?
Guardrails are not magic dust sprinkled over a workflow.
OpenAI’s guardrail docs call out an important boundary detail: input guardrails run on the first agent in a chain, output guardrails run on the final output, and tool guardrails are what you use around custom function-tool calls inside the workflow.
That means a delegated workflow with side effects needs checks near the side effects. If the risky thing is a database write, file edit, refund, deployment, email send, or shell command, put validation at that tool boundary.
5. What Trace Proves What Happened?
Delegation without observability is how you get a shrug in JSON.
OpenAI’s tracing docs describe traces for model generations, tool calls, handoffs, guardrails, and custom events. Whether you use OpenAI’s tracing surface, LangSmith, Phoenix, Langfuse, logs, or your own event records, the need is the same: you should be able to reconstruct why control moved, what context crossed, which tools ran, which checks fired, and who produced the final answer.
This matters most when the system fails. “The agent made a bad decision” is not a diagnosis. “The router sent a migration task to the schema agent without the rollback constraint” is something you can fix.
A Small Migration Example
Imagine an agent workflow for a database migration.
The tempting version splits the work immediately:
- schema agent designs the migration
- API agent updates handlers
- test agent updates coverage
- reviewer agent checks everything
That sounds tidy. It may even work for simple changes. Now add a real constraint: the field must be nullable for two deploys because mobile clients update slowly. If the schema agent knows this but the API agent does not, the API handler may require the field immediately. If the test agent sees only the new desired behavior, it may lock in the wrong assumption.
A better boundary design would make the rollout constraint part of the contract:
Objective: add customer_timezone.
Constraint: nullable for two deploys; old clients omit it.
Non-goal: do not require the field at API boundary yet.
Owner: main agent chooses final rollout plan.
Subtasks:
- schema agent: propose additive migration only
- API agent: preserve backward compatibility
- test agent: cover old-client and new-client paths
Trace requirement: each subagent returns assumptions and touched files
Same agents. Very different boundary.
Grounds For Concern: When Not To Delegate
Do not delegate just because the task has multiple nouns. Keep the work together when the pieces are tightly coupled, when implicit decisions are changing quickly, when the main challenge is judgment, or when verification requires a single coherent view of the system.
Be especially cautious with parallel code edits. Parallel research is often fine because the outputs can be compared. Parallel edits against the same code path can create incompatible assumptions, overlapping changes, and review work that costs more than the saved time.
Also be cautious when each subagent needs the full context anyway. If every specialist receives the same giant prompt, the “multi-agent” design may cost more tokens while adding more places for disagreement.
The Last Sip
Agent delegation is useful, but it is not free intelligence. It is control flow.
Handoffs, subagents, routers, and skills help when they create a boundary that improves the workflow: clearer ownership, safer permissions, cleaner context, faster independent work, reusable procedures, or better observability.
They hurt when they become a pretend team meeting where nobody brought the same notes.
So before you add another agent, design the interface. Name the purpose. Scope the context. Put checks where risk happens. Keep the trace. Decide who owns the answer.
That is when delegation stops being an AI org chart and starts behaving like engineering.
Sources On The Counter
- OpenAI’s Agents SDK handoffs docs explain handoffs as tool-represented delegation with typed metadata, callbacks, input filters, and control-transfer semantics.
- OpenAI’s guardrails docs are useful for understanding where input, output, and tool checks actually run in delegated workflows.
- OpenAI’s tracing docs describe built-in traces for model generations, tool calls, handoffs, guardrails, and custom events.
- Anthropic’s Claude Code subagents docs show how custom subagents are described, invoked, constrained, and used for isolated or parallel work.
- LangChain’s multi-agent docs compare subagents, handoffs, skills, and routers by workload shape, cost, state, and context isolation.
- Cognition’s “Don’t Build Multi-Agents” is a sharp practitioner warning about context loss, implicit decisions, and fragile parallel agent designs.