Skip to content

Plan everything first or react step by step

In this lesson we put the patterns of this part of the course side by side and choose between them for a task. We place two ways of deciding the steps at the ends of one spectrum and compare a fixed workflow with an agent. Then we count the calls of six ways to run a task of twelve steps. At the end we split a large goal into levels of plans and look at what gets lost where two patterns meet.

The patterns come from the earlier lessons of this part. Reasoning before each action decided one step at a time from the result of the step before. A second pass that critiques the first added a critic that reads an output and asks for changes. Writing the plan before taking the steps had the model write the steps first, and its follow run sent a customer a false email because the plan didn’t change when step three returned a new fact.

At one end the agent decides the whole sequence of steps first and then runs it. This is plan-then-execute. At the other end the agent decides each step from the result of the step before, which is the ReAct loop. The Agent Engineer Course treats these as two pure forms that real agents mix [1], and this course calls the choice between them plan-then-execute vs reactive.

The plan end is predictable. Before the first step you know the steps and their order, so you also know how many calls the run makes. A person can read the list and correct it while nothing has changed yet, as in the planning lesson. Steps that don’t depend on each other can run in parallel, because the plan shows which ones they are [1]. The weakness is a step that surprises. A plan is written before its steps return anything, so it can be wrong or miss something, and it adapts only when someone plans again [1]. When the plan is wrong, more of the work is wasted than in a loop that adapts as it goes [2].

The reactive end adapts well. Each decision sees the result of the step before it. A surprise changes the next step with no extra machinery, and there is no call that writes a plan first. The weakness is that the run is hard to bound. Before it starts, nobody knows how many steps it takes or which tools it calls. The Agent Engineer Course lists more weaknesses of the reactive end. A reactive agent has no view of its progress as a whole, and it can miss a step that a plan would have listed. Its steps are hard to run in parallel, because each one waits for the result before it, and without a plan the agent can drift away from the goal [1]. The step limits from Stopping the loop on purpose are one way to put a bound on the run.

Anthropic’s engineering article on building agents draws a similar line between two kinds of system [3]. In a workflow, code that the developers wrote decides the path of model calls and tool calls. In an agent, the model decides its own steps and which tools to use. Its advice is to build the smallest system that does the job and to add parts only when the job asks for them. A workflow suits a task whose steps are clear in advance, and it behaves the same way on every run. When the model has to choose the path as it goes, an agent is the better fit. That freedom costs more to run, and a mistake in one step can make the steps after it go wrong too [3].

On the spectrum, a fixed workflow is past the plan end. A person writes the plan once, as code, and the model can’t change it. Where the model decides, the system is an agent, at the reactive end or somewhere between the two ends.

Most systems are between the ends. The Agent Engineer Course says that most production agents write a short plan of a few high-level steps and make ReAct-style decisions inside each step. They look at the plan again after each large step [1]. Its lesson on design patterns gives the same advice, a rough plan first and then reasoning step by step while the plan runs [2]. The work run of the planning lesson had the re-planning half of this pattern, with a new look at its five-step plan after each step. Code ran each step there, so no decision was made inside a step.

The same course lists when to lean to each end [1]. Lean to the plan when the task is well understood, splits into independent parts, must report its progress, or is costly to get wrong. Lean to the reactive end when the task is exploratory, when you can’t guess what the steps find, when speed matters more than a thorough result, or when the task has fewer than three steps.

The cost of a pattern is in its calls. The program site/examples/building-agents/plan-or-react/costs.py counts the model calls and tool calls of six ways to run a task of twelve tool steps. It adds up the time when every call runs after the one before it, with 3 seconds per model call and 1 second per tool call. The seconds are assumptions written by hand, to compare the patterns with each other, and no model is called.

  • fixed workflow: code that a person wrote runs the twelve steps, and no model call decides them.
  • plan then execute: one model call writes the plan, and code runs its steps, as follow did in the planning lesson.
  • plan, check after each step: the plan, and one model call after each step to keep or change it, as work did.
  • reactive: one model call picks each step, and one more writes the answer, as in the ReAct loop.
  • coarse plan of 3 phases: one call writes a plan of three phases. Inside a phase the model picks each step, and at the end of each phase one call checks the plan.
  • reactive with a critic: the reactive loop, and a critic call that reads the result of each step.

To run it yourself, copy the plan-or-react folder from the repository and run the command below inside your copy.

Example · run it

Run this, and compare what you see with the output below.

Terminal window
python3 costs.py
Output
12 tool steps, 3 s per model call, 1 s per tool call
pattern                      model  tool  seconds
fixed workflow                   0    12       12
plan then execute                1    12       15
plan, check after each step     13    12       51
reactive                        13    12       51
coarse plan of 3 phases         16    12       60
reactive with a critic          25    12       87

Output verified in CI from site/examples/building-agents/plan-or-react/costs.py.

Every pattern makes the same 12 tool calls. The differences are in the model calls. The fixed workflow makes 0 model calls and finishes in 12 seconds, and plan then execute makes 1 model call and finishes in 15. Neither can react to a surprise. A check after each step costs as many model calls as the reactive loop, 13 against 13, so adapting costs about the same whether a plan comes first or not. The plan adds a list of steps that a person can read first. The critic makes the run the slowest in the table, 87 seconds against 51 for the same loop without it.

The reactive row has one more catch. Its 13 calls are true only if the task takes twelve steps, and a reactive loop learns the number of steps at the end of the run. The rows with a plan know their count before the first step. In your copy, change STEPS, MODEL_SECONDS or TOOL_SECONDS at the top of costs.py, and run it again for the numbers of your own task.

Checkpoint · scenario

A wrong early step would waste every step after it. Where on the spectrum do you start?

A goal can be too large for one flat list. Hierarchical planning splits it into subgoals, and each subgoal gets a plan of its own. The Agent Engineer Course names four levels: the goal, the subgoals that are the large phases of work, the tasks, and the steps. An agent usually plans at the level of subgoals and tasks, and ReAct-style decisions handle the steps inside a task [1].

Each subgoal can run in its own agent call with a fresh context. In Claude Code a subagent starts with a context of its own and doesn’t see the main conversation. It gets its own system prompt and a task message that the main agent writes for it. Claude Code also loads parts of the project setup for it, such as the CLAUDE.md files. A fork is the exception, and it starts with the parent conversation. A subagent does its work in its own context and returns a summary to the main conversation [4]. The top level then keeps the list of subgoals and the status of each one, and the detail stays in the context of the level below.

That keeps each context small and on one subject. The cost is at the line between two levels. The level below knows only what the task message and its own setup give it, and the level above knows only what the summary says. Say a top-level agent writes release notes for three services, one subagent per service, and the team’s rule is that the notes list only changes a customer can see. If the rule stays in the top level’s context and never reaches the task messages, each subagent lists every change it finds. If a subagent sees that a release was rolled back and writes “done” in its summary, the top level puts the rolled-back change in the notes.

A system that combines patterns has a handoff wherever one part passes work to another. Take a composition of a planner, an executor that runs the steps, and a reflector that critiques the result. Each pattern has failures of its own, and each handoff can add one that neither side has alone:

  • Planner to executor. The executor gets the steps and not the constraints the planner knew, such as a budget, and it breaks a limit that nobody told it about.
  • Executor to planner. The planner doesn’t see what the steps returned, and it keeps a plan that a result has made wrong. This is the follow run of the planning lesson.
  • Executor to reflector. The reflector gets the output and not the original goal, so it checks the form of the answer and passes an answer to the wrong question.
  • Reflector to executor. The executor applies every request the reflector sends and nothing sets a limit on the rounds, so the two loop. The reflection lesson capped the rounds at two for this reason.

Each added pattern also adds model calls, time and parts that can break [2]. Keep a composition only when it shows better results on the task than the simpler system [3]. A failure can also pass from one part to the next. A step that fails early makes the steps after it fail, and the agent can report the last failure as the cause instead of the first one [1]. To find these problems before the users do, write down at each handoff what passes across and what doesn’t. Then test the composition with a fault at each handoff, such as an empty plan or a tool that returns an error.

Checkpoint · match

The travel agent books a trip to Oslo. Match each handoff to what is lost at it.

Exercise

For each of the tasks below, place it on the spectrum from plan-then-execute to reactive, name the pattern you would start with, and write what it costs in model calls and seconds at twelve steps. Use the table from costs.py for the numbers. Write one paragraph per task. The point is to name the property of the task that decides the pattern, before any code exists.

  1. Each month, export the invoices from the billing system, convert them and upload them to the accounting system, in the same twelve steps.
  2. Find out why a nightly job has started to fail, in a code base that nobody on the team wrote.
  3. Set up a new employee: create accounts in six systems, order a laptop, book the meetings of the first week and email the manager a summary. A system may refuse a user name that is already taken.
  4. Write a report on five competitors: research each one, compare them and recommend one.

A good result names a property of each task and a pattern that follows from it. Task one has known steps, so it is a fixed workflow, at 0 model calls and 12 seconds. Task two is exploratory and belongs at the reactive end, at 13 model calls and 51 seconds if it takes twelve steps, with a step limit because nobody knows the count in advance. Task three has dependent steps that change accounts and a result that can change the rest. It gets a plan that a person reads and a check after each step, at 13 model calls and 51 seconds. Task four fits a coarse plan of 3 phases: research on the five competitors, a comparison, and the recommendation. The model decides the steps inside each phase, at 16 model calls and 60 seconds, and each phase can run in a fresh context. Which of your four would you move one place toward the reactive end first if an evaluation showed it failing, and what would you measure before you move it?

Stretch: Pick one of the four tasks and change costs.py so that its rows match your design, with the number of phases or the steps with a critic that you chose. Run it and compare the numbers with your estimate.

Recap

  1. Plan-then-execute decides every step first. It is predictable and easy to review, and a step that surprises can make it wrong. The reactive end decides each step from the result before it, so it adapts, and its length is hard to bound [1].
  2. Use a fixed workflow when the steps are known and an agent when the task needs decisions by the model, and start with the simplest that works [3]. Most agents plan coarsely and react inside each step [1].
  3. At twelve steps a fixed workflow makes 0 model calls and a plan that only runs makes 1. A check after each step or a reactive loop makes 13, and a critic on each step raises it to 25.
  4. Hierarchical planning gives each subgoal its own plan, and a subgoal can run in a fresh context, as a Claude Code subagent does [4]. Each level knows only what the handoff gives it. Write down what passes at each handoff of a composition, and test each handoff with a fault.

You can now

  • Picks a design pattern for a task and says why
  • Composes patterns and names the failure modes of the composition

  1. Addy Osmani, Ivar Soares Urdalen, Leo Simons. Planning and reasoning: the loop, plan-then-execute, hierarchy. Agent Engineer Course. Course. AEC-06
  2. Addy Osmani, Ivar Soares Urdalen, Leo Simons. Agentic design patterns: ReAct, reflection, tool use, planning. Agent Engineer Course. Course. AEC-04
  3. Erik S., Barry Zhang. Building effective agents. Anthropic Engineering. Reference. Anthropic effective agents
  4. Anthropic. Create custom subagents. Claude Code documentation. Reference. Claude Code subagents