Skip to content

Andrew Ng's 4 Core Patterns

Overview

Andrew Ng distilled agentic system design into 4 fundamental patterns in 2024-2025. These are the foundation all other patterns build upon.


Pattern 1: Reflection

What It Does

Agent generates output, then critiques and improves its own work before returning to user.

The Loop

Generate → Critique → Improve → Return

Benefits

  • Higher quality outputs
  • Catches obvious errors
  • Reflects values back to agent

When to Use

  • Quality is paramount (writing, analysis)
  • LLM can self-critique effectively
  • Extra inference cost is acceptable

Example: Essay Writing Agent

class ReflectionAgent:
    def run(self, prompt: str) -> str:
        # Generate
        draft = self.llm.generate(prompt)

        # Critique
        critique = self.llm.generate(f"""
            Critique this essay:
            {draft}

            Focus on: clarity, accuracy, completeness
        """)

        # Improve
        final = self.llm.generate(f"""
            Based on this feedback:
            {critique}

            Revise the essay:
            {draft}
        """)

        return final

Cost/Benefit

  • Cost: 3x inference cost (generate, critique, improve)
  • Benefit: ~30% quality improvement typical

Pattern 2: Tool Use

What It Does

Agent can call functions/APIs to gather information and take action.

The Loop

Reason → Choose Tool → Call Tool → Integrate Result → Repeat

Key Insight

This is what makes agents agents. Without tools, they're just chatbots.

Categories of Tools

  • Information: Search, database query, retrieval
  • Action: API calls, file writes, system commands
  • Computation: Math, data analysis, code execution

Example: Research Agent

class ToolUsingAgent:
    def __init__(self, tools: Dict):
        self.tools = tools  # {name: function}

    def run(self, goal: str) -> str:
        while not self.done():
            # Decide which tool to use
            tool_choice = self.llm.choose_tool(
                goal=goal,
                available_tools=list(self.tools.keys())
            )

            # Call the tool
            result = self.tools[tool_choice.name](**tool_choice.args)

            # Integrate result
            self.update_context(result)

            # Check if done
            if self.goal_achieved():
                return self.format_result()

Real-World Impact

Enable agents to interact with actual systems: - Look up data in databases - Call APIs to execute transactions - Write files and documents - Send messages and notifications


Pattern 3: Planning

What It Does

Agent breaks complex goal into smaller sub-goals before executing.

The Loop

Goal → Decompose → Plan Steps → Execute Plan → Reflect

Why It Matters

Complex tasks fail without planning. Planning enables: - Clarity (understand scope) - Efficiency (avoid wasted steps) - Debuggability (can see step-by-step)

Example: Research Plan Agent

class PlanningAgent:
    def run(self, goal: str) -> str:
        # Step 1: Create plan
        plan = self.llm.generate(f"""
            Goal: {goal}

            Create a step-by-step plan. Each step should be:
            - Specific (what exactly to do)
            - Achievable (possible with available tools)
            - Ordered (early steps enable later ones)

            Format as numbered list.
        """)

        # Step 2: Execute plan
        results = []
        for step in plan.steps:
            result = self.execute_step(step)
            results.append(result)

        # Step 3: Compile results
        return self.llm.generate(f"""
            Original goal: {goal}
            Plan executed: {plan}
            Results: {results}

            Provide final comprehensive answer.
        """)

Cognitive Load

  • Without planning: Agent gets lost, repeats work, inefficient
  • With planning: Clear roadmap, better quality, sometimes slower

Pattern 4: Routing

What It Does

Directs incoming requests to specialist agents based on content.

The Loop

Incoming Request → Classify → Route → Specialist Agent → Respond

Benefits

  • Specialists are more accurate
  • Can use different models for different tasks
  • Cost optimization (use right model for task)

Example: Customer Support Router

class RoutingAgent:
    def __init__(self):
        self.specialists = {
            "billing": BillingAgent(),
            "technical": TechnicalAgent(),
            "account": AccountAgent(),
            "general": GeneralAgent()
        }

    def route(self, customer_message: str) -> str:
        # Classify the issue
        category = self.llm.classify(customer_message)

        # Route to specialist
        specialist = self.specialists[category]

        # Get response
        response = specialist.handle(customer_message)

        return response

Production Usage

  • Customer support (route to right team)
  • API gateways (route to right service)
  • Triage systems (route by priority/type)

How These Patterns Interact

- ┌─────────────────────────────────────────┐
    - User Request                    │
  - ┬──────────────────────────┘
               │
- ┌──────────▼──────────┐
    - Routing Pattern     │
    - (Which specialist?) │
  - ┬──────────┘
               │
- ┌──────────▼──────────┐
    - Planning Pattern    │
    - (What's the plan?)  │
  - ┬──────────┘
               │
- ┌──────────▼──────────┐
    - Tool Use Pattern    │
    - (Execute steps)     │
  - ┬──────────┘
               │
- ┌──────────▼──────────┐
    - Reflection Pattern  │
    - (Is it good?)       │
  - ┬──────────┘
               │
- ┌──────────▼──────────┐
    - Response       │
  - ┘

Pattern Selection Guide

Goal Best Pattern Why
Better quality Reflection Self-critique
Interact with systems Tool Use Need to take action
Complex tasks Planning Need roadmap
Multiple types of requests Routing Specialize response

Combining Patterns (Typical Production Agent)

class ProductionAgent:
    def run(self, request: str) -> str:
        # Step 1: Route to appropriate specialist
        category = self.route(request)
        specialist_config = self.specialists[category]

        # Step 2: Create plan for this request
        plan = self.plan(request, specialist_config)

        # Step 3: Execute plan using tools
        result = self.execute_with_tools(plan)

        # Step 4: Reflect and improve
        if self.should_reflect(result):
            result = self.reflect(result)

        return result

Key Metrics by Pattern

Pattern Complexity Quality Gain Cost Use Frequency
Reflection Low +30% 3x tokens 60%
Tool Use Medium +200% Variable 80%
Planning Medium +50% 2x tokens 70%
Routing Low +20% Minimal 50%

Common Mistakes

❌ Using reflection for every task (expensive)
❌ Forgetting to validate tool results
❌ Creating plans that are too detailed
❌ Routing incorrectly (misclassification)


Next: Read About Anthropic'S 5 Workflows


Last Updated: August 9, 2026