Lesson 2 of 4 · 35 min

Budgets are part of control flow

Compute and enforce a budget before the next model or tool call.

An agent can keep searching because every result suggests another question. A useful controller turns the user's limits into stopping rules. Cost, elapsed time, token use, tool calls, and concurrency are separate resources. A task may be cheap but too slow, or fast but too expensive. Define the applicable limits before execution.
Track spent resources and reserved resources. Reservations matter when workers act in parallel. If three workers each inspect the same remaining balance and then spend it, a shared ceiling becomes meaningless. Reserve each worker's maximum allocation atomically before starting it. Return unused allocation when it finishes. The controller should refuse a new action whose worst-case reservation does not fit.
A stop condition should say what output is possible at the boundary. For example, a research task can return a partial table with clear gaps after its search limit. It must not present unchecked entries as complete. Set an escalation policy for high-value unresolved work. The model can recommend another search, but the application chooses whether there is budget and authorization to perform it.
Do not use a single estimated average as a hard guarantee. Model output length and tool runtime vary. Use maximum output limits, request deadlines, and bounded retries. Some remote charges may settle after a timeout, so an uncertain request retains its reservation until reconciled or accounted for conservatively. Track both estimated and billed consumption when available.

Worked example

A teaching agent has a 120-unit budget. It has spent 30 units. Worker A holds 25 units and worker B holds 20. The available balance is 120 minus 30 minus 25 minus 20, or 45 units. A proposed worker C needs at most 50, so it cannot start. A 40-unit version can start, leaving five units unreserved.
Worker A finishes after using 18. Its reservation converts to 18 spent and releases seven. Spent is now 48; reservations are 20 and 40; available is 12. This accounting prevents the coordinator from counting A's released budget twice. If C times out with uncertain billing, its reservation stays until the cost is resolved.

Exercise and solution

The total limit is 80 calls. Forty-one calls are complete, and two running workers hold reservations of 12 and 9. A new branch requests 20. Decide whether it can start, then update the balance if the first worker completes using eight calls.
Initially 18 calls remain unreserved, so the 20-call branch cannot start. After the first worker finishes, spent becomes 49 and the remaining reservation is nine. Available becomes 22, so the branch can start if the time limit also permits it. Award one point each for the initial calculation, refusal, reservation release, and checking the independent time limit.

Make reservations visible

A shared resource ceiling needs an inspectable ledger. This invented ledger uses abstract units, not a provider price.
EntryStateSpentReserved
CoordinatorComplete300
Worker ARunning025
Worker BRunning020
Available under 120 limitUnallocated045
The available row is derived, not an additional reservation. When worker A reports final usage of 18, one atomic update changes its state to complete, records 18 spent, and removes its 25 reservation. If separate updates release the reservation before recording the usage, another worker could spend the apparent free balance during the gap.
A completion message may be delivered twice, possibly with different delivery-event IDs. The ledger must settle each worker execution only once. Store a terminal settlement state keyed by worker execution, with the accepted usage and event references. A second notification returns that settlement when it agrees, or enters an explicit correction process when it conflicts. Event deduplication alone is insufficient because two distinct notifications can describe the same execution.
code
1reserve(execution_id, max_units):2    transaction:3        lock the shared budget row4        require execution_id has no reservation or settlement5        available = limit - spent_total - reserved_total6        require max_units <= available7        insert reservation(execution_id, max_units)8        increment reserved_total by max_units910settle(execution_id, actual_units, notification_id):11    transaction:12        lock the shared budget row13        lock the execution record in the same global lock order14        if execution is settled:15            return prior settlement or record a usage dispute16        if actual_units > reserved_units: freeze new admission and record overrun17        decrement reserved_total by this execution's reservation18        increment spent_total by actual_units19        mark execution settled with accepted usage20        retain notification_id as delivery evidence
The shared budget-row lock serializes reservation decisions across different workers. A transaction at Read Committed isolation without that shared lock or an equivalent conditional aggregate update can still overspend when workers read the same balance. The pseudocode omits lock timeouts, currency conversion, delayed provider billing, and cancellation. Those are production concerns. It prevents concurrent allocation or duplicate settlement from spending the same reserved units twice. A hard external-cost ceiling also requires enforceable per-call maxima; a reservation based only on average usage cannot guarantee it. If provider usage exceeds the reservation, record the actual consumption and the overrun, stop new admission, and reconcile the cause. Do not hide the charge to keep the displayed balance nonnegative. Negative remaining balance then describes a real overrun, not permission to continue spending.

A second worked case: token and time limits disagree

A task has 2,000 tokens of output budget left and 20 seconds before its deadline. A proposed call has a maximum output of 1,000 tokens but a 30-second timeout. It fits the token budget but cannot fit the requested time bound. The controller should choose a shorter bounded action, return the checked partial result, or ask for more time only where the workflow permits it.
The reverse case also matters. A call may finish in two seconds but consume the remaining token or monetary budget. Do not collapse all limits into one "small request" label. Track each resource in its own unit and enforce the intersection of the constraints.
A useful status explains which limit stopped progress. "Budget exhausted" is ambiguous when the user needs to decide whether more time, more money, or a narrower scope would help. The report can state that source retrieval is complete but synthesis stopped at the output cap, or that two vendors remain unchecked because the deadline arrived.

Misconceptions to reject

"Workers can each use the remaining balance" permits multiple workers to claim the same resource. Each worker needs a distinct reservation under an atomic shared decision.
"A timeout releases all cost immediately" ignores uncertain provider consumption. The request may still be billed or complete remotely. Keep conservative accounting until the contract supplies enough evidence to settle it.

Transfer exercise

Limit is 300 units. Spent is 120. Worker X reserves 80 and Y reserves 50. X completes at 60 units, but its completion event arrives twice. Determine the correct final available balance and explain the duplicate handling.
After one valid settlement, spent is 180 and Y still reserves 50, so 70 units are available. The second completion notification changes nothing, even if its delivery-event ID differs, because the execution is already settled. A system that releases X's reservation twice or adds usage twice corrupts the ledger. Award one point for the arithmetic, one for atomic conversion, one for the terminal settlement keyed by execution, and one for treating provider billing corrections as separate reconciled events rather than replaying the original settlement.

Interview probe

Original practice: Why can a budget check fail under parallel execution? A strong answer shows two workers spending the same available balance and proposes atomic reservations. Follow up with uncertain billing after a timeout. A weak answer gives each worker the full remaining budget.

Sources

  1. 01Anthropic: building effective agents
  2. 02Anthropic: long-running agent systems
  3. 03PostgreSQL: transaction isolation supports the stated Read Committed boundary. The budget schema and arithmetic are original teaching designs.
docsAnthropic: building effective agentsanthropic.comdocsAnthropic: long-running agent systemsanthropic.comdocsPostgreSQL: transaction isolationpostgresql.org

Checkpoint

Limit 120, spent 30, reserved 25 and 20. Available?

A90B70C45D65
Sign up free to answer and see why

Checkpoint

Two workers reserve from the same budget under Read Committed transactions. What additional mechanism protects the shared ceiling?

AIndependent transactions that lock only each worker's own new row.BA shared budget-row lock or an equivalent conditional atomic update of the aggregate balance.CA completion notification sent after both reservations.DReading the balance twice without a write condition.
Sign up free to answer and see why

Checkpoint

Two different notification IDs report completion of the same worker execution. What should settlement use as its once-only boundary?

ANotification ID only.BWorker execution's terminal settlement state, with notification IDs retained as evidence.CCurrent wall-clock second.DThe amount alone, ignoring execution identity.
Sign up free to answer and see why

Checkpoint

The task deadline is reached. An agent has checked two suppliers, but the required third supplier's source is unavailable. The user has not extended the deadline. What result should it return?

AThe checked comparison sections with their sources, the missing third supplier and its effect on the decision, and an explicit incomplete status.BA complete three-supplier recommendation, filling the missing section from a plausible estimate.CA complete two-supplier recommendation without saying the required comparison was narrower.DNo useful evidence, because any missing section invalidates every completed source check.
Sign up free to answer and see why

Checkpoint

A worker times out with uncertain billed usage. What is the valid accounting response?

ACharge zero because no response arrived.BAllocate the reservation to another worker before settlement.CRelease all reserved usage immediately.DRetain or conservatively settle the uncertain usage until evidence permits reconciliation.
Sign up free to answer and see why

Explain how you would settle duplicate worker usage reports without violating a shared resource ceiling. Name the record that justifies each transition. Rate confidence from 1 to 5 and state the unresolved boundary.

Not yetGetting thereConfident

Wrap-up

  • Enforce resource limits in the controller. Reserve before parallel work and return honest partial results when a limit stops the task.

Sources

Free to read · better with Enzo

Learn it with Enzo

Save your progress, answer the checkpoints, and let Enzo quiz you on what you just read.