PlanAndExecute
from loomflow.architecture import PlanAndExecute, Plan, PlanStep, StepResultPlan-and-Execute commits to a plan upfront and walks it step-by-step. Wang et al. 2023 (Plan-and-Solve Prompting); He et al. 2025 (Plan-then-Execute Pattern Implementation).
For the conceptual page see Plan-and-Execute.
Class signature
class PlanAndExecute:
name: str = "plan-and-execute"
def __init__(
self,
*,
max_steps: int = 8,
planner_prompt: str | None = None,
executor_prompt: str | None = None,
synthesizer_prompt: str | None = None,
) -> None: ...Constructor parameters
max_steps
| Type | int |
| Default | 8 |
Hard cap on plan length. The planner sometimes produces a 30-step
plan when 5 steps would do. That’s usually a planner failure mode.
The architecture truncates to max_steps defensively. Must be
>= 1; raises ValueError otherwise.
planner_prompt
| Type | str | None |
| Default | None (uses built-in default) |
Override the planner’s system prompt. The default teaches the model to emit a JSON list of steps, each a short imperative description. Provide your own when the default doesn’t fit your domain (e.g. domain-specific step shapes, custom output formats).
executor_prompt
| Type | str | None |
| Default | None (uses built-in default) |
Override the per-step executor prompt. The default seeds each step with the original problem + the plan + prior step outputs, then asks for the step’s result.
synthesizer_prompt
| Type | str | None |
| Default | None (uses built-in default) |
Override the final synthesizer prompt. The default combines step outputs into a single answer. Customize when you want a different output shape (structured JSON, citations format, etc.).
Methods
declared_workers
Returns {}. Single-agent.
run
Three-phase loop:
- Plan. ONE LLM call. Output is a JSON list parsed into a
Plan. Emitsplan.planner_started/plan.createdevents. - Execute. Walks
plan.stepssequentially. Each step is a text-only model call seeded with the original problem + the plan- prior step outputs. Per-step events:
step.started/step.completed.
- prior step outputs. Per-step events:
- Synthesize. ONE LLM call combining step outputs into the
final answer. Writes to
session.output.
Empty plan terminates with session.output = "Planner produced no steps; cannot execute."
and emits plan.empty_plan.
Related types
Plan
class Plan(BaseModel):
steps: list[PlanStep]The planner’s output. Stored on session.metadata["plan"] for
introspection.
PlanStep
class PlanStep(BaseModel):
description: strOne imperative description of a step. Currently the only field; sub-architecture invocation per step (each step running its own ReAct / etc.) is planned for a future release.
StepResult
class StepResult(BaseModel):
step: PlanStep
output: strThe result of executing one PlanStep. The synthesizer receives
list[StepResult] and produces the final answer.
Cost model
For an N-step plan: 1 (planner) + N (steps) + 1 (synthesizer) LLM
calls. ReAct on the same task: roughly N + 1 calls. But each
call carries the growing message history. Plan-and-Execute is
cheaper when message history is the dominant token cost.
What’s NOT in v1
- Sub-architecture invocation per step. Each step is a single text-only call, not a fresh ReAct (or any other architecture) invocation. That’s planned for a later release; until then, steps can’t call tools. For tool-heavy plans, use ReWOO.
- Adaptive replanning. No re-plan after a failed step. The plan is committed at start. Failures surface as the step’s output text.
Example
from loomflow import Agent
from loomflow.architecture import PlanAndExecute
agent = Agent(
"Research the topic and produce a structured brief.",
model="claude-opus-4-7",
architecture=PlanAndExecute(max_steps=5),
)
result = await agent.run("State of vector databases in 2026.")Or by string:
agent = Agent("...", model="...", architecture="plan-and-execute")Source
loomflow/architecture/plan_and_execute.py
Plan-and-Execute vs ReWOO. Both are plan-then-execute
architectures. PlanAndExecute steps are text-only model calls;
ReWOO steps are tool calls with
{En} placeholder substitution. Use ReWOO when the plan is
“search → fetch → summarize”; use PlanAndExecute when each step is
its own reasoning chunk.