Anthropic's 5 Workflow Patterns¶
Overview¶
While Andrew Ng focuses on discrete patterns (Reflection, Tool Use, Planning, Routing), Anthropic takes a workflow-oriented approach—viewing agent systems as compositions of distinct operational patterns.
These 5 patterns represent common workflow types across production agentic systems.
-
Pattern 1: Agentic Loop¶
What It Does¶
Agent iteratively perceives, reasons, acts, and reflects until goal is achieved.
The Flow¶
- ┌─────────────────────────────────────────┐
- Start: Goal + Context │
- ┬──────────────────────┘
│
- ┌──────────▼──────────┐
- Perceive + Reason │
- (What should I do?) │
- ┬──────────┘
│
- ┌──────────▼──────────┐
- Act (Call Tool) │
- ┬──────────┘
│
- ┌──────────▼──────────┐
- Reflect │
- (Goal achieved?) │
- ┬──────────┘
│
- ┌──────────▼──────────┐
- Continue or Stop? │
- ┬──────────┘
│
- ┌────────────┴────────────┐
│ │
(No) (Yes)
│ │
- ┐ ┌───────┘
│ │
▼ ▼
Loop Back Return Result
Use Cases¶
- Information gathering
- Problem solving
- Task completion
- Iterative refinement
Example: Research Agent¶
class AgenticLoopResearchAgent:
def run(self, goal: str) -> str:
state = {"goal": goal, "findings": []}
while True:
# Perceive: What do I know?
# Reason: What's the next step?
next_action = self.llm.decide(state)
# Act: Execute decision
if next_action.type == "search":
result = self.search_tool(next_action.query)
elif next_action.type == "fetch":
result = self.fetch_tool(next_action.url)
elif next_action.type == "analyze":
result = self.analyze_findings(state)
# Reflect: Did it work?
state["findings"].append(result)
if self.goal_achieved(state):
return self.compile_report(state)
Characteristics¶
- Autonomy: Agent decides when to continue/stop
- Iterative: Loop repeats until goal met
- Reactive: Responds to environment feedback
- Explainable: Each step is visible
When to Use¶
Complex, multi-step goals Information gathering tasks Problems requiring exploration Simple one-shot requests Time-critical decisions
Pattern 2: Retrieval Augmented Generation (RAG)¶
What It Does¶
Retrieve relevant context before generating response, improving grounding and accuracy.
The Flow¶
User Query
↓
Retrieve Relevant Documents
↓
Augment Prompt with Context
↓
Generate Response
↓
Return Result
Use Cases¶
- Knowledge-based Q&A
- Document analysis
- Customer support
- Domain-specific assistance
Example: Documentation Agent¶
class RAGDocumentationAgent:
def answer(self, question: str) -> str:
# Retrieve: Find relevant docs
relevant_docs = self.vector_store.search(question, top_k=5)
# Augment: Add context to prompt
context = "\n".join([doc.content for doc in relevant_docs])
prompt = f"""
Based on this documentation:
{context}
Answer the question: {question}
"""
# Generate: Create response
response = self.llm.generate(prompt)
return response
Characteristics¶
- Grounded: Responses based on specific documents
- Fast: Single inference pass (no loop)
- Deterministic: Same query → same retrieved docs
- Traceable: Can show source documents
When to Use¶
Document-based Q&A Knowledge bases Reducing hallucination Real-time information needs Tasks requiring exploration
Strengths vs Agentic Loop¶
RAG Agentic Loop
Speed Fast Slower (loop)
Accuracy High Very High
Cost Low Higher
Latency <1s Variable
Exploration No Yes
Pattern 3: Chain of Thought Prompting¶
What It Does¶
Force explicit step-by-step reasoning, improving quality on complex tasks.
The Flow¶
Complex Problem
↓
Prompt for Step-by-Step Reasoning
↓
LLM Generates Reasoning Steps
↓
LLM Arrives at Answer
↓
Return Reasoning + Answer
Use Cases¶
- Complex reasoning tasks
- Multi-step problems
- Decision-making
- Quality-critical applications
Example: Decision-Making Agent¶
class ChainOfThoughtAgent:
def analyze(self, problem: str) -> dict:
prompt = f"""
Problem: {problem}
Let me think through this step-by-step:
1. First, I'll identify the key factors
2. Then, I'll consider alternatives
3. Next, I'll evaluate trade-offs
4. Finally, I'll make a recommendation
Step 1: Key factors are...
"""
response = self.llm.generate(prompt)
# Parse out reasoning and answer
reasoning_steps = self.extract_steps(response)
final_answer = self.extract_answer(response)
return {
"reasoning": reasoning_steps,
"answer": final_answer,
"confidence": self.assess_confidence(reasoning_steps)
}
Characteristics¶
- Transparent: Reasoning is visible
- Higher quality: Better performance on hard tasks
- More tokens: Uses extra tokens for thinking
- Debuggable: Can see where reasoning goes wrong
When to Use¶
Complex problems Quality is paramount Need to understand reasoning Simple tasks Latency-critical Cost-sensitive
-
Pattern 4: Function Calling¶
What It Does¶
Agent decides which tool/function to call based on task, enabling tool use and environment interaction.
The Flow¶
Task
↓
LLM Decides Which Function
↓
Call Selected Function
↓
Get Result
↓
Continue or Return
Use Cases¶
- Calling APIs
- Database queries
- External tool integration
- Structured data extraction
Example: Multi-Tool Agent¶
class FunctionCallingAgent:
def __init__(self):
self.tools = {
"search": self.search_web,
"calculate": self.calculate,
"save": self.save_result,
"fetch": self.fetch_url
}
def run(self, goal: str):
messages = [{"role": "user", "content": goal}]
while True:
# Ask LLM which tool to use
response = self.llm.generate(
messages=messages,
tools=list(self.tools.keys())
)
# Check if LLM wants to call a tool
if response.tool_calls:
for tool_call in response.tool_calls:
tool_name = tool_call.name
args = tool_call.arguments
# Call the tool
result = self.tools[tool_name](**args)
# Add result to messages
messages.append({
"role": "assistant",
"content": response.content
})
messages.append({
"role": "tool",
"content": str(result)
})
else:
# LLM generated final response
return response.content
Characteristics¶
- Action-oriented: Agent affects world
- Standardized: Function calling APIs standardized (2023-2024)
- Structured: Clear tool definitions
- Composable: Tools can be chained
When to Use¶
Need to interact with systems Taking action required Calling APIs/databases Pure reasoning tasks No external tools available
Pattern 5: Multi-Agent Coordination¶
What It Does¶
Multiple agents work together, coordinating through communication or shared state.
The Flow¶
- ┌──────────────┐
- Orchestrator │
- ┬───────┘
│
- ┌──────────┼──────────┐
│ │ │
Agent A Agent B Agent C
│ │ │
- ┼──────────┘
│
Result Aggregation
Use Cases¶
- Complex workflows
- Specialized subtasks
- Parallel work
- Knowledge combination
Example: Research Team¶
class MultiAgentResearchTeam:
def __init__(self):
self.researcher = ResearcherAgent()
self.analyst = AnalystAgent()
self.writer = WriterAgent()
self.orchestrator = OrchestratorAgent()
def run(self, goal: str):
# Orchestrator decomposes task
tasks = self.orchestrator.decompose(goal)
# Agents work on their tasks
results = {}
# Researcher finds papers
results["papers"] = self.researcher.find_papers(tasks["research"])
# Analyst analyzes them
results["analysis"] = self.analyst.analyze(
papers=results["papers"],
task=tasks["analysis"]
)
# Writer compiles report
final_report = self.writer.write(
analysis=results["analysis"],
task=tasks["writing"]
)
return final_report
Characteristics¶
- Specialized: Each agent has expertise
- Scalable: Add agents for more capacity
- Communicative: Agents coordinate
- Complex: Harder to debug
When to Use¶
Large, complex projects Multiple specializations needed Parallel work possible Simple tasks Tight coordination needed Real-time communication required
Comparing the 5 Patterns¶
Decision Matrix¶
| Pattern | Speed | Quality | Complexity | Latency | Cost |
|---|---|---|---|---|---|
| Agentic Loop | Medium | Very High | High | High | High |
| RAG | Very Fast | High | Low | Low | Low |
| Chain-of-Thought | Slow | Very High | Low | Medium | Medium |
| Function Calling | Medium | High | Medium | Medium | Medium |
| Multi-Agent | Medium | Very High | Very High | High | High |
Combining Patterns (Typical Production System)¶
Multi-Agent Orchestration
- Agent 1: Agentic Loop
- Uses Chain-of-Thought for complex reasoning
- Uses Function Calling for tool use
│
- Agent 2: RAG System
- Retrieves documents
- Generates answers
│
- Agent 3: Function Calling
- Integrates with external APIs
Real-World Example: Enterprise Research System¶
class EnterpriseResearchSystem:
def process_request(self, request: str):
# Multi-agent coordination
research_team = {
"search_agent": AgenticLoopAgent(
tools=[web_search, academic_db]
),
"rag_agent": RAGAgent(
knowledge_base=company_kb
),
"analysis_agent": ChainOfThoughtAgent(),
"api_agent": FunctionCallingAgent(
tools=api_registry
)
}
# Orchestrator coordinates
results = self.orchestrate(request, research_team)
return results
-
Pattern Selection Guide¶
Choose Agentic Loop If¶
- Need iterative problem-solving
- Complex, multi-step task
- Environment interaction needed
- Quality more important than speed
Choose RAG If¶
- Document-based Q&A
- Knowledge base access
- Speed important
- Hallucination reduction needed
Choose Chain-of-Thought If¶
- Complex reasoning required
- Quality paramount
- Need to explain reasoning
- Cost acceptable
Choose Function Calling If¶
- Tool integration needed
- Structured data extraction
- API calls required
- Automation needed
Choose Multi-Agent If¶
- Very large/complex task
- Multiple specializations
- Parallel work possible
- Team coordination needed
Hybrid Patterns (2025 Best Practice)¶
Most production systems use hybrid combinations:
Research System:
Orchestrator (Multi-Agent)
→ Search Agent (Agentic Loop + Function Calling)
→ Analysis Agent (Chain-of-Thought)
→ Knowledge Agent (RAG)
→ Report Agent (Function Calling)
This combines:
- Agentic Loop's exploration
- RAG's grounding
- Chain-of-Thought's reasoning
- Function Calling's action
- Multi-Agent's coordination
Key Takeaways¶
- Agentic Loop = Iterative problem-solving
- RAG = Grounded, fast answers
- Chain-of-Thought = Complex reasoning
- Function Calling = Tool integration
- Multi-Agent = Scalable, specialized work
Best Practice: Combine patterns based on task needs
-
Next: Read 12 Foundational Patterns¶
-
Last Updated: August 9, 2026