+1 (570) 533-9287

Subagents Without the Sprawl: When to Split a LangGraph Agent, and What It Costs

Multi-agent is the default answer in every architecture thread right now. Supervisors, subagents, handoffs, deep agents, planner-worker fleets. Some of it is real: a well-placed subagent fixes a class of failure that no amount of prompt editing will. Most of it, in the code we read, is an org chart drawn over a problem that had one loop and needed one loop.

This post is the decision procedure we use with clients, and the bill that comes with saying yes.

The only good reason to split: context, not tidiness

A subagent buys you exactly one durable thing — a separate context window with its own tools, its own instructions, and its own return value. Everything else people claim for multi-agent (modularity, specialization, "each agent does one job well") is available inside a single agent with better prompts and fewer tools.

So the test is mechanical. Split when the work generates a large volume of intermediate tokens that the main loop must not carry:

  • Search and read tasks. A research step that pulls twelve documents, skims them, and needs two paragraphs back. Twelve documents in the main window is context rot by turn four; two paragraphs is free.
  • Long tool transcripts. Log grepping, browser sessions, repeated SQL exploration. Fifty noisy tool results, one answer.
  • Genuinely different tool sets with different trust levels. An agent that touches untrusted web content should not also hold the tool that issues refunds. That is a containment boundary, not a style choice.

Do not split for these:

  • "Separation of concerns." Files and functions do this. Agents cost tokens.
  • "Each agent has a clean persona." A section header in one system prompt does the same work for zero latency.
  • "The model is confused by ten tools." Reduce or rename the tools first. Tool-selection errors are usually a schema and naming problem; we have seen a rename from query to search_customer_orders_by_email drop wrong-tool calls to near zero. Try that before you buy a hop.

What the split actually costs

Be explicit about this before you commit, because it is rarely priced in review:

Latency. Every handoff adds at least one full model turn for the delegation decision and one for the parent to read the result. Two levels of nesting on a slow model turns a 6-second interaction into 20 seconds. Parallel subagents help wall-clock time, but only if the parent can fan out without needing intermediate results.

Tokens. Each subagent re-reads its own instructions and tool schemas on every step. A three-subagent design often triples system-prompt spend even when the subagents are idle-short. Measure cost per completed task, not cost per call.

Lost information. The subagent decides what to summarize. Whatever it drops, the parent cannot recover — it never saw the raw material. This is the failure mode teams underestimate: the parent confidently reports a conclusion built on a summary that quietly omitted the caveat.

Debuggability. One trace becomes a tree. Without per-subagent trace naming you will spend your incident time figuring out which loop produced the bad sentence.

Patterns worth using, in order of how often we reach for them

Tool-shaped subagent

The subagent is exposed to the parent as a normal tool with a narrow signature — research(question: str) -> Findings. The parent never sees the inner trajectory. This is the deep-agent pattern in its useful form, and it is where we start ninety percent of the time. It keeps routing logic in one place, keeps evals simple, and lets you replace the subagent with a plain function later if the model turns out not to be needed.

Supervisor with typed handoffs

A parent routes to one of several workers and gets structured results back. Worth it when the workers really are disjoint — different data stores, different permissions, different SLAs. Keep the routing decision a structured output, not a free-text intent; you want it assertable in tests.

Swarm / peer handoff

Agents hand control to each other without a central router. Powerful, and hard to reason about. We have not yet met a production system that needed this and could not be served by a supervisor. If you build it, cap the number of handoffs per run and log every transfer as a first-class event.

Draw three boundaries deliberately

State. Decide what is shared and what is private. In LangGraph, the clean default is: subagents get their own message list, the parent gets only the return payload, and anything both need lives in a small typed field on the shared state or in a store. Sharing the full message history between agents defeats the point of splitting.

Tools. Enforce the tool boundary in code, not in the prompt. If the researcher is not allowed to write, it should not be bound to a write tool — "do not call write_record" in a system prompt is a suggestion, and untrusted text in a retrieved document is an argument against it.

Return type. Make subagent results structured. A schema with findings, sources, confidence, and an explicit insufficient_evidence flag gives the parent something to branch on. Free-text returns push every recovery decision back into the parent's judgment, which is exactly where it is weakest.

Checkpoint and interrupt behavior

If the parent graph is checkpointed, decide what happens when a subagent is mid-flight during a crash or a human interrupt. Two defensible answers: subagent work is atomic and re-runs from scratch on resume (simple, wasteful), or subagents have their own checkpointer and thread ID (cheaper on resume, more moving parts). Pick one and write it down. The failure we see in the wild is a half-finished subagent whose side effects already landed, re-run from the top, doing them again. Idempotency keys on any tool with side effects are not optional once you nest.

Prove the split with evals, not vibes

The split is a change like any other, and it should have a measured delta. Before you refactor, freeze a set of real tasks and record, per task: final-answer score, total tokens, wall-clock latency, and tool-call count. Then run the same set against the split architecture.

What we look for:

  • Answer quality flat or up. If quality is flat and cost is up, the split failed. That is a legitimate result; we have reverted several.
  • Parent context size down materially. If the parent's peak token count is not meaningfully lower, you did not buy context isolation and you paid for hops anyway.
  • Trajectory assertions at both levels. Score the subagent's internal trajectory separately — did it call the right tools, in a sane order, within its step budget — and assert on the parent's use of the result. A subagent that returns something plausible and a parent that over-trusts it produce a confident wrong answer with a clean trace at each level.
  • A summarization-loss probe. Include tasks whose correct answer depends on a detail a lazy summary would drop. This is the single most useful eval case for any delegated architecture.

The honest default

Start with one agent and good tools. Add a tool-shaped subagent when you can name the intermediate tokens you are keeping out of the main window. Add a supervisor only when you have two or more workers with genuinely different permissions or data access. Stop there until an eval tells you otherwise.

Most of the multi-agent systems we are asked to debug would be faster, cheaper, and easier to reason about as one loop with three fewer abstractions — and a couple of them genuinely needed the split, which is why the decision is worth making on evidence rather than on what the architecture diagrams look like this month.

If you are staring at a multi-agent design and cannot tell which case you are in, that is a good hour of conversation. Tell us what your agent does and we will ask the questions we would ask in a review.