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