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