AI Design Patterns

Core AI Design Patterns Every Team Uses

Router, ReAct, Planner–Executor, and Reflection patterns explained with when to use each, when not to, and a small implementation sketch for production.

EnhanceLearning.AIArchitect & Researcher
May 24, 20267 min read
AI Design PatternsReActOrchestration
Core AI Design Patterns Every Team Uses — cover illustration | EnhanceLearning.AI

Teams rediscover the same four shapes under new product names. Naming them saves design time: Router, ReAct, Planner–Executor, and Reflection cover most production LLM control flow. The skill is not memorizing the labels. It is knowing which pattern fits the job before you invent a fifth agent.

Pattern map#

PatternControl ideaUse whenAvoid when
RouterClassify, then dispatchClear categories, cheap decisionCategories blur; need multi-step repair
ReActInterleave thought and tool useExploratory lookup with short hopsLong plans need an explicit schedule
Planner–ExecutorPlan first, then run stepsMulti-step jobs with reviewable plansSingle tool call would suffice
ReflectionCritique and reviseHigh-stakes drafts, grounding checksLatency budget cannot afford a second pass

Four AI control patterns: Router, ReAct loop, Planner–Executor, Reflection critique pass | EnhanceLearning.AI

Router#

A router is a small model call (or rules + model) that picks a destination: FAQ bot, billing tools, human queue. Keep the router dumb and the destinations strong. The failure mode is a confident misroute; mitigate with an "unsure → clarify or default safe path" class.

Code
type Route = "billing" | "tech" | "human";

async function route(message: string, llm: LLM): Promise<Route> {
  const out = await llm.classify(message, {
    labels: ["billing", "tech", "human"],
    instruction: "If unsure, choose human.",
  });
  return out.label as Route;
}

Routers shine behind support portals and multi-skill assistants. They are a poor fit when the next step depends on what the first tool returns — that is ReAct or Planner–Executor territory.

ReAct (reason + act)#

ReAct interleaves a short rationale with tool calls until the model emits a final answer. It is the default for "look something up, then maybe look again." Keep the trail short; force a stop when tools fail twice the same way.

The production version of ReAct is less about the chain-of-thought prose and more about the observe step: tool results must be appended as data the next decision can see. If you discard tool errors, the loop hallucinates success.

Planner–Executor#

Here the model (or a cheaper planner) proposes a step list, optionally gets approval, then an executor runs tools without re-planning every token. Plans are artifacts you can show a human and diff in evals.

Code
plan = planner.make_plan(goal)          # list[{"id","action","args"}]
validate_plan(plan)                     # schema + policy
for step in plan.steps:
    result = executor.run(step)
    if not result.ok:
        plan = planner.repair(plan, step, result)  # bounded repairs only
        validate_plan(plan)

Use Planner–Executor when steps are numerous or costly enough that "winging it" with ReAct wastes money. Skip it for one-shot extraction.

Reflection (critic) pass#

Reflection is a second call that only checks: unsupported claims, schema drift, policy breaches. It should return structured findings, not a friendlier rewrite — unless your product explicitly wants rewrite.

Pattern composition

Real systems compose these. A Router sends billing intents to a ReAct tool loop; high-value replies get a Reflection pass before send. Composition is fine. Spaghetti — router inside critic inside planner with no budgets — is how latency and cost become inexplicable.

Anti-patterns that look clever#

  • God router — dozens of micro-destinations with overlapping labels; misroute rate explodes
  • Unbounded ReAct — no repeated-failure detector; the loop burns budget on the same broken tool
  • Plan forever — planner rewrites the whole plan after every minor tool glitch
  • Reflective soup — three critique agents debating tone while the schema is invalid

Instrumentation per pattern#

Routers need confusion matrices on live traffic (predicted route vs human correction). ReAct needs tool-error histograms and duplicate-call rates. Planner–Executor needs plan stability (how often repairs fire) and step success. Reflection needs disagreement rate between critic and final publish, plus false-positive blocks that hurt UX. If you cannot graph those, you are flying on anecdotes.

Choosing quickly in a design review#

  1. Is the next step known from the user message alone? → Router or single call
  2. Does each step depend on live tool output? → ReAct
  3. Do you need a reviewable multi-step schedule? → Planner–Executor
  4. Is wrong output worse than extra latency? → add Reflection

If you need all four on day one, your scope is too wide. Ship the thinnest pattern that passes the eval set for the job class you actually have.

A note on "multi-agent" as a pattern#

Multi-agent is not a fifth control primitive so much as a deployment topology for the patterns above: an orchestrator may use Planner–Executor while workers use ReAct under tighter allowlists. Keep the pattern vocabulary for control flow; use "multi-agent" when you are talking about isolation and permissions. Mixing the terms is how design docs become unreadable.

Budget and stop conditions per pattern#

Every pattern needs explicit ceilings or it will eat your margin:

PatternBudget knobsStop when
RouterMax tokens on classify callConfidence below threshold → safe default
ReActMax tool hops, max duplicate tool signatureSame tool fails twice with same args
Planner–ExecutorMax plan length, max repair iterationsRepair loop exceeds N or plan invalidates
ReflectionSingle pass by default; rewrite only if flaggedCritic returns zero blocking findings

Encode stops in the runtime, not in prompt prose. "Please stop after five tools" is a suggestion. A counter in the orchestrator is a contract.

When patterns compose, budgets compose too. A Router → ReAct → Reflection chain can silently triple latency if each layer has its own generous default. Set a global step budget for the user-visible request and allocate slices per layer in config.

From prototype to production handoff#

Notebooks hide the boring parts: schema validation, idempotency, logging, and what happens when the router mislabels a billing message as tech support. Before you call a pattern "shipped," require:

  • Structured outputs at every handoff — JSON schemas, not markdown essays between components
  • Trajectory logging — which pattern fired, which tools, which repair loops
  • Fallback paths — misroute → human queue; plan invalid → clarify; critic block → safe template
  • Eval coverage per pattern edge — misroutes, tool failures, policy violations

The pattern name belongs in your observability tags. When on-call sees a spike in planner_repair events, they should know which workflow to open — not guess from a generic "agent_error" metric.

One more discipline worth enforcing in design review: name the failure owner. Routers fail open or closed — pick one per surface and test it. ReAct failures are usually tool or retrieval bugs. Planner failures are schema or policy bugs. Reflection failures are false positives blocking good answers or false negatives shipping bad ones. If you cannot say which team owns each failure mode, the composition is too tangled to ship.

Record the chosen pattern in the service runbook header. When a latency spike hits overnight, that one line tells on-call which control path to inspect.

Summary#

Router, ReAct, Planner–Executor, and Reflection are the workhorses of AI control design. Pick by dependency structure and risk, not by novelty. Implement budgets and schemas first; the pattern name is just how you explain the graph to the next engineer on-call.

Share
Premium blueprints

Want premium architecture blueprints?

Be among the first to explore interactive reference architectures, implementation playbooks, and premium engineering resources at launch.

Related Articles

Recommended reading based on this topic.

AI Design Patterns

Why AI Design Patterns Are Essential for AI-Native Engineering

Why pattern literacy is a core competency for AI-native systems: shared control shapes, repeatable behaviour, and governance that survives team handoffs.

Read Article
AI Design Patterns

How AI Design Patterns Evolve as LLM Capabilities Improve

Which AI design patterns persist, simplify, or fade as LLMs improve—and how to design control shapes that survive capability jumps without endless rewrites.

Read Article
Agentic AI

Why Most AI Agents Are Workflows in Disguise

Tell true agentic reasoning from deterministic orchestration in disguise — and assess whether your system chooses next steps or follows scripts.

Read Article