Build1 publisher3 min readPublished
Retries inflated one agent turn to 47,004 input tokens for a 280-token answer
A hosted-skills agent that let the model call four tools in whatever order it liked pushed a single webshop question past the context window of a frontier model. The fix was to gather the evidence in code first.
The Engineer · Build desk

What happened
- A scam-checking agent for webshops was built on Azure Functions hosted skills with four tool functions, and the .agent.md instructions left the model to call check_domain, check_website, check_archive_history and web_search itself.
- The first version returned "Model deployment rate limit exceeded" on gpt-4.1, then the same error after a move to gpt-5.6-terra.
- Raising the deployment capacity to 500K TPM produced a new failure instead: "Your input exceeds the context window of this model."
- An agent_token_usage event in Application Insights recorded one turn at 47,004 input tokens and 280 output tokens.
- The web_search tool returned an error when no Tavily key was configured, so the model retried with a different query and carried the failed attempt into every later turn.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint Whoever writes the agent instructions owns the token bill, because tool code cannot cap how many round trips the model decides to take.
- exposure The TPM ceiling is bought per deployment, so a single retry-heavy conversation consumes throughput that every other caller of the same skill needs.
- decision Tool authors now have a concrete reason to pick between raising an error and returning a structured unavailable value, since only one of those ends the loop.
A tool call inside a hosted skill is not a cheap local function call. Each one is a full model round trip that carries the system prompt, the tool schemas, the chat history, and every tool result that came before it [7]. Call four tools in sequence and the fourth call pays for the first three results plus everything already sitting in the thread [3][7]. Steef-Jan Wiggers, who wrote the post [21], put the diagnosis plainly: "Not one line of my tool code was wrong," he wrote [10].
One turn spent about 168 input tokens for every token it produced [17]. At that input size, a 500K TPM deployment covers roughly ten turns a minute for the whole application: 500,000 divided by 47,004 is 10.6 [18]. Raising capacity bought a different error message [5].
The evidence the agent needs is cheap and deterministic. RDAP returns a domain's registration date, registrar and age; a direct HTTPS fetch confirms the site is reachable and checks whether it links contact, about, terms, privacy and returns pages; the Internet Archive CDX API shows when the site first appeared and whether its history is continuous [12]. The RDAP helper is an httpx GET against rdap.org with a 15 second timeout that returns registered false on a 404 [16]. "Nothing clever, which is the point," Wiggers wrote [19].
Reputation was the part that could not be gathered without a key. The Trustpilot content API needs a paid business account and scraping review sites violates their terms, so the second tier runs Tavily searches against site:trustpilot.com, the business name plus "reviews", and the business name plus "scam OR fraud OR oplichting" for Dutch shops [15][13]. The model sees result titles, URLs and snippets, and never invents a rating [13].
When no key is configured, that tier reports itself unavailable and the agent says so in its verdict; graceful degradation was a design goal [14]. That choice is what keeps a missing key from becoming a quota incident. An error return invites another attempt; an unavailable field is data the model can report and move past [9][14].
For the 47,004 to transfer to your project, two things about this setup have to hold on yours. The runtime keeps the thread for you, so failed turns and retries stay in it [8]. And at least one tool has to fail in a way the model reads as worth retrying [9]. The redesign the post lands on is one sentence: a single deterministic tool gathers every signal, under the pattern Wiggers calls "evidence in code, judgment in the model" [11]. The account stops there, with no agent_token_usage line for the rewritten version [20].
What to watch
- Whether the renamed hosted skills runtime ships a default per-thread trim or turn cap, given the built-in chat UI keeps failed turns.
- Whether other samples on gpt-5.6-terra keep hitting deployment rate limits at 500K TPM.
- Whether the legit-check-agent deterministic tool degrades cleanly when RDAP or the Internet Archive CDX API is slow or down.