GVNR

How to stop an AI agent spending too much money

Most advice on this is a list of dashboards to watch. Watching is not stopping. This is about the controls that actually refuse an action, in the order they are worth adding, and what each one misses.

You can do the first four with no tool at all, and most of the value is there. The last two need something sitting in front of the agent.

1. Turn on the provider's own cap first

It is free, it needs no code, and it is the only control that works when everything else you build has a bug in it. Anthropic ships usage limits at organisation, workspace and member level; OpenAI has hard and soft monthly caps in billing. Claude Code takes a per-session ceiling directly:

claude --max-budget-usd 5

Where it fails: a monthly cap is a cliff, not a brake. You find out you were wrong at the end of the month, and by then the money is gone. It also cannot tell a useful $200 from a wasted $200.

2. Give each agent its own budget, in dollars

Token counts are the wrong unit. They are not comparable across models, and a cached session re-reads its whole context every turn, so raw token sums balloon into the billions while costing very little.

Weight by price instead. One effective token is one input-token of cost at that model's price, so output at roughly 5x input, cache writes at about 1.25x, cache reads at about 0.1x. Then a dollar cap converts with a single multiply, and $20 means $20 whether the agent is on a frontier model or a small one.

Where it fails: a per-session cap is still a total. An agent that burns the lot in ninety seconds and an agent that works all afternoon look identical to it.

3. Cap the rate, not just the total

This is the one almost nobody ships, and it is where the money actually goes. A total only notices once it is spent. A rate notices while it is happening.

Four rates are worth watching, and you can compute all of them from a sliding window of request outcomes:

SignalWhat it catchesSane starting point
Dollars per minute, per agentA single agent that has gone wrong. Ordinary work sits around $0.10 to $0.25 a minute, so $2 leaves normal sessions alone$2
Dollars per minute, across the fleetMany agents each looking individually fine$10
New agents per minuteAn orchestrator spawning orchestrators. A team that starts over an hour is a choice; eight inside a minute is a bug8
Errors per minuteA retry storm. A rate-limited call fails cheaply, the retry after it does not6

Gate on the derivative, not the total. In pseudocode, that is the whole idea:

window = requests in the last 60s
spend_per_min       = sum(cost(r) for r in window if r.agent == this_agent)
fleet_spend_per_min = sum(cost(r) for r in window)
errors_per_min      = count(r for r in window if r.failed)
new_agents          = count(distinct new agent ids in window)

if spend_per_min > burn_limit: ask the human
if fleet_spend_per_min > fleet_burn_limit: ask the human
if errors_per_min > retry_limit: ask the human
if new_agents > fanout_limit: ask the human

Make it ask once, not block. An overnight run that dies at 2am has cost you the night. One that pauses and waits has cost you nothing.

4. Catch the loop

Repeated work is cheap per call and expensive in aggregate. Hash the action and its arguments, keep a short streak counter per agent, and treat a streak past three or four as a loop rather than progress. This is behaviour, not cost, so it fires before the budget notices.

5. Gate what it may do, not only what it may spend

Here is the part a spend cap structurally cannot do. The actions that hurt most are nearly free:

A budget check will wave every one of those through on a full budget. You need a separate check that runs on capability regardless of spend, with three outcomes rather than two: refuse the reckless ones outright, and make the irreversible ones stop and ask.

Where the agent supports it, do this before the tool runs rather than at the API. Claude Code exposes a PreToolUse hook for exactly this, and a refused action there never executes at all.

Be honest about the limit: pattern rules are a guard, not a sandbox. In June 2026, GuardFall research from Adversa AI tested eleven open-source coding agents and found ten whose command guards could be defeated by shell obfuscation. If your threat model is an adversary rather than an accident, the answer is process or container isolation with no credentials in reach, and a pattern guard on top of it.

6. Keep a record you can defend

Once an agent acts for a person, "what did it do" becomes a question someone else asks you. A log is not enough, because anyone with write access can revise it. Chain each record to the one before it so an edit visibly breaks the chain, and record the fields an audit actually wants: the human it acted for, the tool, the model that answered, and the rule that decided.

What not to bother with

If you would rather not build it

GVNR is controls 2 to 6 above in one install, available for Claude Code today with other agents coming. It is free. Full disclosure: we make it.

/plugin marketplace add instruxi-io/claude-plugins
/plugin install enforcer-governor@instruxi

It runs inside Claude Code and nothing leaves your machine until you sign in to a workspace. The quickstart takes about a minute, and how it compares is honest about the cases where something else is the better answer.

Nothing above requires it. Points 1 to 4 are worth doing this afternoon whatever you use.

An Instruxi solution. Verified against Enforcer Governor v2.8.0 on 25 September 2026. Runs in Claude Code today; other harnesses are coming. Nothing leaves your machine until you sign in to an Enforcer workspace. Next: Install, Configure, Block dangerous commands. Enforcer, the identity and authorization service, is at enforcer.instruxi.dev.