Plan-Execute Pattern
The Plan-Execute pattern separates planning from execution. The agent first creates a comprehensive plan, then executes each step systematically. This pattern is ideal for complex, multi-step tasks that benefit from upfront planning.
Overview
Plan-Execute agents work in two distinct phases:
- Planning Phase - The LLM creates a detailed, step-by-step plan
- Execution Phase - Each step is executed in order using available tools
- Re-planning (optional) - Adjust the plan based on execution results
This pattern is inspired by classical AI planning systems and the Plan-and-Solve paper.
When to Use Plan-Execute
✅ Good for:
- Complex multi-step tasks
- Tasks requiring sequential execution
- When you need predictable execution order
- Tasks that benefit from upfront planning
- Long-running workflows
❌ Not ideal for:
- Simple, single-step tasks (use ReAct instead)
- Highly exploratory tasks (use ReAct instead)
- When flexibility is more important than structure (use ReAct instead)
- Real-time interactive applications (use ReAct instead)
Pattern Comparison
Not sure which pattern to use? See the Agent Patterns Overview for a detailed comparison of all patterns.
Basic Usage
import { createPlanExecuteAgent } from '@agentforge/patterns';
import { ChatOpenAI } from '@langchain/openai';
import { webScraper, calculator, fileWriter } from '@agentforge/tools';
const agent = createPlanExecuteAgent({
model: new ChatOpenAI({ model: 'gpt-4' }),
tools: [webScraper, calculator, fileWriter],
maxExecutionSteps: 20
});
const result = await agent.invoke({
messages: [{
role: 'user',
content: 'Research the top 5 programming languages in 2026, compare their popularity, and create a summary report.'
}]
});
console.log('Plan:', result.plan);
console.log('Result:', result.messages[result.messages.length - 1].content);Configuration Options
Core Options
interface PlanExecuteConfig {
// Required
model: BaseChatModel; // The language model
tools: StructuredTool[]; // Available tools
// Optional
maxExecutionSteps?: number; // Max steps to execute (default: 25)
maxPlanningIterations?: number; // Max re-planning attempts (default: 3)
returnIntermediateSteps?: boolean; // Include execution steps
enableReplanning?: boolean; // Allow plan adjustments (default: true)
}Advanced Configuration
const agent = createPlanExecuteAgent({
model: new ChatOpenAI({ model: 'gpt-4' }),
tools: [webScraper, calculator, fileWriter],
// Execution limits
maxExecutionSteps: 30,
maxPlanningIterations: 5,
// Enable re-planning based on results
enableReplanning: true,
// Return detailed execution trace
returnIntermediateSteps: true,
// Custom planning prompt
planningPrompt: `Create a detailed, step-by-step plan.
Each step should:
- Be specific and actionable
- Specify which tool to use
- Include expected outcomes
- Consider dependencies`
});How It Works
1. Planning Phase
The agent creates a structured plan:
// Example plan generated by the agent
{
steps: [
{
id: 1,
description: "Search for '2026 programming language popularity'",
tool: "web-search",
expectedOutcome: "List of top programming languages"
},
{
id: 2,
description: "Extract statistics for top 5 languages",
tool: "calculator",
expectedOutcome: "Numerical comparison data"
},
{
id: 3,
description: "Write summary report to file",
tool: "file-write",
expectedOutcome: "Report saved successfully"
}
]
}2. Execution Phase
Each step is executed sequentially:
for (const step of plan.steps) {
const result = await executeTool(step.tool, step.params);
// Check if re-planning is needed
if (result.requiresReplanning) {
plan = await replan(plan, result);
}
}3. Re-planning
If a step fails or produces unexpected results:
const agent = createPlanExecuteAgent({
model,
tools,
enableReplanning: true,
// Custom re-planning strategy
replanningStrategy: async (plan, executionResult, error) => {
if (error) {
// Remove failed step and add alternative
return adjustPlan(plan, executionResult);
}
return plan;
}
});Customization
Custom Planning Prompt
const agent = createPlanExecuteAgent({
model,
tools,
planningPrompt: `You are an expert planner.
Create a comprehensive plan with these requirements:
1. Break down the task into 5-10 clear steps
2. Identify dependencies between steps
3. Specify tools and parameters for each step
4. Include validation checkpoints
5. Plan for error handling
Format your plan as a numbered list with tool specifications.`
});Custom Execution Strategy
import { createPlanExecuteAgent, ExecutionStrategy } from '@agentforge/patterns';
const parallelStrategy: ExecutionStrategy = {
async execute(plan, tools) {
// Group independent steps
const groups = groupIndependentSteps(plan.steps);
// Execute each group in parallel
for (const group of groups) {
await Promise.all(
group.map(step => executeTool(step.tool, step.params))
);
}
}
};
const agent = createPlanExecuteAgent({
model,
tools,
executionStrategy: parallelStrategy
});Streaming
Monitor planning and execution in real-time:
const stream = await agent.stream({
messages: [{ role: 'user', content: 'Complex research task' }]
});
for await (const chunk of stream) {
if (chunk.planning) {
console.log('Planning:', chunk.planning.currentStep);
}
if (chunk.execution) {
console.log('Executing step:', chunk.execution.stepId);
console.log('Result:', chunk.execution.result);
}
}Best Practices
1. Provide Clear Task Descriptions
The quality of the plan depends on task clarity:
// ❌ Vague
const result = await agent.invoke({
messages: [{ role: 'user', content: 'Do some research' }]
});
// ✅ Clear and specific
const result = await agent.invoke({
messages: [{
role: 'user',
content: `Research the environmental impact of electric vehicles:
1. Find recent studies (2024-2026)
2. Compare with traditional vehicles
3. Include manufacturing and lifecycle data
4. Create a summary with citations`
}]
});2. Set Appropriate Step Limits
const agent = createPlanExecuteAgent({
model,
tools,
maxExecutionSteps: 25, // Prevent runaway execution
maxPlanningIterations: 3 // Limit re-planning attempts
});3. Enable Re-planning for Robustness
const agent = createPlanExecuteAgent({
model,
tools,
enableReplanning: true, // Adapt to unexpected results
replanningThreshold: 0.7 // Re-plan if confidence < 70%
});4. Use Checkpoints for Long Tasks
import { withCheckpointing } from '@agentforge/core';
const agent = withCheckpointing(
createPlanExecuteAgent({ llm, tools }),
{
checkpointEvery: 5, // Save state every 5 steps
storage: 'redis'
}
);Common Patterns
Research & Report Generation
import { webScraper, htmlParser, fileWriter } from '@agentforge/tools';
const researchAgent = createPlanExecuteAgent({
model: new ChatOpenAI({ model: 'gpt-4' }),
tools: [webScraper, htmlParser, fileWriter],
maxExecutionSteps: 30,
planningPrompt: `Create a research plan:
1. Identify key topics to research
2. Search multiple sources for each topic
3. Synthesize findings
4. Generate structured report
5. Save to file with citations`
});Data Pipeline
import { fileReader, jsonParser, csvParser } from '@agentforge/tools';
const pipelineAgent = createPlanExecuteAgent({
model: new ChatOpenAI({ model: 'gpt-4' }),
tools: [fileReader, jsonParser, csvParser],
planningPrompt: `Create a data processing plan:
1. Read source data
2. Validate and clean data
3. Transform to target schema
4. Write to database
5. Verify data integrity`
});Multi-Source Analysis
import { apiCall, webScrape, calculator, chartGenerate } from '@agentforge/tools';
const analysisAgent = createPlanExecuteAgent({
model: new ChatOpenAI({ model: 'gpt-4' }),
tools: [apiCall, webScrape, calculator, chartGenerate],
enableReplanning: true,
planningPrompt: `Create an analysis plan:
1. Gather data from all sources
2. Normalize and merge datasets
3. Perform statistical analysis
4. Generate visualizations
5. Create summary report`
});Debugging
Inspect the Plan
const result = await agent.invoke(input, {
returnIntermediateSteps: true
});
console.log('Generated Plan:');
result.plan.steps.forEach((step, i) => {
console.log(`${i + 1}. ${step.description}`);
console.log(` Tool: ${step.tool}`);
console.log(` Expected: ${step.expectedOutcome}`);
});Track Execution Progress
const result = await agent.invoke(input, {
callbacks: [{
handleToolStart: (tool, input) => {
console.log(`Starting: ${tool.name}`, input);
},
handleToolEnd: (output) => {
console.log('Completed:', output);
},
handleToolError: (error) => {
console.error('Error:', error);
}
}]
});Visualize Plan Execution
import { visualizePlanExecution } from '@agentforge/core';
const result = await agent.invoke(input, {
returnIntermediateSteps: true
});
// Generate Gantt chart or flowchart
const diagram = visualizePlanExecution(result);
console.log(diagram);Performance Optimization
1. Parallel Execution
Execute independent steps in parallel:
const agent = createPlanExecuteAgent({
model,
tools,
executionMode: 'parallel', // Execute independent steps concurrently
maxParallelSteps: 3
});2. Plan Caching
Cache plans for similar tasks:
import { withPlanCache } from '@agentforge/patterns';
const agent = withPlanCache(
createPlanExecuteAgent({ llm, tools }),
{
ttl: 3600,
similarityThreshold: 0.8
}
);3. Incremental Execution
Resume from checkpoints:
const agent = createPlanExecuteAgent({
model,
tools,
resumeFromCheckpoint: true,
checkpointStorage: 'redis'
});
// Resume interrupted execution
const result = await agent.invoke(input, {
checkpointId: 'previous-run-id'
});Comparison with ReAct
| Feature | Plan-Execute | ReAct |
|---|---|---|
| Planning | Upfront, structured | Dynamic, iterative |
| Execution | Sequential | Flexible |
| Best for | Complex, multi-step | General purpose |
| Predictability | High | Medium |
| Adaptability | Medium (with re-planning) | High |
| Token usage | Higher (planning overhead) | Lower |
Next Steps
- ReAct Pattern - For flexible, iterative tasks
- Reflection Pattern - For self-improving agents
- Multi-Agent Pattern - For collaborative planning
- API Reference - Complete API documentation
Further Reading
- Plan-and-Solve Paper - Research paper
- LangGraph Planning - LangGraph tutorial
- Examples - Working code examples