Planning and replanning
A plan is a list of steps with a check after each one. Its value is not the list — it is knowing which step failed and being able to change only that step.
Why plan at all
A plan makes the work visible before it is done. That is useful for the same reason a checklist is: a missing step is cheap to spot in a list and expensive to discover after four tool calls.
It also gives the loop a notion of position. Without a plan, “what is left” is whatever the model happens to remember; with one, it is a list with completed items.
Keeping the plan as data rather than as prose inside the prompt is what makes this possible. A list of items with ids and done flags can be sliced, reordered and rendered into the next prompt; a paragraph of intentions cannot. The model can propose the plan, but the program owns it, marks items done and decides what the remaining tail is.
A plan is a hypothesis
The first plan is written before any evidence arrives, so it is a guess about what will be needed. Treating it as fixed is how an agent keeps trying to read a document that does not exist.
Replanning means: after a step fails or returns something surprising, rewrite the remaining steps and keep what is already done. That is a small operation if the plan is data, and impossible if the plan is buried in the prompt.
The plan should also record what each step is for. “Read the policy” is an action; “find the refund window” is a goal with a test. When the action fails, the goal tells the replanner what to preserve: a different document can still answer the same question, while a different question changes the plan entirely. That distinction is what keeps a replan local instead of a rewrite.
Plan as state
state["plan"] = [
{"id": 1, "task": "find the refund policy", "done": False},
{"id": 2, "task": "extract the time window", "done": False},
{"id": 3, "task": "write the answer", "done": False},
]
# After a failure, only the unfinished tail changes:
state["plan"] = state["plan"][:done] + new_stepsExecute a plan and mark it done
Run the executor, then make step two fail and confirm only the unfinished tail is retried. The completed step must not run again.
The plan is not the work
A plan earns its keep when a step fails. The executor marks the first two items done, the third returns nothing, and the replanner replaces only the unfinished tail: search the FAQ instead, read the result, answer. The completed work stays completed, so the retry does not repeat the expensive part. That is the whole value of keeping the plan as data.
A common mistake is replanning after every observation. Each rewrite is a model call, and the plan can oscillate between two routes without ever finishing either. The symptom is a run that spends its budget producing a beautifully revised list and no answer. Replan on failure, contradiction or a goal that no longer matches — not on every step.
When planning is overkill
A task that needs one tool call does not need a plan. Neither does a task whose steps are already fixed — that is a chain, and a plan adds a model call to discover what you already knew.
Planning pays when the task has several dependent steps and the path is not obvious. The signal is a question you cannot answer without first finding something else.
Keep plan items small enough to verify. “Research the topic” cannot be marked done; “find the refund window in the policy” can.
Replanning needs a reason
Do not replan after every step. Replan when a step fails, when an observation contradicts an assumption, or when the remaining plan no longer matches the goal.
Unnecessary replanning is expensive and unstable: each rewrite is another model call, and the agent can spend the whole budget rearranging its list instead of doing the work.
Record the reason in the state: “read failed: document missing”, “search returned no results”, “goal changed after the customer replied”. The reason is what makes the next plan reviewable and what stops the agent from replanning for the same cause twice. It also gives you a test: feed the recorded observation and assert the tail that was produced. That record makes a failed run debuggable without replaying the model.
Rewrite only the tail
The lookup fails, so the plan changes. Run it and compare the fixed-plan run with the replanned one — same goal, different route.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
What is the main value of an explicit plan?
