The agent went in circles and burned the budget — catching it early

One task ate a month's budget — nearly always a loop. The causes, and three ways to protect yourself.

3 min · · Updated · агенты · экономия · limits

A familiar story: you left the agent with a task, came back half an hour later, and half the month's budget is gone. The log shows twenty identical attempts to read the same file.

This is neither rare nor a malfunction. Here's where it comes from and how to protect yourself.

Why agents loop

The task is unsolvable as stated. "Fix the test" — while the test fails on a missing environment variable the agent doesn't have and can't get. It will keep trying, because admitting a task is impossible is something it does poorly.

A tool keeps returning the same thing. A command fails, the agent concludes it should try differently, tries something nearly identical, gets the same error. The loop closes.

Context overflowed and the model lost the thread. In a long session early steps get evicted, and the agent stops remembering what it already tried. From that point it can repeat the same path indefinitely.

The model isn't up to the task. A cheap model on a hard problem may circle: it can neither solve nor stop. That, incidentally, is the hidden cost of economising — the requests are cheaper but there may be far more of them.

Spotting it

The simplest approach is to watch spend during the work, not at the end of the month.

bash
curl https://api.zukko.pro/v1/balance -H "Authorization: Bearer fetch_your_key"

The response holds the exact account balance in cents (the balance_cents field). Agents usually stream, and streaming responses carry no cost headers, so this or GET /v1/usage is the convenient way to watch spend. The dashboard has a per-model breakdown and a request history. A sharp jump in request count within one task, with no progress, is a reliable sign of a loop.

A sign you can catch by eye: on the fifth step the agent's reasoning starts containing "let me try again", "perhaps it's something else", "let's check once more". Two of those in a row — stop it.

Three safeguards

A cap on the key. The most reliable. A dedicated key for the agent with a daily ceiling means the loop hits the limit rather than your balance. It's configured in the dashboard: keys have daily and monthly caps and simply stop working once exhausted — requests get a 429 key_daily_limit_reached (resets at 00:00 UTC) or key_monthly_limit_reached.

While you're there, restrict which models that key may use, so the agent can't wander onto the most expensive one.

A separate key per project. Then overspending is localised: the limit trips only on the key that looped, and the others keep working. Note that the /v1/usage history is account-wide (all keys together, no per-key filter), and the balance is per account too. To split spend by project, log X-Zukko-Cost-Micros per key on your side (for non-streaming requests) or set up a separate account.

A step limit in the agent itself. Nearly every harness lets you cap iterations. The default is often generous; twenty to thirty steps per task is a sensible starting ceiling.

When it has already happened

Interrupt the session, don't wait for it to finish. Start a new one — with specifics instead of a general brief.

Bad: "figure out why the tests fail." Good: "the test test_weekly_stats fails with TypeError: days must be int. Look at app/models.py, the days field is declared as a string. Fix the type and run that test."

The spend difference between those two phrasings can be very large.

If the task genuinely can't be done without you, tell the agent about the constraint directly: "there is no DB_URL in the environment, treat the database as unavailable." That spares it fruitless attempts.

On model choice

The temptation to use a cheaper model for a hard task is understandable, but the arithmetic usually disagrees. glm-5.3 at $0.10 per million is three times cheaper than a flagship — but if it loops for ten extra steps, you pay more than claude-opus-5-5 would have cost for one correct answer.

A sensible split is a cheap model for mechanical steps and a flagship for the ones requiring judgment.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

Agent stuck in a loop — capping the spend · Zukko