Catching the Prompt That Silently Grew Fivefold: A Pre-Send Token Budget Check on One Key
A practical guide to building a local token-count guard that estimates every assembled prompt before it is sent to a multi-model API aggregator, so runaway context concatenation surfaces as a warning instead of an unexpected USDC charge. Covers where prompt bloat comes from, how to place a pre-send check, how to combine token counting with your own price bookkeeping, and how to tune warnings and blocks without getting in the way of legitimate work.
Why a Pre-Send Check Matters
When you call many models through one API key, every request is billed by tokens. A prompt that quietly triples or quintuples in size still returns a perfectly normal-looking answer, so the first signal is often the balance movement, not the output. Because you pay official price × 1.3, a bloated prompt costs proportionally more than the same bloat on a bare provider API. A local count before the request leaves your process turns that surprise into a warning you can read in a log or terminal.
The goal is not to block all large prompts. It is to make prompt size an explicit, visible decision rather than an accident of string concatenation.
Where Prompts Silently Grow
Most runaway prompts come from a few repeatable patterns:
- History accumulation. You append every turn to a message list and never trim or summarise older turns.
- Retrieved context stacking. A retrieval step returns chunks and you concatenate all of them, even when several are near-duplicates or off-topic.
- Loop concatenation. An agent retries, and each retry appends the previous attempt, the error, and the new instruction.
- Template drift. A shared prompt template gains sections over time, and callers inherit them without noticing.
- Tool output passthrough. A tool returns a large JSON or log blob that gets embedded verbatim.
Each of these is cheap to detect if you measure the final assembled string or message list just before sending.
Placement: One Choke Point
The check is only reliable if it runs at a single choke point. If you call the aggregator from several places, wrap them in one client function and run the guard inside it.
A workable order of operations:
- Assemble the final request (model, messages, system prompt, tools).
- Estimate input tokens locally.
- Compare against a budget you define per call site.
- Warn, truncate, or refuse, then send or return an error.
- Log the estimate alongside the response so you can calibrate later.
Doing this after assembly, not during, is important: it captures everything that actually ships.
Estimating Tokens Without Inventing Numbers
You do not need exact tokenisation to catch a fivefold jump. You need a consistent estimator that correlates well with real counts and runs fast.
- Use a tokeniser library when one is available for the model family you target. It is the most faithful local option.
- Use a calibrated heuristic otherwise, such as character count divided by a factor, adjusted by language and content type.
- Count each message's role and structure, not just the text, since message framing is billed too.
- Account for tool and schema definitions if they are included in the request.
Whatever you choose, keep the estimator stable. A change in the estimator invalidates your historical baselines. Treat the estimate as a relative signal, not a billing-grade figure.
Turning Size Into Money Awareness
The strongest guard is one that speaks in the units you actually spend. Combine the token estimate with your own price reference to show an upper-bound cost per call, then express it against your running budget.
- Maintain a small local table of per-model input and output rates based on the aggregator's published official prices.
- Multiply by 1.3 to reflect what you pay, so warnings read in USDC terms you recognise.
- Show the estimate, the multiplier-adjusted cost, and the remaining balance side by side.
This keeps the guard honest: it does not claim to know your exact invoice, only to surface the order of magnitude before you commit.
Tuning: Warn First, Block Later
A guard that fires on every request gets disabled within a day. Start permissive and tighten based on logs.
- Set a soft threshold at your typical prompt size plus headroom; log a warning when crossed.
- Set a hard threshold for obviously pathological sizes; refuse or require an explicit override flag.
- Track a rolling baseline per call site, since a chat endpoint and a batch summariser have different norms.
- Alert on change, not just absolute size. A prompt that doubles against its own recent median is more interesting than one that is simply large.
- Record the estimator version with each log line so threshold drift is explainable.
If a call is legitimately large, allow it with an explicit opt-in so the decision stays visible.
Reducing Size Instead of Refusing
When the check trips, you often have cheaper options than failing the request:
- Trim or summarise older conversation turns.
- Deduplicate retrieved chunks and drop low-relevance ones.
- Replace large tool output with a compact digest plus a pointer to the full data.
- Move stable instructions to a shorter system prompt.
- Split a batch job into smaller calls.
Each of these keeps the workflow moving while keeping the prompt within the budget you set.
Calibration and Review
Because local estimates are approximate, close the loop periodically. Sample real responses, compare the local estimate with actual usage reported by the aggregator, and adjust your heuristic or tokeniser choice. Keep the calibration review manual and infrequent; the guard's job is early warning, not precision accounting.
Where Contributor Economics Fit In
If you also publish prompts, tools, or integrations that others use through the same key, note that key contributors are credited official price × 1.1 (premium × 1.2) in USDC. A pre-send guard benefits that setup too: well-behaved callers keep prompts lean, which keeps shared budgets predictable and keeps contributor credits from being consumed by avoidable context bloat.