Multi-Step Autonomy: How Agents Plan, Act, Verify, and Retry

How multi-step autonomous agents plan, act, verify, and retry without a prompt for every step, and the guardrails that keep loops safe.

Multi-Step Autonomy: How Agents Plan, Act, Verify, and Retry

A single-shot AI call takes an input and returns an output. Multi-step autonomy means the system can take a goal — “fix the failing test in the billing module” — and work through however many steps that actually requires, checking its own progress along the way, without a human typing a new prompt after every action.

The core pattern is a loop, not a pipeline: plan → act → verify → retry (or stop). Understanding that loop, and where it needs guardrails, is most of what it takes to build autonomy that’s useful instead of dangerous.

The Loop, Concretely

Goal: "Fix the failing test in test_billing.py"
Plan: Read the test, read the code it exercises, form a hypothesis
Act: Read test_billing.py and billing.py
Verify: Hypothesis — off-by-one error in tax rounding
Act: Edit billing.py to fix the rounding
Verify: Run test_billing.py → still failing, different assertion
Plan: Revise hypothesis — the fix exposed a second bug
Act: Read the new failing assertion, edit again
Verify: Run test_billing.py → passes
Verify: Run full test suite → no regressions
Stop: Goal achieved, open PR

Each verify step is what makes this autonomy rather than blind repetition — the agent isn’t just generating a plausible-looking edit, it’s checking real ground truth (test output) before deciding whether to continue, retry, or stop.

Why Verification Has to Be Real, Not Self-Reported

The single biggest failure mode in early agent systems was letting the model judge its own success — “I believe this fix is correct” is not verification, it’s a guess with confidence. Real multi-step autonomy ties the “verify” step to something outside the model’s own output: test results, linter exit codes, a schema validator, a second model acting as a checker. This connects directly to feedback loops — autonomy without a real feedback signal is just an agent confidently repeating its own mistakes.

The Guardrails That Keep Loops From Running Away

GuardrailWhat it prevents
Max iteration countInfinite retry loops burning time and money on an unsolvable task
Cost/token budget per taskA single task consuming disproportionate compute
Escalation trigger after N failed verificationsAgent silently giving up or looping instead of asking for help
Diff size limitA “small fix” ballooning into an unreviewable rewrite
Scope boundary (allowed files/directories)An agent wandering outside the task’s intended blast radius

A production system should treat “the agent hit its iteration limit” as a normal, expected outcome — not a bug — and route it to a human with full context of what was tried, exactly like a person would escalate a task they got stuck on.

Plan-and-Execute vs. Reactive Loops

Two common architectures handle the plan step differently:

  • Reactive (ReAct-style): the agent decides its next action one step at a time, reasoning fresh after every observation. Flexible, but can wander on long tasks.
  • Plan-and-execute: the agent commits to a multi-step plan upfront, then executes it, replanning only if a step fails. More predictable and auditable, better for tasks where the shape of the work is well understood in advance (e.g., “upgrade this dependency across the repo”).

Most production coding agents use a hybrid: plan-and-execute for the overall task shape, reactive reasoning within each step.

Practical Starting Point

Don’t design for full autonomy on day one. Start with a loop capped at 2–3 iterations and a hard escalation to a human on any verification failure — this gives you real production data on where the agent actually gets stuck before you invest in more sophisticated planning or higher iteration limits. Autonomy budgets should expand based on observed reliability, not assumed capability.