Plan and Execute
See the whole road first.
Packing for a holiday one item at a time, with no list, is how you end up on a beach with no swimsuit. On long tasks, step by step agents get lost. So some agents write a plan first, and then they follow it.

- Packing with no list
- Step-by-step agents get lost
- Write a plan first
Writing a plan
We tell the model the goal, and which tools it's got, and we ask for a plan of no more than four steps. Using a schema gives us a real list. Run it. A clear plan, in a sensible order. This has a big benefit. A person can read the plan and approve it before anything happens. It's much easier to review a plan than to clean up after a mistake.
from pydantic import BaseModel
from llm import ask
class Plan(BaseModel):
steps: list[str]
goal = "A customer's wheelset A17 is damaged. Decide how to handle it."
tools = "get_order, search_policy, refund, escalate_to_human"
plan = ask(f"Goal: {goal}\nTools: {tools}\nWrite a plan of at most four short steps.", schema=Plan)
for number, step in enumerate(plan.steps, 1):
print(number, step)1 Retrieve the customer order details using get_order. 2 Search damage and return guidelines using search_policy. 3 Issue a payment return for the item using refund if compliant with policy. 4 Escalate to a human agent using escalate_to_human if issues arise.
Also uses llm.py
from google import genai
from google.genai import types
client = genai.Client()
def ask(prompt, system=None, schema=None):
config = types.GenerateContentConfig(temperature=0.2, system_instruction=system)
if schema:
config.response_mime_type = "application/json"
config.response_schema = schema
r = client.models.generate_content(model="gemini-flash-latest",
config=config, contents=prompt)
return r.parsed if schema else r.textWhen reality changes the plan
Plans break. Here, the third step fails, because payments are down. A dumb executor would stop, or it'd keep going regardless. Ours notices the error, and it replans, keeping what's already done, and replacing the rest. Run it. It did two steps, hit the error, and changed its plan to bring in a person. Good plans are living documents. Never follow one blindly.
steps = ["get_order A17", "search_policy damage", "refund A17 40"]
results = {"get_order A17": "delivered 12 days ago",
"search_policy damage": "two-year warranty",
"refund A17 40": "ERROR: payments are down"}
done = []
for step in steps:
out = results[step]
print(f"{step:<22} {out}")
if out.startswith("ERROR"):
steps = done + ["escalate_to_human"]
print("Replanning:", steps[len(done):])
break
done.append(step)get_order A17 delivered 12 days ago search_policy damage two-year warranty refund A17 40 ERROR: payments are down Replanning: ['escalate_to_human']
Step by step or plan first?
Which approach is best? Step by step adapts quickly, so it's great for short, messy tasks. Plan first keeps long tasks on track, and it lets people review. Many modern agents do both. They keep a to do list, work through it step by step, and update it as they learn. You've seen this in coding agents.
Step by step
- Adapts fast
- Good for short tasks
- Can lose its way
Plan first
- Keeps on track
- Good for long tasks
- People can review it
Summary
Plan for long tasks, and replan when reality changes. Next, a technique that catches mistakes before anyone sees them. Reflection.
Key takeaways- Plans keep long tasks on track
- People can review plans
- Replan when things change