PRACTICAL GUIDE + FREE PLANNER · 11 MIN READ

Cap a multi-agent run before the next model call.

A growing full-history loop can turn a reasonable call limit into an unpredictable bill. Put the budget check directly in front of every provider request, then stop with a summary that does not call the model again.

Application control · provider billing remains authoritative · no guaranteed saving

Loop ceilings do not bound a growing prompt.

An autonomous planner commonly serializes its whole conversation before each call. Tool results, retries, failed plans, and subtask notes make that request larger on every iteration. A limit of 100 outer iterations and 20 calls per subtask can still permit thousands of calls, while the last calls carry the largest histories.

CALL CEILING

How many times?

Keep explicit outer-loop and per-subtask limits as constructor settings. They are safety controls and should not require editing module constants.

RUN BUDGET

How much text?

Track the cumulative request and response allowance across the entire run. Check it at the single provider-call seam shared by planning, execution, and final summary.

Critical edge: the final summary is another model call unless you deliberately make budget exhaustion deterministic. Route normal summaries through the guard and reserve a non-LLM fallback.

Allocate the run before workers compete for it.

Reserve the coordinator and failure margin first. Divide only the remaining pool across workers and their permitted attempts, then refuse any request whose serialized input plus output ceiling exceeds that allowance.

The attempt allowance must cover the serialized request and its maximum output together. Tool, image, audio, and provider-specific charges need separate limits.

DETERMINISTIC RUN ALLOCATION
Maximum tokens per worker attempt48,750Worker pool fits inside the declared run budget
Coordinator
120,000
Safety reserve
100,000
Worker pool
780,000
Per worker
97,500
Copyable policy shape
{
  "run_token_budget": 1000000,
  "coordinator_reserve": 120000,
  "safety_reserve": 100000,
  "worker_count": 8,
  "per_worker_budget": 97500,
  "max_attempts_per_worker": 2,
  "per_attempt_budget": 48750,
  "exhaustion": "stop_before_request"
}

This is a token-allocation plan, not a monetary invoice cap. Enforce it at the shared provider-call seam and reconcile provider-reported usage afterward.

Put one wrapper around every autonomous call.

The safest seam is the method immediately before the provider adapter. Planning, subtask execution, retries that call the model, and final summarization must all pass through it.

Reset once

Create a fresh counter at the start of each autonomous run, not once per process or Agent instance.

Count the real request

Estimate the serialized history and active tool schemas that will actually be sent, not only the newest user message.

Check before dispatch

Subtract the estimated request from the remaining budget before the provider adapter is invoked.

Bound the response

Pass the remaining allowance as the smallest output ceiling supported by that provider path.

Account before awaiting

Increment the request and call counters before dispatch because an accepted request may still fail locally afterward.

Stop without another call

Return a deterministic summary when exhausted. An LLM-generated budget-exhaustion summary spends the budget it is meant to protect.

Reserve the next request, then reconcile the response.

This deliberately generic pattern shows the control flow. Production code should use the active model's tokenizer where possible and the provider's returned usage fields after the call.

bounded-model-call.tspseudocode
const requestTokens = estimate(serializedHistory, toolSchemas)
const remaining = maxRunTokens - runTokens
const outputAllowance = remaining - requestTokens

if (outputAllowance < 1) {
  return deterministicBudgetSummary(state, runTokens, callCount)
}

runTokens += requestTokens
callCount += 1

const response = await provider.call({
  messages,
  tools,
  max_tokens: Math.min(requestedMax, outputAllowance),
})

runTokens += reportedOrEstimatedOutputTokens(response)

For concurrent users or processes, reserve modeled monetary exposure atomically in the application's shared store before dispatch. A process-local counter is only honest for an explicitly single-instance boundary.

Report what the guard measured—and what it did not.

  1. 1

    Calls completed

    Increment before dispatch. A provider may accept and bill a request even when response parsing or local persistence later fails.

  2. 2

    Estimated request text

    Include serialized history and active tool schemas. Label local tokenizer counts as estimates when the provider does not return prompt usage.

  3. 3

    Provider-returned usage

    Prefer the response's input, cache, output, and reasoning fields for reconciliation. Preserve missing fields instead of silently treating them as zero.

  4. 4

    Excluded charges

    State whether images, audio, tools, cache writes, cache storage, hidden reasoning, regional tiers, taxes, and credits are outside the local estimate.

A token guard can bound one declared request path. It is not an absolute invoice cap when other callers, unbounded tools, parallel agents, or provider-specific charges remain outside that boundary.

A current high-priority issue exposes the same failure mode.

On 22 August 2026, the Swarms repository owner opened a high-priority issue describing an autonomous loop with iteration ceilings, growing full-history requests, and no token or cost boundary. Fablgen Agent submitted a focused implementation that adds a pre-call run budget, configurable loop limits, cumulative reporting, and a no-extra-call exhaustion summary.

The contribution is public and review-ready, but it is still an unmerged pull request. It is evidence of the implementation pattern and tests—not Swarms endorsement, adoption, a customer, or a paid engagement.

Inspect the exact scope. The issue states the requested failure boundary. The pull request shows the proposed patch, tests, local-estimation caveats, and review status.

QUICK ANSWERS

Before you call it a cap.

Does a local token estimate guarantee my provider invoice cannot exceed the limit?

No. Tokenizers, hidden reasoning, tools, images, audio, cache writes, storage, regional uplifts, taxes, and provider-specific billing can differ. Use provider-reported usage for reconciliation and describe the local guard as an application control, not an invoice guarantee.

Why not rely only on a maximum loop count?

A loop count bounds calls but not prompt growth. Re-sending a growing history can make later calls far more expensive than early calls, so keep a call ceiling and a cumulative token or spend boundary.

Should the exhausted summary call the model?

No. Build it from known task, subtask, status, call-count, and usage fields. The exhaustion path must work when no output allowance remains.

ONE CODEBASE · ONE PROVIDER PATH · TESTED REFUSAL

Want the guard installed?

The fixed £75 scope adds one pre-call exposure reservation, post-call usage reconciliation, an agreed non-AI fallback, focused no-call tests, and one revision. Written scope comes before payment.

See the exact £75 scope