Agent architectures: router, plan-and-execute, supervisor, handoffs and human gates
Module 07 showed the agent loop and five simple workflow patterns. Production agents are usually built from a handful of larger shapes: a router that sends each request to a specialist, a planner that writes the steps before acting, a supervisor that delegates to sub-agents, handoffs that pass the conversation between agents, and human gates before anything risky. This module explains each one, when it fits, what it costs, and how the main frameworks implement it, with a demo you can run and real systems that chose each shape.
- Sam Router, planner, supervisor, swarm. Do I need all of these?
- Priya Almost never all at once. They're shapes you add to a single agent when a measured problem calls for one. Start with one agent and good tools; that's the baseline everything else has to beat.
- Priya Think of a hospital. The triage desk sends you to the right department: that's a router. The doctor writes a care plan and revises it when test results come back: plan-and-execute. An attending physician calls in specialists and reviews what each finds: a supervisor. A referral, where the next doctor takes over your case: a handoff. And the consent form before surgery: a human gate.
- Sam And what goes wrong with each?
- Priya A router can send a request to the wrong place with no second chance. A plan goes stale if nobody revises it. A supervisor costs tokens, about fifteen times a chat in Anthropic's research system, and its sub-agents can build mismatched parts. Handoffs can lose context. And if you gate everything, people approve without reading.
- Sam Walk me through a real flow.
- Priya A support desk. The router sends a crash report to the tech agent. A refund goes to the billing agent, which writes its whole plan first: look up the order, check the policy, refund, email. A two hundred and fifty dollar refund hits the human gate: the refund tool pauses, the run is saved, and it resumes once a person approves. And a forty-five-day-old order fails the policy check, so the agent replans and offers store credit instead.
- Sam Supervisor or handoffs?
- Priya With a supervisor, only the lead talks to the user and control comes back after each sub-task, so parts can run in parallel. With handoffs, control and the conversation move to the next agent, which talks to the user directly. Research and reviews suit a supervisor; customer service suits handoffs.
- Priya The chooser asks five questions: can the steps be listed up front, are there clear categories, does the work split into independent parts, does the user talk to specialists, and are there irreversible actions. The gate exercise asks which actions should run, need approval, or never happen.
- Priya Your turn. Should an agent ever be able to drop a production table?
- Priya No. It shouldn't even hold credentials that can. That's the Replit lesson.
- Sam When do real teams pick each one?
- Priya Anthropic used a supervisor with parallel sub-agents for broad research and beat a single agent by ninety percent. Cognition argues for a single agent on coupled work like a feature in a codebase. And LinkedIn's Hiring Assistant runs plan-and-execute under a supervisor, because, in their words, ReAct alone is not sufficient for an enterprise-grade agent, with recruiters approving the decisions they're accountable for.
- Priya LangGraph has subagents, handoffs and interrupts for approvals. The OpenAI Agents SDK has handoffs as tools. Microsoft Agent Framework, the successor to Semantic Kernel and AutoGen, reached version one in April twenty twenty-six. CrewAI has a hierarchical process with a manager, and Google's ADK has sequential, parallel and loop workflows.
- Priya Triage, plan, specialists, referral, consent. And start with one doctor.
- Priya Starting multi-agent. A plan nobody revisits. Splitting coupled work across a supervisor. Gating everything. A gate written only in the prompt. And handoffs that drop context.
- Priya Build one agent for a small support desk, then add a router, then plan-and-execute, then a gate inside the refund tool, and measure each step on twenty real requests.
1. The idea
| Architecture | How it works | Fits when | Main risk |
|---|---|---|---|
| Single agent | One model in a loop with tools (Module 07) | Most tasks; always the baseline | Context fills on very long tasks |
| Router | A cheap classifier sends each request to one specialist agent or model | Requests fall into clear categories with different tools or prompts | A wrong route, with no second chance |
| Plan-and-execute | A planner writes the steps; an executor runs them, observes and replans | Multi-step tasks whose steps can be listed up front | A stale plan when the world changes mid-run |
| Supervisor | A lead agent splits the work, delegates to sub-agents, reviews and merges | Independent parts that can run in parallel | Tokens (about 15× a chat) and mismatched parts |
| Handoffs (swarm) | The active agent passes control, and the conversation, to another | A user talks to one specialist at a time | Context lost or bloated at each handoff |
| Human gate | The run pauses before a risky action until a person approves | Irreversible, costly or accountable actions | Approval fatigue if everything is gated |
They combine. LinkedIn's Hiring Assistant is a supervisor that plans and executes, with humans approving the decisions recruiters are accountable for (Case C13). Start with one agent and add structure only where a measured problem needs it.
2. How it works
One support system, four requests. The router picks a specialist; the billing agent plans, executes, replans when the policy check fails, and pauses at a human gate for a large refund.
Supervisor or handoffs?
| Supervisor (subagents) | Handoffs | |
|---|---|---|
| Who talks to the user | Only the supervisor | Whichever agent is active |
| Control | Returns to the supervisor after each sub-task | Moves to the next agent and stays there |
| Parallel work | Yes: several sub-agents at once | No: one agent at a time |
| Context | Sub-agents get a brief, return a summary | The conversation moves with control, filtered or whole |
| Good for | Research, reviews, multi-part jobs | Customer service, triage, guided flows |
3. Try it yourself
Choose an architecture
Where does the human gate go?
For each action an agent can take, choose: let it run, gate it behind approval, or never let the agent do it.
4. Why it matters at work
When to use which, from real systems
| Situation | Architecture | Evidence |
|---|---|---|
| Broad research with many independent leads | Supervisor with parallel sub-agents | Anthropic's research system beat a single agent by 90.2% on its internal eval, using about 15× the tokens of a chat (C11) |
| One coupled piece of work, such as a feature in a codebase | Single agent, with compression for long runs | Cognition's Flappy Bird example: sub-agents built parts on conflicting assumptions (C12) |
| A business workflow with known stages and accountable decisions | Plan-and-execute under a supervisor, with human approvals | LinkedIn chose plan-and-execute because "ReAct alone is not sufficient for an enterprise-grade agent" (C13) |
| Actions that can destroy data or money | Human gates, plus environments the agent can't reach | Replit's agent deleted a production database during a code freeze (C05) |
| Support across a few clear topics | Router, or handoffs when the user talks to each specialist | Each specialist gets a short prompt and only its own tools, which keeps cost and confusion down |
For both decisions together, rigor and architecture, see Module 20a: When to use which.
The support system in code
A router, a plan-execute-replan loop and an approval gate, in about 50 lines. The refund over $100 pauses for a human; the 45-day-old order fails the policy check and the plan is rewritten to offer store credit. The program was run in all three languages; each prints the output below it.
ORDERS = {"81": (40, 10), "92": (250, 5), "77": (60, 45)} # order id -> (amount in dollars, days since purchase)
APPROVAL_LIMIT = 100 # refunds above this need a human
REFUND_WINDOW = 30 # days
def route(message):
"""Router: send each request to one specialist. A small, cheap model does this in practice; keywords stand in here."""
text = message.lower()
if "refund" in text or "charge" in text:
return "billing"
if "crash" in text or "error" in text:
return "tech"
return "general"
def plan(order_id):
"""Planner: write the whole plan up front, before acting."""
return ["look up order", "check refund policy", "issue refund", "email customer"]
def execute(order_id, approve):
amount, days = ORDERS[order_id]
steps, log = plan(order_id), []
while steps:
step = steps.pop(0)
if step == "check refund policy" and days > REFUND_WINDOW:
log.append(f"{step}: {days} days, outside the {REFUND_WINDOW}-day window -> replan")
steps = ["offer store credit", "email customer"] # replan from what was observed
continue
if step == "issue refund" and amount > APPROVAL_LIMIT:
decision = approve(order_id, amount) # human gate: execution pauses here
log.append(f"{step}: ${amount} needs approval -> {decision}")
if decision != "approved":
steps = ["email customer"]
continue
log.append(step)
return log
def human(order_id, amount):
return "approved" # in a real system the run waits, saved, until a person decides
requests = ["The app crashes when I log in", "Please refund order 81", "Please refund order 92", "Please refund order 77"]
for message in requests:
agent = route(message)
print(f'"{message}" -> {agent} agent')
if agent == "billing":
for line in execute(message.split()[-1], human):
print(" ", line)
const ORDERS: Record<string, [number, number]> = { "81": [40, 10], "92": [250, 5], "77": [60, 45] }; // order id -> [amount in dollars, days since purchase]
const APPROVAL_LIMIT = 100; // refunds above this need a human
const REFUND_WINDOW = 30; // days
// Router: send each request to one specialist. A small, cheap model does this in practice; keywords stand in here.
function route(message: string): string {
const text = message.toLowerCase();
if (text.includes("refund") || text.includes("charge")) return "billing";
if (text.includes("crash") || text.includes("error")) return "tech";
return "general";
}
// Planner: write the whole plan up front, before acting.
function plan(orderId: string): string[] {
return ["look up order", "check refund policy", "issue refund", "email customer"];
}
function execute(orderId: string, approve: (id: string, amount: number) => string): string[] {
const [amount, days] = ORDERS[orderId];
let steps = plan(orderId);
const log: string[] = [];
while (steps.length) {
const step = steps.shift()!;
if (step === "check refund policy" && days > REFUND_WINDOW) {
log.push(`${step}: ${days} days, outside the ${REFUND_WINDOW}-day window -> replan`);
steps = ["offer store credit", "email customer"]; // replan from what was observed
continue;
}
if (step === "issue refund" && amount > APPROVAL_LIMIT) {
const decision = approve(orderId, amount); // human gate: execution pauses here
log.push(`${step}: $${amount} needs approval -> ${decision}`);
if (decision !== "approved") steps = ["email customer"];
continue;
}
log.push(step);
}
return log;
}
const human = (orderId: string, amount: number) => "approved"; // in a real system the run waits, saved, until a person decides
const requests = ["The app crashes when I log in", "Please refund order 81", "Please refund order 92", "Please refund order 77"];
for (const message of requests) {
const agent = route(message);
console.log(`"${message}" -> ${agent} agent`);
if (agent === "billing") {
const words = message.split(" ");
for (const line of execute(words[words.length - 1], human)) console.log(" ", line);
}
}import java.util.*;
import java.util.function.BiFunction;
public class Main {
static final Map<String, int[]> ORDERS = Map.of("81", new int[] {40, 10}, "92", new int[] {250, 5}, "77", new int[] {60, 45}); // order id -> {amount in dollars, days since purchase}
static final int APPROVAL_LIMIT = 100; // refunds above this need a human
static final int REFUND_WINDOW = 30; // days
// Router: send each request to one specialist. A small, cheap model does this in practice; keywords stand in here.
static String route(String message) {
String text = message.toLowerCase();
if (text.contains("refund") || text.contains("charge")) return "billing";
if (text.contains("crash") || text.contains("error")) return "tech";
return "general";
}
// Planner: write the whole plan up front, before acting.
static Deque<String> plan(String orderId) {
return new ArrayDeque<>(List.of("look up order", "check refund policy", "issue refund", "email customer"));
}
static List<String> execute(String orderId, BiFunction<String, Integer, String> approve) {
int amount = ORDERS.get(orderId)[0], days = ORDERS.get(orderId)[1];
Deque<String> steps = plan(orderId);
List<String> log = new ArrayList<>();
while (!steps.isEmpty()) {
String step = steps.poll();
if (step.equals("check refund policy") && days > REFUND_WINDOW) {
log.add(step + ": " + days + " days, outside the " + REFUND_WINDOW + "-day window -> replan");
steps = new ArrayDeque<>(List.of("offer store credit", "email customer")); // replan from what was observed
continue;
}
if (step.equals("issue refund") && amount > APPROVAL_LIMIT) {
String decision = approve.apply(orderId, amount); // human gate: execution pauses here
log.add(step + ": $" + amount + " needs approval -> " + decision);
if (!decision.equals("approved")) steps = new ArrayDeque<>(List.of("email customer"));
continue;
}
log.add(step);
}
return log;
}
public static void main(String[] args) {
BiFunction<String, Integer, String> human = (id, amount) -> "approved"; // in a real system the run waits, saved, until a person decides
for (String message : List.of("The app crashes when I log in", "Please refund order 81", "Please refund order 92", "Please refund order 77")) {
String agent = route(message);
System.out.println("\"" + message + "\" -> " + agent + " agent");
if (agent.equals("billing")) {
String[] words = message.split(" ");
for (String line : execute(words[words.length - 1], human)) System.out.println(" " + line);
}
}
}
}"The app crashes when I log in" -> tech agent
"Please refund order 81" -> billing agent
look up order
check refund policy
issue refund
email customer
"Please refund order 92" -> billing agent
look up order
check refund policy
issue refund: $250 needs approval -> approved
email customer
"Please refund order 77" -> billing agent
look up order
check refund policy: 45 days, outside the 30-day window -> replan
offer store credit
email customer
In a real system the gate saves the run's state and stops; a person approves in a dashboard or chat, and the run resumes from the saved point, possibly days later. That's what LangGraph's interrupt() and the workflow checkpointing in Microsoft Agent Framework provide.
5. In the frameworks
Frameworks rename things often; the shapes stay the same. Checked 4 November 2026.
| Framework | Supervisor | Handoffs | Plan-and-execute and workflows | Human gate |
|---|---|---|---|---|
| LangGraph (LangChain) | Subagents as tools of a main agent | Handoffs that switch the active agent | Custom graphs mixing fixed steps and agents; router pattern | interrupt() pauses the graph until resumed |
| OpenAI Agents SDK | Agents used as tools | handoff(), exposed to the model as a tool, with filters on the history passed | Your code around the runner | A human-in-the-loop guide in the SDK docs |
| Microsoft Agent Framework (successor to Semantic Kernel and AutoGen; 1.0 in April 2026) | Group chat and Magentic orchestration | Handoff orchestration | Sequential and concurrent workflows with checkpointing | Workflows pause and resume from checkpoints |
| CrewAI | Hierarchical process: a manager plans, assigns and reviews | – | Sequential process | Human input on tasks |
| Google ADK | Collaborative workflows: one coordinator over sub-agents | Agent routing (experimental) | Sequential, parallel and loop workflows; graph workflows | Human input nodes in graph workflows |
6. Remember it
How this hook works: what “Triage, plan, specialists, referral, consent” means
The story → the concept
| Hospital | Agents |
|---|---|
| Triage desk | Router |
| Care plan, revised after test results | Plan-and-execute with replanning |
| Attending physician calling specialists | Supervisor and sub-agents |
| Referral to another doctor | Handoff |
| Consent form before surgery | Human approval gate |
The trap it saves you from
Building the whole hospital for a sore throat: five agents and a framework where one agent with good tools would do.
7. Common mistakes
8. Hands-on lab (roadmap week 7)
- Baseline: build a single agent with three tools for a small support desk. Record success on 20 test requests.
- Router: add a router in front with two specialists. Did accuracy or cost change?
- Plan-and-execute: for a five-step task, have the agent write the plan first and replan when a step fails. Compare with the plain loop.
- Gate: put an approval gate inside the refund tool (not the prompt). Try to talk the agent past it.
- Write the rule: one paragraph for your team on which architecture to start with, and what evidence justifies adding the next.
9. Self-check quiz
Requests fall into billing, technical and account questions, each needing different tools. Which architecture is the lightest fit?
Why did LinkedIn choose plan-and-execute for Hiring Assistant?
Where should an approval gate for refunds live?
A customer should talk to a billing specialist, then be passed to a technical specialist who continues the conversation. Which pattern?
What should you build first for a new agent feature?
10. Go deeper
| Resource | Time | Why |
|---|---|---|
| How we engineered LinkedIn's Hiring Assistant (LinkedIn, October 2025) | 20 min | Plan-and-execute with a supervisor and sub-agents, and humans approving decisions. |
| How we built our multi-agent research system (Anthropic, June 2025) | 20 min | A supervisor in production: gains, costs and delegation lessons. |
| Don't build multi-agents (Cognition, June 2025) | 10 min | The case for a single agent on coupled work. |
| Multi-agent patterns and human-in-the-loop (LangChain docs) | 20 min | Subagents, handoffs, router and custom workflows; interrupt(). |
| Handoffs (OpenAI Agents SDK) | 10 min | Handoffs as tools, with history filters. |
| Microsoft Agent Framework 1.0 (Microsoft, April 2026) | 10 min | The successor to Semantic Kernel and AutoGen, and its orchestration patterns. |
| CrewAI processes and ADK workflows | 10 min | Hierarchical managers; sequential, parallel, loop and graph workflows. |