Default to a single loop: one model, a set of tools, iterate until done. In 2026 that architecture handles most production agent workloads, because current frontier models sustain long multi-step tool use without the hand-holding that motivated 2023's agent frameworks. Reach for subagents only when you need context isolation or real parallelism, for handoffs only when routing between genuinely different specialists, and for graphs when the workflow is actually known in advance — in which case you should question whether you needed an agent at all. Every layer you add costs debuggability, and debuggability is the scarcest resource in this kind of system.

The single loop is the baseline

The whole architecture fits in a screenful:

messages = [{"role": "user", "content": task}]
while True:
    resp = llm(messages, tools=TOOLS)
    if resp.stop_reason != "tool_use":
        return resp
    messages.append(assistant_turn(resp))
    messages.append(tool_results(run_tools(resp)))  # all results, one message

Its virtues are structural, not aesthetic. One context means the model has perfect memory of everything it did — no state synchronisation, no information lost at hand-off boundaries. One sequence of messages means a trace is literally readable top to bottom. When something goes wrong, you replay one conversation. Before adding anything to this, be able to name the specific failure you're fixing.

Where the loop actually breaks

Four failure modes justify more architecture, and it's worth being precise about which one you have:

  1. Context pollution. Tool outputs (500-line search results, full file contents) accumulate until the window is mostly dead weight — cost rises linearly and attention quality falls. Often fixable within the loop by pruning old tool results, per context window management, before reaching for subagents.
  2. Heterogeneous work. Paying frontier-model prices to grep files. Sometimes solved by routing instead of architecture.
  3. Real parallelism. Fifty files to review, twenty sources to check — serial tool calls make the turn take minutes.
  4. Horizon length. Tasks whose full trajectory simply exceeds any practical context budget.

Only 3 and 4 require multi-agent designs. 1 and 2 have cheaper fixes.

Pattern: orchestrator and subagents

One agent owns the task and delegates bounded subtasks to workers, each running in a fresh context and returning a summary. This buys context isolation — the orchestrator never sees the 40,000 tokens the worker burned reading files, only its 300-token conclusion — and parallel fan-out, since workers are independent.

The failure mode is always the same place: the task brief. The worker knows nothing the orchestrator doesn't tell it, and vague briefs return confident, useless summaries. Treat the brief like an API contract — objective, constraints, what to return, what not to do — and treat the summary format the same. Anthropic's engineering write-ups on building effective agents land on the same point: the boundaries, not the agents, are where these systems fail. Second-order costs to budget for: latency (a delegation round-trip per subtask), and evaluation surface — every worker type needs its own eval cases now.

Pattern: handoffs

Route the conversation itself between specialist loops — a triage agent hands a billing question to a billing agent that owns the conversation from there, with its own tools and system prompt. Different from subagents: control transfers rather than returns.

This earns its keep when specialists genuinely conflict — incompatible tool sets, different safety postures, prompts that would contradict each other if merged. That's a support-desk shape. If your "specialists" share 80% of their prompt and tools, you've built one agent with extra steps; merge them and route with a cheap classifier at the door instead.

Pattern: graphs and workflows

If you can draw the steps on a whiteboard — fetch, extract, validate, write — build a pipeline with LLM calls at the nodes, not an agent. Fixed control flow is cheaper (each node uses the smallest capable model), testable node-by-node, and immune to the model deciding to skip a step. The industry keeps relearning the rule: an agent is what you use when you can't write the workflow down. Frameworks that turn known five-step processes into "agent graphs" add configuration without adding capability; the graph you can't test is worse than the function you can.

The comparison

ArchitectureReaches forMain failure modeDebuggability
Single loopMost tasksContext bloat on long runsExcellent — one readable trace
Loop + subagentsParallelism, context isolationInformation lost in briefs/summariesModerate — N traces to correlate
HandoffsConflicting specialistsMis-routing, context lost at transferModerate
Workflow graphKnown step sequencesRigidity when inputs varyExcellent — unit-testable nodes

The complexity tax is multiplicative, not additive: each agent type multiplies your tracing needs, retry semantics, and eval surface. A two-day multi-agent bug hunt is usually a one-hour single-loop bug hunt with worse logging.

What I'd build today

Climb the ladder in order and stop at the first rung that works: single LLM call → workflow with LLM nodes → single loop with well-designed tools → loop plus subagents for the parallel or context-heavy parts. Skip the agent framework until you've outgrown the 40-line loop — most teams never do, and the ones that do then know exactly which primitives they need. Spend the saved complexity budget on the things that actually determine agent quality in production: tool design, tracing, and evals.