Diagram showing the four core AI agent design patterns of reflection, tool use, planning, and multi-agent systems
AI Agents
Intermediate
16 min read Updated

The 4 Core AI Agent Design Patterns Explained: Reflection, Tool Use, Planning & Multi-Agent

Master the 4 core AI agent design patterns: Reflection, Tool Use, Planning, and Multi-Agent Collaboration. Learn architectures, Python code, and trade-offs.

ai-agents design-patterns reflection planning tool-use

The transition from zero-shot prompting to agentic architectures represents the biggest architectural shift in modern artificial intelligence engineering. Having ai agent design patterns explained clearly allows software engineers to move past fragile single-turn prompts and build autonomous systems that iteratively solve complex, multi-step engineering challenges.

Rather than waiting for larger foundation models to fix reasoning errors, engineering teams wrap models in structured execution loops. When architecting autonomous AI agent workflows, four core architectural patterns dictate system reliability: Reflection, Tool Use, Planning, and Multi-Agent Collaboration.

Key Takeaways:

  • The 4 core AI agent design patterns categorized by Andrew Ng and Anthropic are Reflection, Tool Use, Planning, and Multi-Agent Collaboration.
  • Reflection implements an Evaluator-Optimizer feedback loop, evaluating generated outputs against unit tests or rubrics to self-correct before user delivery.
  • Tool Use bridges language models to deterministic calculators, databases, and APIs via standardized specifications like the Model Context Protocol (MCP).
  • Production engineering requires choosing deterministic workflows (chaining, routing) over unconstrained autonomous loops unless dynamic open-ended reasoning is mandatory.

Grid diagram detailing the four core agent design patterns of reflection, tool use, planning, and multi-agent collaboration Figure 1: The 4 Core AI Agent Design Patterns, highlighting the distinct mechanisms of self-reflection, API tool integration, task decomposition, and multi-agent squads.

The Agentic Shift: Beyond Single-Pass Prompting

Traditional interactions with language models follow a zero-shot paradigm: a user submits a prompt, the model samples tokens in a single forward pass, and the interaction terminates. While effective for simple summarization, zero-shot inference collapses when tasks require multi-step logic, code compilation, or live data verification.

If a model makes a minor reasoning error at step two of a ten-step derivation, zero-shot prompting has no mechanism to recover. The error cascades down the generation sequence, producing a confidently hallucinated conclusion. Agentic design patterns introduce execution wrappers that grant the model time to think, verify, and adapt.

Why Zero-Shot Generation Encounters a Hard Ceiling

Language models generate text autoregressively, predicting the next most probable token based on preceding tokens. Because generation occurs without backtracking, the model cannot pause mid-stream, realize an earlier assumption was false, and rewrite the opening paragraph.

Human engineers do not write production software in a single unedited keystroke stream. We write an initial draft, execute unit tests, inspect error traces, and refine the implementation. Agentic architectures replicate this iterative engineering discipline in software.

Andrew Ng’s 4 Design Patterns Framework

AI pioneer Andrew Ng popularized the classification of agentic capabilities into four distinct, composable design patterns:

  1. Reflection: The agent inspects its own generated output, identifies logic flaws or syntax errors, and iteratively refines the result.
  2. Tool Use: The model invokes external calculators, compilers, databases, and web search engines to gather ground truth.
  3. Planning: The agent decomposes a sprawling objective into a structured sequence of sub-tasks and dynamically updates the plan when steps fail.
  4. Multi-Agent Collaboration: The architecture divides work among specialized agent personas (such as a researcher, coder, and tester) that converse and critique each other.

Empirical evaluations by DeepLearning.AI and frontier research labs demonstrate that wrapping an older model in reflection and planning design patterns improves benchmark coding accuracy by up to 45%, frequently outperforming raw zero-shot frontier models.

How Dynamic Feedback Outperforms Next-Generation Foundation Models

A common misconception among software leaders is that upgrading to the latest multi-trillion parameter model will automatically eliminate hallucinations. Production data contradicts this assumption.

In standardized evaluations across enterprise code generation, reflection loops deliver a 37% reduction in runtime syntax errors, while planning decomposition cuts token waste by 42% on multi-hop benchmarks. A smaller, faster 8B parameter model wrapped in an automated reflection and tool-use loop consistently beats an unconstrained frontier model operating in single-shot mode. Production telemetry confirms that designing reliable software around the model matters far more than raw parameter scale.

Pattern 1: Reflection (Self-Correction and Evaluator-Optimizer Loops)

The reflection pattern is the simplest and most effective starting point for improving output quality. Instead of delivering the model’s first generation directly to the end user, reflection passes the draft through an automated critique stage.

This architecture is often referred to as the Evaluator-Optimizer pattern. It transforms language generation into a closed feedback loop that catches formatting mistakes, edge-case bugs, and logical inconsistencies.

The Producer-Critic Execution Cycle

Reflection functions through two cooperative roles: a Generator (Producer) and an Evaluator (Critic). These roles can be fulfilled by two separate system prompts within the same model, or by two distinct models with different specialized capabilities.

The cycle operates across three distinct phases:

  1. Draft Generation: The Generator produces an initial candidate response or code block based on the user prompt.
  2. Structured Evaluation: The Critic inspects the draft against explicit evaluation criteria, checking for unit test coverage, security vulnerabilities, or factual alignment.
  3. Iterative Refinement: If the Critic flags deficiencies, it provides verbal feedback back to the Generator, which produces an improved second draft.

Reflexion and Verbal Reinforcement Learning

Pioneered in the landmark Shinn et al. Reflexion Paper on arXiv, Reflexion equips agents with dynamic episodic memory through linguistic feedback. Rather than updating neural weights mathematically, the agent learns through verbal trial-and-error.

When an agent attempts a task (such as running a Python script) and encounters a runtime exception, Reflexion does not simply retry the exact same prompt. It writes a self-reflective analysis into its short-term memory buffer explaining why the attempt failed. On the subsequent attempt, the model consults this reflection, avoiding the previous pitfall and converging on a working solution.

from typing import List
from pydantic import BaseModel, Field

class EvaluationResult(BaseModel):
    is_valid: bool
    critique_feedback: str = Field(description="Actionable critique identifying bugs or edge-case gaps")

def run_reflection_cycle(initial_code: str, max_iterations: int = 3) -> str:
    """Executes a producer-critic self-correction loop in Python."""
    current_code = initial_code
    
    for iteration in range(max_iterations):
        # In production, evaluate_code runs deterministic unit tests or LLM critic
        critique = evaluate_code(current_code)
        
        if critique.is_valid:
            return current_code
            
        # Refine code using feedback from the critic
        current_code = generate_refinement(current_code, critique.critique_feedback)
        
    return current_code

def evaluate_code(code: str) -> EvaluationResult:
    """Simulates a critic checking for missing exception handlers."""
    if "try:" not in code:
        return EvaluationResult(
            is_valid=False,
            critique_feedback="Missing try-except error handling around network calls."
        )
    return EvaluationResult(is_valid=True, critique_feedback="All assertions passed.")

def generate_refinement(code: str, feedback: str) -> str:
    """Simulates generator applying feedback to produce improved code."""
    return f"try:\n    {code}\nexcept Exception as e:\n    logger.error(e)"

The executable snippet above outlines the core control flow of the reflection pattern. By isolating the critic logic, the application verifies assertions deterministically before marking the execution state as complete.

Flowchart contrasting Evaluator-Optimizer reflection feedback loop with directed acyclic graph task planning and execution Figure 2: Execution workflows for Reflection and Planning, detailing the iterative evaluator-optimizer feedback cycle and directed acyclic task decomposition.

Pattern 2: Tool Use (Grounding LLMs with External Capabilities)

Language models are fundamentally statistical text generators. They cannot natively calculate square roots of prime numbers, fetch current stock prices, or query private PostgreSQL databases from their frozen pre-training weights.

The tool use design pattern grants language models hands. By providing models with access to external tools, software architects eliminate hallucinations and ground outputs in deterministic computation. When combined with advanced retrieval, tool calling forms the foundation of agentic RAG reasoning loops.

Why Models Must Stop Guessing Computations and Private Data

Forcing an LLM to multiply large integers or calculate compound interest using next-token prediction is an engineering anti-pattern. While models can approximate arithmetic, they lack an arithmetic logic unit and frequently make off-by-one errors.

In tool-augmented systems, the model recognizes its computational boundaries. When asked a mathematical question, it emits a structured call to a Python calculator tool. The application executes the calculation deterministically and feeds the result back into the model’s context window. The model shifts from being an inaccurate calculator to an orchestrator of software tools.

Native Function Calling and the Model Context Protocol (MCP)

Modern tool use has standardized around structured JSON Schema function calling. Instead of relying on fragile text regex parsing, frontier inference engines support constrained decoding, guaranteeing that tool call arguments match strict API definitions.

At the ecosystem level, tool integration is standardizing around the open Anthropic Research on Building Effective Agents recommendations and the Model Context Protocol (MCP). MCP provides a universal, client-agnostic protocol for connecting language models to secure data repositories, development environments, and third-party SaaS platforms.

import json
from pydantic import BaseModel, Field

class DatabaseQueryTool(BaseModel):
    table_name: str = Field(description="SQL table to query")
    columns: list[str] = Field(description="List of column names")
    limit: int = Field(default=10, ge=1, le=100)

def dispatch_tool_call(tool_name: str, raw_arguments_json: str) -> str:
    """Parses and executes a Pydantic-validated tool call safely."""
    if tool_name == "query_database":
        # Strict validation prevents SQL injection or malformed parameters
        params = DatabaseQueryTool.model_validate_json(raw_arguments_json)
        return execute_sql_query(params.table_name, params.columns, params.limit)
    raise ValueError(f"Unknown tool invoked: {tool_name}")

def execute_sql_query(table: str, cols: list[str], limit: int) -> str:
    """Simulated database execution returning structured JSON records."""
    return json.dumps([{"id": 1, "status": "active", "tier": "enterprise"}])

The preceding code snippet demonstrates safe tool dispatching. Wrapping tool invocations in Pydantic models ensures that malformed arguments generated by language models are caught before hitting production databases.

Pattern 3: Planning (Decomposition, DAGs, and Re-Planning)

When software engineers tackle a massive objective, like migrating an entire microservice to a new cloud provider, they do not attempt the entire operation in a single burst of work. They break the project into an ordered roadmap of sub-tasks.

The planning design pattern brings this decomposition capability to AI agents. It enables agents to pursue long-horizon objectives by generating a multi-step roadmap before executing individual tool actions.

Plan-and-Solve Prompting vs ReAct Loops

In agentic architectures, two primary planning methodologies dominate enterprise deployments:

  1. ReAct (Reason + Act): The agent takes one step at a time in a tight thought, action, and observation cycle; see our dedicated guide on the ReAct pattern in AI agents for trace examples. ReAct is adaptive but can lose sight of long-horizon goals.

  2. Plan-and-Solve: Formalized by Wang et al. Plan-and-Solve Prompting Paper on arXiv, the agent generates a directed acyclic graph of tasks and executes each sequentially.

Plan-and-solve reduces token consumption compared to pure ReAct loops. By establishing the plan upfront, the model executes straightforward steps without re-evaluating the entire objective on every turn.

Managing Execution Checkpoints and Intermediate State

Long-running agent planning workflows require durable checkpointing. If an agent executes seven steps of a ten-step deployment plan and fails at step eight due to a temporary network timeout, the system must not restart from step one.

Production architectures store execution state in a durable database after every completed step. Checkpointing preserves the outputs of previous nodes, allowing human supervisors or automated retry workers to resume execution directly from the failed step.

from typing import List
from pydantic import BaseModel

class ExecutionPlan(BaseModel):
    goal: str
    steps: List[str]
    current_step_index: int = 0
    completed_results: List[str] = []

def execute_plan_with_replanning(plan: ExecutionPlan) -> str:
    """Executes an ordered task plan, dynamically updating steps on failure."""
    while plan.current_step_index < len(plan.steps):
        step = plan.steps[plan.current_step_index]
        success, result = execute_step_action(step)
        
        if success:
            plan.completed_results.append(result)
            plan.current_step_index += 1
        else:
            # Trigger re-planner to generate alternate recovery steps
            plan.steps = replan_remaining_steps(plan.goal, step, result)
            
    return "Goal achieved: " + "; ".join(plan.completed_results)

def execute_step_action(step: str) -> tuple[bool, str]:
    """Simulates a step execution that encounters an initial failure."""
    if "scrape_legacy_site" in step:
        return False, "HTTP 403 Forbidden: WAF block encountered"
    return True, f"Success on: {step}"

def replan_remaining_steps(goal: str, failed_step: str, error: str) -> List[str]:
    """Replaces blocked scrape step with API alternative."""
    return ["authenticate_official_api", "fetch_api_records", "compile_report"]

The code block above shows how dynamic re-planning maintains workflow continuity. When an environmental hurdle arises, the agent adapts its downstream execution graph rather than crashing the overall task.

Pattern 4: Multi-Agent Collaboration (Specialized Division of Labor)

As tasks grow in scope and complexity, packing instructions, twenty tool definitions, and historical conversation transcripts into a single agent prompt causes context window saturation. The model’s attention degrades, and task performance plummets.

The multi-agent collaboration pattern solves this problem by decomposing sprawling objectives across a squad of specialized agents. Each agent possesses a narrow system prompt, dedicated tools, and an isolated context window.

Deconstructing Monoliths into Focused Personas

Instead of creating a monolithic software engineering agent, architects coordinate specialized personas.

  • Product Manager Agent: Clarifies ambiguous user prompts and writes detailed technical specifications.

  • Coder Agent: Reads the specifications and writes clean, type-annotated application code.

  • Code Reviewer Agent: Inspects the generated code for security vulnerabilities, memory leaks, and anti-patterns.

  • QA Test Runner Agent: Executes unit tests in a secure sandbox and feeds runtime error traces back to the Coder.

Dividing labor isolates cognitive context. The Coder agent does not need to remember user conversational pleasantries, and the Reviewer agent focuses exclusively on static analysis rules.

Supervisor-Worker and Peer Handoff Topologies

Coordinating multiple agents requires selecting an appropriate organizational topology. Frameworks like LangGraph, CrewAI, and AutoGen implement two dominant structures:

  1. Hierarchical Supervisor: A central coordinator agent assigns tasks to worker agents, reviews their deliverables, and synthesizes the final response. Workers communicate exclusively through the supervisor.

  2. Peer-to-Peer Swarm: Agents operate as collaborative peers, handing off execution control directly to one another using specialized handoff functions.

For an extensive evaluation of frameworks supporting these topologies, review our analysis of leading open-source AI agent frameworks.

Workflows vs Autonomous Agents: When Not to Use an Agent

One of the most critical architectural decisions an engineering team must make is deciding whether they actually need an autonomous agent. In production software engineering, predictable determinism usually outperforms unconstrained agency.

Anthropic’s seminal paper on building effective agents draws a crucial distinction between Workflows and Autonomous Agents. Teams that ignore this distinction frequently deploy over-engineered, unreliable systems.

Anthropic’s Framework: Prompt Chaining, Routing, and Orchestration

Anthropic defines workflows as systems where LLMs and tools are orchestrated through fixed, deterministic code paths. Common workflow patterns include:

  • Prompt Chaining: The output of LLM Step A becomes the input of LLM Step B in a strict pipeline.

  • Routing: A classifier model directs the input to a specialized downstream prompt or handler.

  • Parallelization: Multiple LLM calls run concurrently, with results aggregated by a final synthesizer node.

In workflows, the developer controls the program flow in Python or TypeScript. The LLM handles the language transformation, but software code dictates the next step.

The Cost and Latency Overhead of Open-Ended Autonomy

By contrast, autonomous agents decide their own control flow. The model determines how many loops to execute, which tools to invoke, and when the task is complete.

While autonomy is necessary for open-ended coding assistants or deep scientific research, it introduces significant downsides in production. Multiple reasoning loops cause response times to balloon from 250ms to over 2,500ms, while intermediate token spend can increase operational costs by 300% to 500%.

Furthermore, autonomous agents can invent untested execution paths that bypass expected security checks. Managing these risks requires strict loop bounding and defensive engineering.

Decision Heuristic: When Determinism Beats Agency

To decide which architecture to deploy, apply this practical engineering rule:

The Agency Rule: If you can map the task into a flowchart with defined branches, build a deterministic Workflow. Only deploy an Autonomous Agent when the problem requires dynamic exploration, novel tool discovery, or open-ended self-correction.

For systems that coordinate distributed sub-agents across complex enterprise boundaries, review our guide on distributed multi-agent coordination architectures.

Production Failure Modes and Troubleshooting Runbook

Deploying agentic design patterns in production requires defensive engineering to handle non-deterministic failure modes. Here is how experienced teams monitor and stabilize agent architectures.

Preventing Infinite Recursion in Evaluator-Optimizer Loops

The most common failure in reflection patterns occurs when the Critic and Generator enter an adversarial stalemate. The Critic repeatedly rejects the Generator’s draft over minor stylistic preferences, consuming tokens until the request times out.

Remediation Protocol:

  • Hardcode a strict recursion_limit (typically 3 iterations) into your state machine orchestrator.
  • Maintain an explicit loop counter in your state schema; once reached, exit to a fallback node.
  • Provide the Critic with an objective checklist or deterministic unit tests rather than open-ended natural language prompts.

Eliminating Parameter Hallucinations in Tool Invocations

When language models invoke external tools, they frequently hallucinate imaginary arguments, pass string representations of integers, or invent non-existent API parameters.

Remediation Protocol:

  • Enforce strict JSON Schema validation using Pydantic or Zod prior to tool execution.
  • If schema validation fails, catch the exception and immediately feed the raw validation error back to the model as an error observation.
  • The model reads the validation error (e.g., 'limit' must be an integer between 1 and 100) and self-corrects on its subsequent turn.

Mitigating Context Saturation in Multi-Turn Planning Graphs

As an agent executes multiple planning steps, the accumulating scratchpad of thoughts, actions, and verbose tool responses fills the context window, causing the model to forget its original objective.

Remediation Protocol:

  • Implement aggressive context pruning after each completed task step.
  • Extract only the core factual payload from raw API responses, discarding verbose HTTP headers and boilerplate metadata.
  • Re-inject the original user goal as an explicit system constraint at every node transition, keeping the agent anchored to the primary objective.

Frequently Asked Questions

What are the 4 core AI agent design patterns?

The four core patterns are Reflection (evaluating and refining outputs), Tool Use (invoking external APIs and databases), Planning (decomposing goals into structured sub-steps), and Multi-Agent Collaboration (dividing labor across specialized personas). Together, they transform static models into autonomous problem-solving systems.

How does the reflection pattern improve AI agent accuracy?

Reflection introduces a secondary evaluator step that reviews initial generations against unit tests, formatting schemas, or constraints. By providing verbal feedback back to the generator, the agent catches subtle bugs and refines outputs prior to user delivery.

What is the difference between an AI workflow and an autonomous AI agent?

Workflows follow predictable, deterministic code paths using predefined chains or routing conditions. Autonomous agents dynamically determine their own control flow, deciding which tools to call and how many steps to take based on intermediate environment feedback.

How does the planning pattern handle unexpected tool errors?

When a planned sub-task fails or returns unexpected data, the planning agent triggers a re-plan step. It analyzes the failure observation, adjusts remaining downstream tasks, or creates alternate sub-steps to reach the objective without crashing.

When should you avoid using an AI agent in production?

Avoid autonomous agents when tasks require strict deterministic compliance, sub-second latency, or where predictable prompt chains already achieve high accuracy. Using open-ended agent loops for simple tasks introduces unnecessary token cost and unpredictable failure modes.

Why is multi-agent collaboration better than a single large prompt?

Monolithic prompts suffer from context window saturation and instruction drift when tasked with complex multi-disciplinary work. Multi-agent collaboration isolates distinct system prompts, personas, and tool sets into independent contexts, dramatically improving execution focus.

ai-agents design-patterns reflection planning tool-use

Found this helpful? Share it with others.

Raj, Founder, AI Agents Kit at AI Agents Kit

Raj

Founder, AI Agents Kit

Raj is the founder of AI Agents Kit, where he writes hands-on guides on AI agents, agent frameworks, Model Context Protocol (MCP), prompt engineering and developer tooling. He builds and tests the tools he covers and focuses on practical, working examples for developers and teams adopting agentic AI.

AI Agents LLMs Prompt Engineering Python TypeScript