← Back to list

The Multi-Agent Pattern Nobody Talks About

Supervisor-worker, debate, and consensus patterns get all the attention. Here’s the pattern I actually use in production — a hierarchical…

Ali Imran · 2026-05-04 23:35 · 0 claps · 6.8 min read
#multi-agent-systems #ai-agent-development #llm-system-design
Open on Medium ↗
Wiki topics: LLM · Large Language Models AGT · AI Agents

The Multi-Agent Pattern Nobody Talks About

Supervisor-worker, debate, and consensus patterns get all the attention. Here’s the pattern I actually use in production — a hierarchical delegation model with typed contracts between agents. Covers why most multi-agent demos fail at scale and the specific architectural decisions that make the difference.

Why supervisor-worker fails at scale

The classic supervisor-worker pattern looks great in a demo: one agent decides, others execute. In production, the supervisor becomes a bottleneck and a single point of failure. Worse, when the supervisor’s understanding drifts mid-conversation, every worker downstream inherits the drift. You end up debugging a chain of failures with no clear root cause.

The deeper issue is that supervisor-worker conflates two distinct responsibilities: understanding what needs to happen and deciding how to sequence it. When those live in the same agent, you get a system where a subtle misread of the user’s intent silently propagates into every downstream task. You don’t find out until the final output is wrong, at which point you’re staring at five agent traces trying to figure out where the drift started.

There’s also a scaling problem that only shows up under real load. A single supervisor handling all orchestration logic creates a natural serialization point. If your supervisor is calling a frontier model for every routing decision, you’re paying full inference cost and latency on every step, even for trivial ones. The pattern that seemed clean in development becomes an expensive throughput ceiling in production.

The debate and consensus patterns have their own problems. Debate is useful for adversarial verification — you want two agents disagreeing to surface errors — but it’s computationally expensive and adds latency that most production systems can’t absorb. Consensus requires all agents to agree before proceeding, which is elegant in theory and paralyzed in practice when one agent consistently produces off-schema outputs.

What all these patterns share is an implicit assumption: that natural language is a reliable interface between agents. It isn’t. Natural language between agents is ambiguous, hard to validate, and impossible to test systematically. The fix is to stop treating inter-agent communication as a language problem and start treating it as an API design problem.

Hierarchical delegation with typed contracts

Treat the agent system like a microservice architecture. Each agent has a strict input contract and a strict output contract — typed, validated at runtime. The agent doesn’t see arbitrary natural language from upstream; it sees a structured request matching its schema. Its output is validated before it goes downstream.

This sounds boring. It is the difference between a system that survives production and one that doesn’t.

In practice, this means defining Pydantic models (or equivalent) for every inter-agent message. An agent that performs web research doesn’t receive “go research this topic for me” — it receives a ResearchRequest with fields like query: str, max_sources: int, required_domains: list[str] | None, and output_format: Literal["summary", "structured_citations"]. Its output is a ResearchResult with a typed schema that the next agent can rely on without parsing.

The immediate benefit is testability. You can unit test every agent in isolation by constructing valid input fixtures and asserting on output schema conformance — no live LLM calls required for the majority of your test suite. When an agent misbehaves in production, you replay the exact input it received and reproduce the failure deterministically.

The less obvious benefit is prompt engineering discipline. When you’re forced to define a typed output schema for an agent, you’re forced to be precise about what that agent is actually supposed to do. Ambiguity in the schema reflects ambiguity in the design. Teams that skip typed contracts tend to paper over design confusion with increasingly elaborate prompt instructions; teams that define contracts up front find the design problems earlier, when they’re cheaper to fix.

The three-layer model

  • Layer 1 — Intent: One agent owns understanding what the user wants. Output is a structured task spec.
  • Layer 2 — Plan: Decomposes the task spec into typed sub-tasks. Owns sequencing and the dependency graph.
  • Layer 3 — Execute: Specialized workers, each handling one task type. Each worker is independently testable.

Each layer can fail independently. Each layer can be swapped, tested, or replaced without touching the others.

Layer 1 in detail. The Intent agent’s sole job is to convert a potentially ambiguous user request into a machine-readable task specification. It does no planning and no execution. Its output is something like a TaskSpec — a typed object with fields for the goal, constraints, success criteria, and any explicit user preferences. If the user's request is ambiguous, this agent asks for clarification before producing a spec. Ambiguity resolution happens here, not three layers deep where it causes cascading failures.

This layer should use your strongest model. The cost is justified because this is the only place where natural language understanding is the primary challenge. Every other layer works from structured inputs.

Layer 2 in detail. The Plan agent takes a TaskSpec and produces a ExecutionPlan — an ordered list of typed SubTask objects, each with its own input contract, dependencies (which other sub-tasks must complete first), and the target worker type. This agent reasons about sequencing, parallelism opportunities, and what to do if a sub-task fails.

The dependency graph is the key artifact here. Explicitly modeling which tasks can run in parallel vs. which must be sequential unlocks real throughput gains. A naive supervisor executes everything sequentially because it doesn’t distinguish between tasks that depend on each other and tasks that just happen to come one after another. The Plan layer makes that distinction explicit and lets your execution runtime parallelize accordingly.

Layer 3 in detail. Execution workers are narrow and fast. A web search worker handles web searches. A code execution worker handles code. A data transformation worker handles transformations. Each worker receives a typed SubTask, does exactly one thing, and returns a typed SubTaskResult. No worker knows what the overall task is. No worker reasons about sequencing. They are pure functions: typed input in, typed output out.

This narrowness is a feature. A small, focused prompt for a narrow task outperforms a large, general prompt for a broad one — both in accuracy and in cost, since you can use a smaller model for execution workers once they’re well-defined enough to fine-tune on.

Validation gates between layers

Between every layer is a validator that checks the typed contract. If validation fails, the system retries with structured error feedback to the previous agent — “your output failed schema X at field Y, fix and retry.” This pattern catches 80% of the cascading-failure modes that kill naive multi-agent systems.

The implementation is straightforward: wrap every layer transition in a validation step that runs the agent’s output through its declared schema. On failure, construct a structured error message that tells the agent specifically what went wrong — not “invalid output” but “field required_domains expected list[str] | None, received str." Include the original input and the failed output in the retry prompt so the agent has full context.

Set a retry limit (two or three is usually enough) and a fallback behavior for when retries are exhausted. The fallback should be explicit and recoverable — either escalate to a human-review queue, return a typed error to the calling layer, or fall back to a simpler execution path. Silent failures are worse than loud ones.

Validation gates also give you a natural instrumentation point. Log every validation event — pass and fail — with the agent ID, layer, input hash, and timestamp. After a week of production traffic, your validation failure logs will tell you exactly which agents are unreliable, which fields are most commonly malformed, and where your prompt engineering effort should go next.

One counterintuitive finding: adding validation gates often surfaces prompt improvements that meaningfully reduce failure rates without any architectural changes. When you can see that Layer 2 consistently fails to populate the dependencies field on multi-step plans, you know exactly what to add to its prompt. The gate makes the problem visible; the fix is usually straightforward.

Why this works in production

You can independently scale each layer based on load. You can A/B test individual agents without rewriting the system. You get observability for free — every layer transition is a trace span. And most importantly, when something breaks, you know exactly which agent broke its contract.

Let me unpack the observability point because it’s more valuable than it sounds. In a typical multi-agent system, a failure produces a trail of natural language outputs from multiple agents, and debugging means reading through all of them trying to infer where the logic diverged from intent. With typed contracts and validation gates, every layer transition is a structured event with a clear pass/fail status and a machine-readable payload. You can reconstruct the full execution graph for any request from your logs, identify the exact layer where the contract was broken, and replay that layer’s input to reproduce the failure.

This transforms debugging from archaeology into root cause analysis. The mean time to identify the source of a production failure drops significantly — not because the agents make fewer mistakes, but because the architecture makes mistakes legible.

The A/B testing point is also underrated. Because each layer has a clear typed interface, you can swap the model, the prompt, or the implementation behind any layer without touching the others. Want to test whether GPT-4o outperforms Claude on the Intent layer? Swap the model, keep the schema, run both in shadow mode on production traffic, compare typed outputs. No changes to Plan or Execute. This is the same benefit microservices give you for conventional software — independent deployability — applied to AI systems.

The architectural cost is real: defining typed schemas upfront requires discipline and adds initial development time. You’ll refine the schemas as you learn more about what each layer actually needs. But the operational benefits compound quickly. Systems built this way tend to improve predictably over time rather than accumulating prompt-engineering debt that makes them increasingly fragile to touch.

The pattern in one sentence

Stop treating agent-to-agent communication as a language problem. Define contracts, validate at every boundary, and build each layer to do exactly one thing well.

Ali Imran is an AI/backend engineer working on LLM systems and production ML. More at saliimranz.github.io


메타데이터
post_id
08f17eb34f6b
slug
the-multi-agent-pattern-nobody-talks-about-08f17eb34f6b
url
https://medium.com/@saliimranz12/the-multi-agent-pattern-nobody-talks-about-08f17eb34f6b
canonical_url
https://medium.com/@saliimranz12/the-multi-agent-pattern-nobody-talks-about-08f17eb34f6b
author_url
https://medium.com/@saliimranz12
status
ok
fetched_at
2026-06-09 15:37:30