An agent runs in a loop: decide, act, observe, repeat. The loop ends when the model decides the task is done. That decision is the weakest part of the design. Models stop too early, claiming success that has not happened, or never stop, retrying a failing call, re-planning in circles or researching forever.
Unbounded loops are expensive and occasionally dangerous. Step budgets and stopping rules put limits around the loop that do not depend on the model's judgement. This guide covers the kinds of budgets to set, how to detect loops and stalls, how to stop gracefully, and how to choose the numbers.
Why agents don't stop well
- No clear done condition. "Research this topic" has no natural end; "find the order and issue the refund" does.
- Unhelpful errors. When a tool returns a vague error, the agent may retry the same call indefinitely; see designing tools that agents can actually use.
- Optimism. Models are trained to complete tasks, so they keep trying rather than admit failure.
- Lost context. In long runs, earlier attempts scroll out of focus, and the agent retries strategies it already tried.
- False completion. The opposite failure: declaring success because the last message sounded final.
Loops and false completion are two of the most common AI agent failure modes.
Four kinds of budget
Set all four; each catches different problems.
| Budget | What it limits | Catches |
|---|---|---|
| Step budget | Number of model turns or tool calls | Loops, re-planning circles |
| Time budget | Wall-clock time per task | Slow tools, waiting on external systems |
| Cost budget | Tokens or money per task | Long contexts, expensive tools, reasoning blow-ups |
| Action budget | Number of side-effecting actions (emails, purchases, writes) | Runaway actions, duplicate operations |
Enforce budgets in code, outside the model. The agent can be told its budget, which helps it plan, but the harness must stop the loop regardless of what the model thinks.
Choosing the numbers
Base budgets on data, not guesses:
- Run the agent on a representative eval set and record steps, time and cost per successful task.
- Look at the distribution. Successful runs usually cluster; failures often take far more steps.
- Set the step budget near the 95th to 99th percentile of successful runs. Runs beyond that point rarely succeed and mostly cost money.
- Set cost budgets per task type, since a research task and a lookup have different needs.
- Revisit after changes to models, prompts or tools.
If many successful runs approach the budget, the task may be too large for one agent run; consider decomposing it; see do you need an agent, or just a workflow?.
Detecting loops and stalls
Budgets are a backstop; earlier detection saves money and gives better outcomes.
- Repeated identical calls: the same tool with the same arguments twice in a row, or three times in a run, is almost always a loop.
- Alternating patterns: A, B, A, B sequences of calls indicate oscillation between two plans.
- No new information: recent tool results add nothing new (same results, same errors).
- Repeated errors: the same error type several times in a row.
- Plan churn: the agent rewrites its plan repeatedly without executing steps.
from collections import Counter
class LoopGuard:
def __init__(self, max_steps=25, max_same_call=2, max_same_error=3):
self.steps, self.calls, self.errors = 0, Counter(), Counter()
self.max_steps, self.max_same_call, self.max_same_error = max_steps, max_same_call, max_same_error
def check(self, tool, args, error=None):
self.steps += 1
key = (tool, tuple(sorted(args.items())))
self.calls[key] += 1
if error:
self.errors[(tool, type(error).__name__)] += 1
if self.steps > self.max_steps:
return "step_budget_exceeded"
if self.calls[key] > self.max_same_call:
return "repeated_identical_call"
if error and self.errors[(tool, type(error).__name__)] >= self.max_same_error:
return "repeated_error"
return NoneProgress checks
For longer tasks, add periodic checkpoints where the agent (or a separate cheap model call) answers: what has been achieved so far, what remains, and is the current approach working? If progress is not being made, the agent should switch strategy, ask the user or stop. A checkpoint every five to ten steps is a reasonable starting point.
Stopping gracefully
How an agent stops matters as much as when. A hard cut-off that returns nothing wastes the work done and confuses users. When a budget or guard triggers:
- Stop taking new actions immediately.
- Summarise what was done: steps taken, actions completed (with IDs), what was found.
- Say clearly what was not done and why: budget reached, repeated error, missing information.
- Suggest a next step: information needed from the user, a human handoff, or a retry with different inputs.
- Leave the system in a consistent state: no half-completed multi-step operations without a record.
Graceful stopping is also where human-in-the-loop patterns fit naturally: a budget stop is a good moment to hand over to a person with full context.
Budgets as a product feature
Budgets are not only a safety mechanism; users notice them. A support agent that gives up politely after a reasonable effort and hands over to a person feels more trustworthy than one that spins for two minutes. Consider exposing limits in the interface where it helps, for example "Searching up to 10 sources," so users know what to expect.
Preventing false completion
The opposite problem, stopping too early with a claim of success, needs a different guard: verify the outcome in code before reporting success. If the task was to book a meeting, check that the calendar event exists. If it was to fix a test, run the test. Only report success when the check passes; otherwise, continue or stop with an honest status.
Budgets in multi-agent systems
When one agent delegates to others, such as an orchestrator spawning research sub-agents, budgets need to compose. Without care, each sub-agent respects its own limit while the total cost of the task grows without bound.
- Set a task-level budget and allocate portions to sub-agents, rather than giving each a fixed independent limit.
- Limit the depth and number of delegations, since sub-agents that spawn further sub-agents multiply costs quickly.
- Return partial results from sub-agents that hit their limits, so the orchestrator can decide whether to continue, re-allocate or stop.
- Log costs per sub-agent so you can see where the budget actually goes.
Telling the agent about its budget
Agents plan better when they know their limits. Include the budget in the prompt ("You have up to 15 tool calls for this task; plan accordingly"), and, for long tasks, show remaining budget as the run progresses. Models often become more decisive, asking the user for missing information earlier instead of searching broadly.
Frequently asked questions
How do I stop an AI agent from looping forever?
Enforce step, time and cost budgets in code, detect repeated identical calls and repeated errors, add periodic progress checks, and have the agent stop gracefully with a summary when a limit is reached.
How many steps should an AI agent be allowed?
Measure the number of steps in successful runs on a representative eval set and set the limit near the 95th to 99th percentile. Runs that go beyond that rarely succeed.
Should the agent know its step budget?
Yes. Telling the agent its budget helps it plan efficiently and ask for missing information earlier. The budget must still be enforced in code.
How can I prevent agents from claiming success when they failed?
Verify the outcome independently in code, such as checking that a record exists or a test passes, before reporting success to the user.



