Stop Agent Loops Before They Drain Your API Budget
Stop Agent Loops Before They Drain Your API Budget
The expensive agent failure rarely looks dramatic. A terminal session keeps retrying a flaky test, rereading the same files, and asking for another patch. You leave for coffee; the agent stays busy without getting closer to done. My rule: every autonomous task gets a finite spending envelope and a definition of progress before it gets tool access.
Reserve spend before dispatching each model call
A maximum iteration count is useful, but twenty turns with a growing repository transcript can cost much more than twenty short prompts. Enforce both a turn limit and a monetary ceiling in the supervisor that launches requests, not merely in instructions to the model.
Before dispatch, reserve a conservative estimate covering input tokens and the permitted output. Reconcile that reservation against reported usage afterward. Include outstanding reservations when checking remaining funds; otherwise, parallel workers can each observe the same available budget and collectively overspend it.
- Assign separate spending limits to tasks, workers, and sessions.
- Reject new requests when reservations would exceed the task ceiling.
- Stop safely when usage accounting is missing or unexpectedly delayed.
- Require explicit approval before increasing any exhausted task budget.
This is application-side control unless your provider explicitly documents equivalent enforcement. A dashboard alert is not a hard stop, and a local budget must survive process restarts if the agent does.
Count cached context without counting it twice
I use Fluxo when switching models because one key and one base URL, https://api.fluxorelay.com, cover multiple model families. It works with Claude Code, Codex, Gemini CLI, and any OpenAI SDK. That simplifies wiring, but it does not remove the need to meter each autonomous job.
Fluxo bills per real token, including cache reads and writes, with no monthly fee. Keep the relevant usage categories in your ledger and apply their current rates. Check whether a response reports cached tokens as a subset of input or as separate fields before calculating totals. Adding every field blindly can double-count usage.
A cache hit is not free execution. An agent repeatedly replaying a huge cached transcript still incurs charges. Record context size per turn, trim stale tool output, and checkpoint concise task state instead of dragging every failed command through every subsequent request.
Make retries consume the same finite budget
Trace your retry stack before running unattended. SDK retries, relay retries where applicable, and agent-level retries can multiply attempts. Set explicit limits at each layer, add exponential backoff with jitter, and count every attempt against the same task envelope.
A timeout does not prove that inference never happened. Treat interrupted requests as potentially billable until reconciled. Do not assume a request identifier provides deduplication unless that behavior is documented. For tools with side effects, use your own operation identifiers and durable completion records before retrying.
Stop loops that change files without making progress
Track repeated tool calls, normalized error signatures, and acceptance-test outcomes. Three identical failures should trigger a checkpoint or human review, not an unlimited sequence of differently worded prompts. File churn alone is not progress.
For a concrete routing policy, let Gemini 3.8 Flash handle bounded triage, then escalate a difficult patch to Claude Sonnet 5.5 only after recording the blocker. Give escalation a separate allowance and a maximum number of handoffs. Model switching must not reset the parent task's budget.
- Cap tool output before oversized logs enter the next prompt.
- Limit concurrent workers sharing one repository and one spending envelope.
- Persist stop reasons so restarts cannot silently resume exhausted tasks.
Test the budget breaker before leaving your terminal
Run a deliberately impossible task with a tiny allowance. Verify that retries stop, worker processes terminate, pending reservations reconcile, and restarting the runner does not revive the loop. Test cancellation propagation too; closing a terminal is not proof that remote work stopped.
If you want to try this setup, create a Fluxo account and start with one tightly capped task. Keep referral accounting separate from operational budgets: users earn a referral share when people they invite pay, but anticipated rewards should never expand an agent's spending authority.