An agent loop is a while statement whose exit condition is decided by a language model. Most of the time the model decides correctly. Occasionally it keeps calling tools, re-reading the same file, or retrying a failing step, and the only thing between that run and an alarming invoice is whatever limit you wrote beforehand. Caps are cheap to add before an incident and awkward to add during one.

Three limits, because each catches a different failure

A single limit is rarely enough, since the failure modes differ:

  • Step cap. The maximum number of model turns or tool calls in one run. It catches loops: the agent repeating a call that never makes progress.
  • Token cap. The maximum input plus output tokens consumed across the run. It catches runs that are not looping but are growing, such as a context that gets larger with every tool result.
  • Wall-clock cap. A deadline on the whole run. It catches slow tools and retries that a step count cannot see, because ten steps against a slow dependency can take as long as a hundred fast ones.

Choose the values from data, not instinct. Look at the distribution of steps and tokens for runs that succeeded, and set the cap comfortably above the high percentiles of that distribution. If your cap sits at the median, you will cut off healthy work. If you can't find a number, log usage for a week before enforcing anything.

Failing gracefully is the real design work

Hitting a cap should not look like a crash. Decide in advance what the system does at the boundary:

  1. Warn before the wall. At around 80% of a budget, tell the model how much remains ("you have 3 steps left; wrap up or report what is incomplete"). Models often behave better when they know the limit exists.
  2. Reserve the last step for reporting. If the cap is ten steps, the tenth should be a summary of what was done and what was not, with no tool access. A run that stops silently leaves the user guessing about partial side effects.
  3. Return a distinct stop reason. Record budget_exhausted separately from completed and error. Otherwise your success metrics quietly include runs that were truncated, and your dashboards look healthier than the product is.
  4. Make partial work inspectable. If the agent changed files or created records before the cap hit, the final message should list them, so a human can finish or undo the job.

Watch for loops that stay under the cap

A step limit will not catch an agent that alternates between two actions for forty steps and then does something useful. Cheap loop detection helps: hash each tool call's name and arguments, and treat a third identical call within a short window as a signal to interrupt the model with a nudge or to stop. This is a heuristic and will have false positives, such as polling a job status on purpose, so give legitimate polling tools an explicit exemption instead of loosening the detector.

The closing point

Budgets are part of the agent's interface, not just an operational safeguard. Tell the model the limits, handle the boundary deliberately, and count every cap hit as a signal worth reviewing. A rising rate of budget_exhausted is usually the earliest sign that a prompt change, a tool change, or a new class of task has made your agent worse.