# Planning Strategies

Course: [AI Agents](https://www.devtutorials.ai/learn/ai-agents) · Section: Agent Planning
Source: https://www.devtutorials.ai/learn/ai-agents/planning/planning-strategies

> Three ways an agent can plan: ReAct, Plan-and-Execute and Reflexion. See each one run on the same bug, and learn which to pick for a task.

Think about three people trying to find a new café.

The first person walks one street at a time. At every corner, they look around and then decide which direction to take next.

The second person studies a map, plans the entire route before leaving, and then follows that plan without making changes. At the end, they check whether they reached the correct destination.

The third person follows a route, gets lost, and then stops to think about what went wrong. The next time, they use what they learned to choose a better route.

All three people can reach the café, but they use different approaches. These approaches are similar to three common agent planning strategies: **ReAct**, **Plan-and-Execute**, and **Reflexion**.

**The main idea:** A planning strategy determines when an agent thinks, how far ahead it plans, and how it responds when something goes wrong.

## A Real-World Example

The Brightgrid ticket page displays "80,000 row" instead of "80,000 rows". Here's how each strategy handles the problem:

- **ReAct** runs the tests, reads the failure, opens the file, and fixes the word. It decides each step after seeing the result of the previous step.
- **Plan-and-Execute** creates a plan from the goal before taking any action. It guesses that commas are the problem, follows that plan, and then checks the result. When the check fails, it creates a new plan.
- **Reflexion** tries a quick fix, checks the result, records why it failed, and then tries again using that lesson.

**In simple words:** ReAct thinks at every step. Plan-and-Execute thinks once at the beginning. Reflexion thinks again after a failure.

## What You Will Learn

In this lesson, you will learn:

1. How ReAct combines reasoning, actions, and observations.
2. How Plan-and-Execute separates planning, execution, and validation.
3. How Reflexion uses self-evaluation and error analysis to improve results.
4. How to choose the right strategy for different tasks.

Each strategy includes a Try it card in the **Agent Lab**. Read the thought shown at each step because it identifies the current phase or attempt. The ReAct example can also run with the live model, which you can enable in Settings.

## ReAct Pattern

**ReAct** stands for **Reason + Act**. It is the most common agent strategy, and every agent you have used earlier in this course follows this pattern.

### Reasoning

In ReAct, each step begins with a short **thought**. The thought explains what the agent knows and what it plans to do next.

For example: "The test expected 80,000 rows but got 80,000 row. I will update the code to match the expected result."

### Acting

After the thought, the agent performs one **action**. An action is usually a single tool call, such as `write_file`.

### Observation Cycles

After the action, the agent receives an **observation**, which is the result returned by the tool. The next thought uses that observation when deciding what to do next.

Thought, action, observation. Then the cycle repeats.

This repeating pattern is called an **observation cycle**.

```js runnable title="A ReAct trace: thought, action, observation"
const cycles = [
  { thought: "I don't know what fails yet.", action: "run_tests", observation: "2 failed: expected 80,000 rows, got 80,000 row" },
  { thought: "The word is wrong. I read the file.", action: "read_file web/format.js", observation: "return n.toLocaleString() + \" row\";" },
  { thought: "I add the missing s.", action: "write_file web/format.js", observation: "saved" },
  { thought: "I check my change.", action: "run_tests", observation: "0 failed" },
];

cycles.forEach((c, i) => {
  console.log("Cycle " + (i + 1));
  console.log("  Thought: " + c.thought);
  console.log("  Action: " + c.action);
  console.log("  Observation: " + c.observation);
});
```

Expected output:

```text
Cycle 1
  Thought: I don't know what fails yet.
  Action: run_tests
  Observation: 2 failed: expected 80,000 rows, got 80,000 row
Cycle 2
  Thought: The word is wrong. I read the file.
  Action: read_file web/format.js
  Observation: return n.toLocaleString() + " row";
Cycle 3
  Thought: I add the missing s.
  Action: write_file web/format.js
  Observation: saved
Cycle 4
  Thought: I check my change.
  Action: run_tests
  Observation: 0 failed
```

Look at cycle 2. The thought in cycle 2 uses the observation from cycle 1: "The word is wrong." This connection between observation and the next action is what makes ReAct effective.

ReAct completes the task in 5 steps. Because it checks the latest result before deciding what to do next, it avoids fixing the wrong problem.

## Plan-and-Execute

**Plan-and-Execute** divides the work into three phases.

### Planning Phase

In the **planning phase**, the agent creates the entire plan before taking any action. This requires only one model call, making it fast and inexpensive.

The risk is that the plan is created before the agent has seen much information. If an early assumption is wrong, the rest of the plan may also be wrong.

### Execution Phase

In the **execution phase**, the agent follows the plan step by step. It does not stop to rethink after every action, which is why it can work quickly.

### Result Validation

In the **validation phase**, the agent checks the result, such as by running tests. If the validation fails, a good agent creates a new plan using what it learned.

The next example follows a plan based on an initial assumption and then validates the result.

```js runnable title="Plan first, run the plan, then validate"
const world = { text: "80,000 row" };

const plan = [
  { step: "Add commas to the number", run: () => { world.text = world.text.replace("80000", "80,000"); } },
  { step: "Run the tests", run: () => {} },
];

console.log("Planning phase: " + plan.map((p) => p.step).join(", "));
for (const p of plan) {
  p.run();
  console.log("Execution phase: " + p.step);
}

const passed = world.text === "80,000 rows";
console.log("Validation phase: " + (passed ? "passed" : "failed, the text is still \"" + world.text + "\""));
```

Expected output:

```text
Planning phase: Add commas to the number, Run the tests
Execution phase: Add commas to the number
Execution phase: Run the tests
Validation phase: failed, the text is still "80,000 row"
```

The plan was built on a guess: "the number needs commas". The number already had commas.

The real problem was the word. Validation catches this.

Read the thoughts. Steps 1 to 3 follow the first plan, and validation fails.

Step 4 says "[Re-planning]". The new plan comes from the real failure, and it works.

**Easy Way to Remember:** ReAct is **look, then step**. Plan-and-Execute is **map, then walk, then check**. Reflexion is **try, fail, learn, try again**.

## Reflexion

**Reflexion** adds a reflection step after a failure. The agent writes a short note about what went wrong and uses that lesson in the next attempt.

### Self-Evaluation

**Self-evaluation** means the agent checks its own work. Usually, it runs the tests and then asks, "Did my attempt work?"

### Error Analysis

**Error analysis** means finding out why the attempt failed. The agent compares the expected result with the actual result.

For example: "I added an s to the word, but the real problem was the number format."

### Plan Improvement

**Plan improvement** means turning an error into a lesson and using that lesson in the next attempt.

For example: "Next time, compare the expected text and the actual text before changing the code."

The lesson is stored in the agent's memory so it can be used in later attempts as well.

```js runnable title="Try, reflect, try again"
const wanted = "80,000 rows";
const lessons = [];

function attempt(n) {
  if (lessons.length === 0) return "80000s rows";
  return "80,000 rows";
}

for (let n = 1; n <= 3; n++) {
  const got = attempt(n);
  if (got === wanted) {
    console.log("Attempt " + n + ": passed");
    break;
  }
  const lesson = "Got \"" + got + "\" but wanted \"" + wanted + "\". Fix the number format, not the word.";
  lessons.push(lesson);
  console.log("Attempt " + n + ": failed");
  console.log("Reflection: " + lesson);
}
```

Expected output:

```text
Attempt 1: failed
Reflection: Got "80000s rows" but wanted "80,000 rows". Fix the number format, not the word.
Attempt 2: passed
```

Attempt 2 is different from attempt 1 because of the lesson learned from the first failure. Without the reflection step, the agent would likely make the same mistake again.

Step 3 shows an incorrect guess. Step 4 shows that the attempt failed.

Step 5 begins with "Reflection:" and explains the mistake. Using that lesson, the agent makes a better choice, and the fix works.

## Choosing a Strategy

No single strategy is the best choice for every task. Each strategy has different strengths and works better in different situations.

Here is how the three strategies compare when solving the two Brightgrid bugs, based on the number of steps they require:

```js runnable title="Steps each strategy took in the Agent Lab"
const results = [
  { strategy: "ReAct", steps: 5, modelCallsBeforeFirstAction: 1 },
  { strategy: "Plan-and-Execute", steps: 7, modelCallsBeforeFirstAction: 1 },
  { strategy: "Reflexion", steps: 7, modelCallsBeforeFirstAction: 1 },
];

for (const r of results) {
  console.log(r.strategy + ": " + r.steps + " steps");
}

const fastest = results.reduce((a, b) => (b.steps < a.steps ? b : a));
console.log("Fewest steps here: " + fastest.strategy);
```

Expected output:

```text
ReAct: 5 steps
Plan-and-Execute: 7 steps
Reflexion: 7 steps
Fewest steps here: ReAct
```

On these small bugs, ReAct performs best. Plan-and-Execute loses 2 steps because it follows an incorrect initial assumption. Reflexion also loses 2 steps because its first attempt fails before it learns from the mistake.

That is not always the case:

| Strategy | Best for | Weak at |
|---|---|---|
| ReAct | Problems where each step depends on the previous result | Long tasks because it calls the model at every step, which can increase cost and time |
| Plan-and-Execute | Long tasks with a clear and predictable structure, such as "build these 10 pages" | Unexpected situations because an incorrect plan can waste steps until validation detects the problem |
| Reflexion | Difficult problems that may require multiple attempts, such as complex bugs | Simple tasks because the extra reflection adds unnecessary overhead |

```js runnable title="Pick a strategy from the task"
function pickStrategy(task) {
  if (task.manyTries) return "Reflexion";
  if (task.stepsKnown && task.longJob) return "Plan-and-Execute";
  return "ReAct";
}

const tasks = [
  { name: "Fix one failing test", stepsKnown: false, longJob: false, manyTries: false },
  { name: "Add the same header to 40 pages", stepsKnown: true, longJob: true, manyTries: false },
  { name: "Find a bug that only happens sometimes", stepsKnown: false, longJob: false, manyTries: true },
];

for (const t of tasks) console.log(t.name + " -> " + pickStrategy(t));
```

Expected output:

```text
Fix one failing test -> ReAct
Add the same header to 40 pages -> Plan-and-Execute
Find a bug that only happens sometimes -> Reflexion
```

Many real agents combine multiple strategies. They may create a high-level plan first, use ReAct within each step, and apply Reflexion when something fails.

Plan-and-Execute is only safe when it includes a validation step at the end. If the result is never checked, a mistake made in the first step can still be reported as a success.

## Common Mistakes

| Mistake | Incorrect Understanding | Correct Understanding | What Can Go Wrong |
|---|---|---|---|
| Ignoring observations during reasoning | "Each step can be decided independently." | Every thought should use the latest observation. | The agent acts using outdated information. |
| Planning without validation | "The plan looked correct, so it must have worked." | Always verify the result after executing the plan. | An incorrect plan is reported as successful. |
| Never re-planning | "Keep following the plan no matter what happens." | Create a new plan when validation fails. | The agent continues following the wrong approach. |
| Retrying without learning | "Just try again." | Identify why the previous attempt failed before trying again. | The next attempt repeats the same mistake. |
| Using one strategy for every task | "ReAct is always the best choice." | Choose the strategy that best fits the task. | Long tasks become slower and more expensive than necessary. |

## Exercises

Each exercise ends with a value on the last line. Press **Check** to compare it with the expected answer.

## What to Remember

- **ReAct** follows a cycle of thought, action, and observation at every step.
- **Plan-and-Execute** creates a plan first, follows the plan, and then validates the result. If validation fails, it creates a new plan.
- **Reflexion** makes an attempt, checks the result, identifies why it failed, and then uses that lesson in the next attempt.
- Always validate the result of a plan before considering the task complete.
- Choose the planning strategy that best fits the task, and combine strategies when working on larger or more complex jobs.

Next: **Advanced Planning**, how an agent compares several possible plans before it picks one.
