InterviewKata
AI engineering · Module 07a · Level 2: Working with AI

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.

A 4-minute conversation: Sam asks, Priya explains
0:00 / 3:43

1. The idea

A hospital. The triage desk sends you to the right department (router). The doctor writes a care plan, then follows it, changing it when test results come back (plan-and-execute). An attending physician calls in specialists and reviews what each finds (supervisor). Sometimes you're referred, and the next doctor takes over your case (handoff). And before surgery, someone must sign the consent form (human gate).
ArchitectureHow it worksFits whenMain risk
Single agentOne model in a loop with tools (Module 07)Most tasks; always the baselineContext fills on very long tasks
RouterA cheap classifier sends each request to one specialist agent or modelRequests fall into clear categories with different tools or promptsA wrong route, with no second chance
Plan-and-executeA planner writes the steps; an executor runs them, observes and replansMulti-step tasks whose steps can be listed up frontA stale plan when the world changes mid-run
SupervisorA lead agent splits the work, delegates to sub-agents, reviews and mergesIndependent parts that can run in parallelTokens (about 15× a chat) and mismatched parts
Handoffs (swarm)The active agent passes control, and the conversation, to anotherA user talks to one specialist at a timeContext lost or bloated at each handoff
Human gateThe run pauses before a risky action until a person approvesIrreversible, costly or accountable actionsApproval 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 userOnly the supervisorWhichever agent is active
ControlReturns to the supervisor after each sub-taskMoves to the next agent and stays there
Parallel workYes: several sub-agents at onceNo: one agent at a time
ContextSub-agents get a brief, return a summaryThe conversation moves with control, filtered or whole
Good forResearch, reviews, multi-part jobsCustomer 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

    SituationArchitectureEvidence
    Broad research with many independent leadsSupervisor with parallel sub-agentsAnthropic'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 codebaseSingle agent, with compression for long runsCognition's Flappy Bird example: sub-agents built parts on conflicting assumptions (C12)
    A business workflow with known stages and accountable decisionsPlan-and-execute under a supervisor, with human approvalsLinkedIn chose plan-and-execute because "ReAct alone is not sufficient for an enterprise-grade agent" (C13)
    Actions that can destroy data or moneyHuman gates, plus environments the agent can't reachReplit's agent deleted a production database during a code freeze (C05)
    Support across a few clear topicsRouter, or handoffs when the user talks to each specialistEach 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.

    FrameworkSupervisorHandoffsPlan-and-execute and workflowsHuman gate
    LangGraph (LangChain)Subagents as tools of a main agentHandoffs that switch the active agentCustom graphs mixing fixed steps and agents; router patterninterrupt() pauses the graph until resumed
    OpenAI Agents SDKAgents used as toolshandoff(), exposed to the model as a tool, with filters on the history passedYour code around the runnerA 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 orchestrationHandoff orchestrationSequential and concurrent workflows with checkpointingWorkflows pause and resume from checkpoints
    CrewAIHierarchical process: a manager plans, assigns and reviews–Sequential processHuman input on tasks
    Google ADKCollaborative workflows: one coordinator over sub-agentsAgent routing (experimental)Sequential, parallel and loop workflows; graph workflowsHuman input nodes in graph workflows

    6. Remember it

    Memory hook: "Triage, plan, specialists, referral, consent"Router, plan-and-execute, supervisor, handoff, human gate. Start with one doctor; add the rest only when the case needs them.
    How this hook works: what “Triage, plan, specialists, referral, consent” means

    The story → the concept

    HospitalAgents
    Triage deskRouter
    Care plan, revised after test resultsPlan-and-execute with replanning
    Attending physician calling specialistsSupervisor and sub-agents
    Referral to another doctorHandoff
    Consent form before surgeryHuman 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

    Starting multi-agentMore agents multiply tokens and failure points. Measure a single agent first; add structure for a specific, observed problem.
    A plan nobody revisitsPlans go stale. Replan when a step's result contradicts what the plan assumed.
    Splitting coupled work across a supervisorSub-agents make conflicting decisions they can't see. Split only independent parts, with full briefs.
    Gating everythingPeople approve without reading. Gate what's irreversible, costly or accountable; let the rest run, logged.
    A gate in the prompt"Ask before deleting" is a suggestion to the model. Enforce the gate in code: the tool itself pauses for approval.
    Handoffs that drop contextDecide what history moves with control; a specialist that can't see why it was called asks the user again.

    8. Hands-on lab (roadmap week 7)

    1. Baseline: build a single agent with three tools for a small support desk. Record success on 20 test requests.
    2. Router: add a router in front with two specialists. Did accuracy or cost change?
    3. 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.
    4. Gate: put an approval gate inside the refund tool (not the prompt). Try to talk the agent past it.
    5. 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?

    Clear categories with different tools: classify once, send to one specialist.

    Why did LinkedIn choose plan-and-execute for Hiring Assistant?

    An explicit plan makes the planner think through all steps; the executor then runs them, with recruiters approving decisions they own.

    Where should an approval gate for refunds live?

    A prompt instruction can be ignored or talked around; a tool that pauses for approval can't.

    A customer should talk to a billing specialist, then be passed to a technical specialist who continues the conversation. Which pattern?

    Control and the conversation move to the next agent, which talks to the user directly.

    What should you build first for a new agent feature?

    It's the baseline every other architecture must beat, at lower cost and with fewer failure points.

    10. Go deeper

    ResourceTimeWhy
    How we engineered LinkedIn's Hiring Assistant (LinkedIn, October 2025)20 minPlan-and-execute with a supervisor and sub-agents, and humans approving decisions.
    How we built our multi-agent research system (Anthropic, June 2025)20 minA supervisor in production: gains, costs and delegation lessons.
    Don't build multi-agents (Cognition, June 2025)10 minThe case for a single agent on coupled work.
    Multi-agent patterns and human-in-the-loop (LangChain docs)20 minSubagents, handoffs, router and custom workflows; interrupt().
    Handoffs (OpenAI Agents SDK)10 minHandoffs as tools, with history filters.
    Microsoft Agent Framework 1.0 (Microsoft, April 2026)10 minThe successor to Semantic Kernel and AutoGen, and its orchestration patterns.
    CrewAI processes and ADK workflows10 minHierarchical managers; sequential, parallel, loop and graph workflows.