Tool Loop: When Your Agent Can't Stop Calling the Same Tool
The runaway agent failure that burns tokens, triggers rate limits, and produces no output. How tool loops form, how to detect them in traces, and the circuit-breaker patterns that stop them.
The agent had one job: find the current stock price of AAPL and write a one-sentence summary. It ran for 47 minutes, made 312 tool calls, and returned nothing. The on-call engineer found it by noticing the rate limit alerts.
Tool loops are one of the most common agentic failure modes in production. The agent enters a cycle of calling the same tool (or a small set of tools) repeatedly, never making progress, until it hits a token limit, a rate limit, or a timeout. Unlike crashes, tool loops produce no error — just silence and a mounting bill.
How tool loops form
Tool loops form when an agent's observation from a tool call doesn't resolve its current goal, and the model decides the right next action is to try the same tool again with slightly different arguments. Three conditions create this:
- The tool returns an ambiguous or empty result that doesn't signal failure clearly
- The model has no explicit 'give up' or 'I cannot complete this' action available
- The system prompt or task description is phrased in a way that makes the model feel it must produce an answer (e.g. 'always return a stock price')
The loop often looks like progress from outside. The model varies its search terms slightly on each call. It might call a search tool, then a web-fetch tool on the results, then a search tool again because the fetched page didn't have what it wanted. Each step is individually reasonable; the emergent behavior is a spiral.
A real trace, annotated
Step 1: search_web("AAPL stock price today") → [{title: "Apple Inc. (AAPL) Stock Quote", url: "..."}]
Step 2: fetch_url("https://finance.yahoo.com/quote/AAPL") → "Please enable JavaScript to view this page"
Step 3: search_web("AAPL stock price site:marketwatch.com") → [{title: "AAPL - Apple Inc.", url: "..."}]
Step 4: fetch_url("https://www.marketwatch.com/investing/stock/aapl") → "Your request was blocked"
Step 5: search_web("what is apple stock price right now 2024") → same results as step 1
Step 6: fetch_url(...) → blocked again
...
Step 312: search_web("AAPL stock price current value") → timeout
The problem here isn't the agent's reasoning — each individual step is defensible. The problem is that the system gave the agent tools that don't work (JS-rendered pages, bot-blocked sites) and no mechanism to recognize or recover from that.
Circuit breaker patterns
You can't rely on the model to self-terminate a loop reliably. The defense must be at the infrastructure layer:
- Step limit: hard cap on the number of tool calls per task (typically 20-50 depending on task complexity). Return an error when the limit is hit — don't silently truncate.
- Repetition detector: maintain a hash of (tool_name, args) for each step. If the same call appears more than N times (typically 2-3), abort with a loop detection error.
- Progress assertion: after every K steps (e.g. 5), check whether the agent has produced any new unique observations. If the last K observations are semantically identical, abort.
- Explicit give-up tool: add a `cannot_complete(reason: string)` tool to every agent's toolkit. Instruct the model in the system prompt to use it when progress is blocked. Models are much better at stopping when given a legitimate exit path.
- Time budget: wall-clock timeout separate from the step limit. Essential for catching slow-loop patterns where each step takes a long time.
The cheapest circuit breaker is the repetition detector — it adds microseconds of overhead and catches 90% of tool loops. Implement it first.
System prompt design to reduce loops
Loop frequency drops significantly with two system prompt changes: (1) give the agent explicit permission to fail ('If you cannot find the information after 3 searches, report that the information is unavailable'); (2) give a time/step budget ('You have up to 10 steps to complete this task'). Models respond to explicit constraints in ways that implicit behavioral expectations don't achieve.
Simulate tool loops →: Use the Agents Lab to reproduce and fix a tool loop.
Try it interactively
GenAI Systems Lab is a free platform for AI engineers — configure real failure modes, break things, and build the judgment that gets you hired.
Open GenAI Systems Lab →