Plan & Solve Agent Pattern
The Plan & Solve pattern separates planning from execution by first creating a comprehensive multi-step plan, then systematically executing each step to solve complex problems.
Overview
Best For: Tasks that can be decomposed into clear, sequential steps
Complexity: ⭐⭐ Moderate (Simple two-phase approach)
Cost: $$ Medium (Planning + execution calls)
When to Use Plan & Solve
Ideal Use Cases
✅ Structured problem solving
Agent creates detailed plan upfront
Executes steps sequentially
Each step builds on previous results
✅ Multi-step workflows
Clear dependency between steps
Benefits from upfront planning
Systematic execution required
✅ Complex calculations
Multi-stage mathematical problems
Data processing pipelines
Algorithm implementation
✅ Research and analysis tasks
Information gathering workflows
Systematic investigation
Sequential reasoning chains
When NOT to Use Plan & Solve
❌ Dynamic environments → Use ReAct for adaptive planning ❌ Tool-based workflows → Use ReAct or REWOO ❌ Learning from failures → Use Reflexion ❌ One-step tasks → Direct LLM call sufficient
How Plan & Solve Works
The Two-Phase Workflow
┌─────────────────────────────────────────┐
│ │
│ PHASE 1: PLANNING │
│ │
│ Task: "Create a marketing strategy" │
│ ↓ │
│ Plan: │
│ 1. Analyze target market │
│ 2. Identify key messaging │
│ 3. Select marketing channels │
│ 4. Create content calendar │
│ 5. Define success metrics │
│ │
└─────────────────┬───────────────────────┘
↓
┌─────────────────────────────────────────┐
│ │
│ PHASE 2: EXECUTION │
│ │
│ Execute Step 1: │
│ "Target market: millennials interested │
│ in sustainable products..." │
│ ↓ │
│ Execute Step 2: │
│ "Key messaging: eco-friendly, │
│ affordable luxury..." │
│ ↓ │
│ Execute Step 3... │
│ Execute Step 4... │
│ Execute Step 5... │
│ │
└─────────────────┬───────────────────────┘
↓
┌─────────────────────────────────────────┐
│ │
│ AGGREGATION │
│ │
│ Combine all step results into │
│ comprehensive final answer │
│ │
└─────────────────────────────────────────┘
Theoretical Foundation
The Plan & Solve pattern is based on problem decomposition and structured execution principles:
Planning reduces errors: Thinking ahead prevents missteps
Sequential execution: Complex problems broken into manageable parts
Accumulative progress: Each step builds on previous work
Clear structure: Explicit plan makes process transparent
Algorithm
def plan_and_solve(task):
"""Simplified Plan & Solve algorithm"""
# Phase 1: Planning
plan = llm_create_plan(task)
# plan = [step1, step2, step3, ...]
# Phase 2: Execution
step_results = []
for step in plan:
result = llm_execute_step(
task=task,
step=step,
previous_results=step_results
)
step_results.append(result)
# Aggregation
final_answer = llm_aggregate(
task=task,
plan=plan,
results=step_results
)
return final_answer
API Reference
Class: PlanAndSolveAgent
from agent_patterns.patterns import PlanAndSolveAgent
agent = PlanAndSolveAgent(
llm_configs: Dict[str, Dict[str, Any]],
prompt_dir: str = "prompts",
custom_instructions: Optional[str] = None,
prompt_overrides: Optional[Dict[str, Dict[str, str]]] = None
)
Parameters
Parameter |
Type |
Required |
Description |
|---|---|---|---|
|
|
Yes |
LLM configs for “planning”, “execution”, and “documentation” roles |
|
|
No |
Custom prompt directory (default: “prompts”) |
|
|
No |
Instructions appended to system prompts |
|
|
No |
Override specific prompts programmatically |
LLM Roles
planning: Used for creating the multi-step plan
execution: Used for executing each step
documentation: Used for aggregating results into final answer
Methods
run(input_data: str) -> str
Executes the Plan & Solve pattern on the given input.
Parameters:
input_data(str): The task or problem to solve
Returns: str - The final aggregated result
Raises: ValueError if graph not built
build_graph() -> None
Builds the LangGraph state graph. Called automatically during initialization.
Complete Examples
Basic Usage
from agent_patterns.patterns import PlanAndSolveAgent
# Configure LLMs
llm_configs = {
"planning": {
"provider": "openai",
"model": "gpt-4",
"temperature": 0.3, # Lower temp for consistent planning
},
"execution": {
"provider": "openai",
"model": "gpt-4",
"temperature": 0.7,
},
"documentation": {
"provider": "openai",
"model": "gpt-4",
"temperature": 0.7,
}
}
# Create agent
agent = PlanAndSolveAgent(llm_configs=llm_configs)
# Solve multi-step problem
result = agent.run("""
Calculate the ROI for a software development project with:
- Initial investment: $500,000
- Development time: 12 months
- Expected revenue: $100,000/month after launch
- Operating costs: $30,000/month
- 3-year evaluation period
Provide detailed ROI calculation with explanation.
""")
print(result)
# Agent will:
# 1. Plan: Break down into steps (calculate costs, revenue, profit, ROI)
# 2. Execute: Run each calculation step
# 3. Aggregate: Combine into comprehensive ROI analysis
With Custom Instructions
# Add domain-specific planning guidance
research_guidelines = """
You are a research analyst. Follow these principles:
PLANNING:
- Break complex questions into researchable sub-questions
- Ensure logical dependency between steps
- Plan for both data gathering and analysis
EXECUTION:
- Be thorough and specific in each step
- Show your work and reasoning
- Build on results from previous steps
- Cite sources when applicable
AGGREGATION:
- Synthesize findings coherently
- Address the original question directly
- Highlight key insights
- Note limitations or uncertainties
"""
agent = PlanAndSolveAgent(
llm_configs=llm_configs,
custom_instructions=research_guidelines
)
result = agent.run("""
Research question: What factors contributed to the success of
remote work adoption during 2020-2023, and what are the long-term
implications for office real estate?
""")
With Prompt Overrides
# Customize planning and execution prompts
overrides = {
"PlanStep": {
"system_prompt": """You are an expert planner who creates detailed,
actionable steps for complex problems. Each step should be:
- Specific and actionable
- Dependent on previous steps where appropriate
- Achievable with available information
- Contributing to the final solution""",
"user_prompt": """Task: {task}
Create a detailed step-by-step plan. Number each step clearly.
Make sure steps are in logical order and build on each other.
Your plan:"""
},
"ExecuteStep": {
"system_prompt": "You are a meticulous executor who completes tasks thoroughly.",
"user_prompt": """Original task: {task}
Current step: {step}
Results from previous steps:
{previous_results}
Execute this step with detail and precision. Show your work.
Your result:"""
},
"AggregateStep": {
"system_prompt": "You synthesize information into clear, comprehensive answers.",
"user_prompt": """Task: {task}
All step results:
{results}
Combine these results into a well-structured final answer that fully
addresses the original task. Organize logically and highlight key points.
Your final answer:"""
}
}
agent = PlanAndSolveAgent(
llm_configs=llm_configs,
prompt_overrides=overrides
)
result = agent.run("""
Design a database schema for an e-commerce platform that supports:
- User accounts and authentication
- Product catalog with categories
- Shopping cart and checkout
- Order history and tracking
- Reviews and ratings
""")
Customizing Prompts
Understanding the System Prompt Structure
Version 0.2.0 introduces enterprise-grade prompts with a comprehensive 9-section structure. Each system prompt is now 150-300+ lines, providing significantly better guidance.
The 9-Section Structure: All prompts now include Role and Identity, Core Capabilities (CAN/CANNOT boundaries), Process, Output Format, Decision-Making Guidelines, Quality Standards, Edge Cases, Examples, and Critical Reminders. Benefits: Increased reliability, transparency, and robustness.
Understanding Plan & Solve Prompts
The pattern uses three prompt templates (all now with comprehensive 9-section structure):
PlanStep: Creates the multi-step plan
Analyzes the task with systematic guidance
Breaks it into sequential steps with quality standards
Ensures logical flow with edge case handling
ExecuteStep: Executes individual steps
Takes current step description
Has access to previous step results
Produces detailed step output with examples
AggregateStep: Combines results
Reviews all step outputs systematically
Synthesizes coherent final answer with quality criteria
Addresses original task comprehensively
Method 1: Custom Instructions
agent = PlanAndSolveAgent(
llm_configs=llm_configs,
custom_instructions="""
PLANNING STYLE: Create 4-7 clear, actionable steps
EXECUTION STYLE: Be thorough and show reasoning
AGGREGATION STYLE: Create executive summary + detailed findings
"""
)
Method 2: Prompt Overrides
# Customize for code generation
code_overrides = {
"PlanStep": {
"user_prompt": """Task: {task}
Create a coding plan with these steps:
1. Define data structures/classes
2. Implement core functionality
3. Add error handling
4. Write tests
5. Add documentation
Your detailed plan:"""
},
"ExecuteStep": {
"user_prompt": """Coding task: {task}
Step: {step}
Previous code:
{previous_results}
Write the code for this step with:
- Clear comments
- Proper error handling
- Type hints (if applicable)
Your code:"""
}
}
agent = PlanAndSolveAgent(
llm_configs=llm_configs,
prompt_overrides=code_overrides
)
Method 3: Custom Prompt Directory
my_prompts/
└── PlanAndSolveAgent/
├── PlanStep/
│ ├── system_prompt.md
│ └── user_prompt.md
├── ExecuteStep/
│ ├── system_prompt.md
│ └── user_prompt.md
└── AggregateStep/
├── system_prompt.md
└── user_prompt.md
Setting Agent Goals
Via Task Description
Provide clear, structured task:
# Well-defined requirements
agent.run("""
Project: Customer Churn Prediction System
Requirements:
1. Analyze customer behavior data
2. Identify key churn indicators
3. Propose ML model approach
4. Define evaluation metrics
5. Create implementation roadmap
Deliverable: Technical specification document
""")
Via Custom Instructions
agent = PlanAndSolveAgent(
llm_configs=llm_configs,
custom_instructions="""
GOAL: Produce actionable, implementation-ready solutions
PLANNING REQUIREMENTS:
- 5-8 concrete steps
- Clear dependencies
- Realistic scope per step
EXECUTION REQUIREMENTS:
- Specific, not generic
- Include examples where relevant
- Reference previous steps
FINAL OUTPUT REQUIREMENTS:
- Start with executive summary
- Organize into logical sections
- Include next steps/recommendations
"""
)
Advanced Usage
Role-Specific Models
# Use different models for different phases
llm_configs = {
"planning": {
"provider": "openai",
"model": "gpt-4", # Strong model for planning
"temperature": 0.2, # Low temp for consistent plans
},
"execution": {
"provider": "openai",
"model": "gpt-3.5-turbo", # Cheaper for execution
"temperature": 0.7,
},
"documentation": {
"provider": "openai",
"model": "gpt-4", # Strong model for synthesis
"temperature": 0.7,
}
}
agent = PlanAndSolveAgent(llm_configs=llm_configs)
Custom Step Execution Logic
class CustomPlanAndSolveAgent(PlanAndSolveAgent):
def _run_single_step(self, step, state):
"""Override to add custom execution logic"""
step_description = step.get("step_description", "")
# Add custom preprocessing
if "calculate" in step_description.lower():
# Use specialized calculation handling
return self._execute_calculation_step(step, state)
elif "research" in step_description.lower():
# Use research-specific approach
return self._execute_research_step(step, state)
else:
# Default execution
return super()._run_single_step(step, state)
def _execute_calculation_step(self, step, state):
"""Custom logic for calculation steps"""
# Implementation here
pass
agent = CustomPlanAndSolveAgent(llm_configs=llm_configs)
Plan Validation
class ValidatedPlanAndSolveAgent(PlanAndSolveAgent):
def _generate_plan(self, state):
"""Override to validate plan before execution"""
state = super()._generate_plan(state)
plan = state.get("plan", [])
# Validate plan quality
if len(plan) < 2:
# Plan too short, regenerate
return super()._generate_plan(state)
if len(plan) > 15:
# Plan too long, might be too granular
# Could prompt for consolidation
pass
return state
agent = ValidatedPlanAndSolveAgent(llm_configs=llm_configs)
Performance Considerations
Cost Optimization
Plan & Solve cost calculation:
Planning: 1 LLM call
Execution: N calls (N = number of steps)
Aggregation: 1 call
Total: N + 2 calls
Typical: 6-8 LLM calls for average task
# Optimize by using cheaper models for execution
llm_configs = {
"planning": {"provider": "openai", "model": "gpt-4"},
"execution": {"provider": "openai", "model": "gpt-3.5-turbo"}, # Cheaper
"documentation": {"provider": "openai", "model": "gpt-4"}
}
# Encourage concise plans via custom instructions
custom_instructions = """
PLANNING: Create 4-6 high-level steps (avoid over-granularity)
"""
Speed Optimization
# Faster models for time-sensitive tasks
llm_configs = {
"planning": {
"provider": "openai",
"model": "gpt-3.5-turbo", # Faster planning
"temperature": 0.3,
},
"execution": {
"provider": "openai",
"model": "gpt-3.5-turbo",
"temperature": 0.7,
},
"documentation": {
"provider": "openai",
"model": "gpt-3.5-turbo",
"temperature": 0.7,
}
}
Comparison with Other Patterns
Aspect |
Plan & Solve |
ReAct |
Self-Discovery |
|---|---|---|---|
Planning |
Upfront, complete |
Adaptive per step |
Dynamic module selection |
Execution |
Sequential steps |
Tool-based actions |
Reasoning strategies |
Flexibility |
Fixed plan |
Highly adaptive |
Moderate |
Tools |
Not supported |
Core feature |
Not supported |
Best For |
Known workflows |
Dynamic problems |
Complex reasoning |
Cost |
Medium |
Medium |
High |
Common Pitfalls
1. Too Granular Plans
❌ Bad: Plan with 20+ tiny steps
# Results in excessive LLM calls and fragmented execution
✅ Good: 4-8 meaningful steps
custom_instructions = """
Create 4-8 substantial steps. Each step should accomplish something meaningful.
Avoid breaking tasks into trivial micro-steps.
"""
2. Steps Without Dependencies
❌ Bad: Independent steps that don’t build on each other
# Plan:
# 1. Research topic A
# 2. Research topic B (unrelated)
# 3. Research topic C (unrelated)
# → Should use parallel execution, not Plan & Solve
✅ Good: Sequential, dependent steps
# Plan:
# 1. Define requirements
# 2. Design architecture (based on requirements)
# 3. Identify implementation challenges (based on architecture)
# 4. Propose solutions (based on challenges)
3. Vague Step Descriptions
❌ Bad: Generic step descriptions
# Step 1: Analyze
# Step 2: Decide
# Step 3: Implement
✅ Good: Specific, actionable steps
overrides = {
"PlanStep": {
"user_prompt": """Task: {task}
Create specific, actionable steps. Each step should clearly state:
- What will be done
- What output is expected
Your detailed plan:"""
}
}
4. Ignoring Previous Results
❌ Bad: Steps don’t use previous outputs
✅ Good: Ensure execution accesses context
# ExecuteStep prompt already includes {previous_results}
# Make sure your custom prompts do too if overriding
Troubleshooting
Plans Are Too Short
Symptom: Agent creates 1-2 step plans for complex tasks
Solutions:
# Add guidance in custom instructions
custom_instructions = """
PLANNING: Create comprehensive plans with 5-8 steps for complex tasks.
Break down the problem thoroughly.
"""
# Or override PlanStep prompt
overrides = {
"PlanStep": {
"user_prompt": """Task: {task}
This is a complex task. Create a detailed plan with 6-10 specific steps.
Your plan:"""
}
}
Steps Don’t Build on Each Other
Symptom: Execution ignores previous results
Solutions:
# Emphasize continuity in ExecuteStep
overrides = {
"ExecuteStep": {
"user_prompt": """Task: {task}
Step: {step}
Previous results:
{previous_results}
Execute this step, explicitly building on and referencing previous results where relevant.
Your result:"""
}
}
Poor Final Synthesis
Symptom: Aggregation doesn’t coherently combine results
Solutions:
# Improve AggregateStep prompt
overrides = {
"AggregateStep": {
"user_prompt": """Task: {task}
Step-by-step results:
{results}
Create a comprehensive final answer that:
1. Synthesizes all step results into a coherent narrative
2. Directly addresses the original task
3. Highlights key findings
4. Provides clear structure (use headings if appropriate)
Your final answer:"""
}
}
Next Steps
Try the complete examples
Learn about ReAct for adaptive planning with tools
Explore Self-Discovery for complex reasoning
Read about prompt customization
References
Related to classic problem decomposition in computer science
Inspired by hierarchical planning in AI systems
Similar to Chain-of-Thought with explicit planning phase