Security

Detecting Agent Loops Before They Burn Budget

Antonio Evans10 min read

A dark-themed dashboard showing a trace timeline with a series of identical tool calls highlighted in red, and a circuit breaker switch flipping to 'open' state.
Key points

Key points

  1. 1An agent loop is a control flow failure, not a model failure: the harness keeps feeding new prompts, tool results or handoffs back into the model without a bound that actually terminates the path.
  2. 2The highest-value rule is fingerprinting tool calls by name plus canonicalized arguments and blocking the third identical call inside a sliding window, which is the debounce pattern demonstrated with lifecycle hooks in Strands Agents.
  3. 3Layer three independent ceilings (wall-clock, step count and token or dollar budget) because each one has a blind spot the others cover.
  4. 4Treat a tripped breaker as an operational incident with a runbook and an owner, not a silent error, and rehearse the trigger path with a tabletop exercise before you need it.

What an agent loop actually is, and why it hides from your dashboards

An agent turn is not a single model call. The harness assembles context, invokes the model, executes whatever tool the model picked, appends the observation to context and repeats until a stop condition fires, as described in Oracle's breakdown of the agent loop. Most agent engineering happens in that harness, not in the model, which is exactly where loop detection belongs.

The failure mode has a name in the research literature. Hou, Wang, Zhao and Wang define an Infinite Agentic Loop as a feedback path that repeatedly triggers model calls, tool invocations or workflow transitions without an effective termination condition, and they note that framework limits such as LangChain's max_iterations or LangGraph's recursion limits are often omitted, misconfigured or placed outside the actual feedback path (the IAL paper). Their static analyzer scanned 6,549 agent repositories and confirmed 68 loop failures across 47 projects.

The reason your APM dashboard does not catch this is economic, not technical. A loop looks like fifty successful HTTP 200 responses from a model API. The cost model changes from linear to exponential once each step carries the accumulated context of every prior step, which is why an analysis of LLM cost control argues that cost per task, not latency, is the metric that matters for agents. That same analysis cites a community-reported incident in which a coding agent's recursion loop consumed roughly 1.67 billion tokens in about five hours.

Two distinct failure modes get conflated, and they need different defenses:

Failure modeWhat happensWhere to intercept
Retry stormA tool call fails, the harness retries the same call with backoffYour HTTP or tool client layer
Reasoning loopThe agent re-plans around an error and calls the same tool with near-identical argumentsThe orchestrator, before tool execution
Handoff cycleAgent A delegates to agent B, which delegates back to AThe multi-agent router

Infrastructure-level circuit breakers see the first one. They cannot see the second, because the retries happen inside the model's reasoning: the agent reads "timeout" as "try a different approach," as a practitioner guide on agent timeouts and circuit breakers puts it. Detection has to live in the harness, where you can inspect the tool name and arguments before the call executes.

Rule 1: fingerprint tool calls and block the third duplicate

The cheapest reliable signal is the (tool name, canonicalized arguments) tuple. Canonicalization matters: {"city": "Oslo", "units": "metric"} and {"units": "metric", "city": "Oslo"} are the same intent and should hash the same. Sort keys, normalize whitespace and casing on string values, drop volatile fields such as request IDs or timestamps that the harness injects.

The Strands Agents loop-prevention demo implements this as a debounce hook on BeforeToolCallEvent, tracking the last three calls and cancelling the execution when the same fingerprint appears twice in that window. Their controlled comparison is the insight worth copying: with an ambiguous tool that ended its response with "more results may be available," the agent made 14 calls; with a tool that returned an explicit terminal state, it stopped in 2. The loop was caused by the tool's wording, not the model's stubbornness.

Here is the pattern written framework-agnostically, as a check that runs before any tool executes:

import hashlib, json
from collections import deque

def fingerprint(name, args):
    canon = json.dumps(args, sort_keys=True, separators=(",", ":"))
    return hashlib.sha256(f"{name}|{canon}".encode()).hexdigest()

class LoopBreaker:
    def __init__(self, window=6, max_repeats=2):
        self.history = deque(maxlen=window)
        self.max_repeats = max_repeats

    def check(self, name, args):
        fp = fingerprint(name, args)
        if self.history.count(fp) >= self.max_repeats:
            return {"allow": False, "reason": "duplicate_fingerprint",
                    "fingerprint": fp[:12], "call": name}
        self.history.append(fp)
        return {"allow": True}

Choosing the thresholds is a decision rule, not a guess. Set max_repeats to 2 (block the third identical call) for read-only tools, where repeat calls are almost always wasted. Raise it to 3 or 4 for idempotent write tools with eventual consistency, where a second read is legitimately needed to confirm state. If you find yourself wanting more than 4, the real fix is usually the tool's response text: return explicit success or failure states instead of hints that "more data may be available."

Also decide what the block returns to the model. Return a terminal-looking message, not a soft error. "BLOCKED: duplicate call detected, the previous result is authoritative, choose a different action or finish" is more effective than "rate limited, retry later," which invites a retry.

Rule 2: three independent ceilings, because each has a blind spot

A single loop detector will miss cases. A wall-clock deadline cannot tell a hard task from a stuck one: a legitimate ten-step workflow might need five minutes while a runaway loop spends serious money in three. A step counter misses an agent that stays under the step limit while each step carries a 200,000-token context. A token budget misses a hung process that consumes nothing but holds a downstream queue hostage. The same circuit-breaker guide recommends running all three together.

A practical configuration, expressed as starting points to tune per workflow:

ControlStarting valueCatchesBlind spot
Wall-clock deadline5 minutes per workflow runHung tool calls, dead socketsCannot distinguish hard work from a loop
Step ceiling25 model or tool invocationsReasoning loops that make progress-shaped callsExpensive individual steps
Token budget500,000 tokens per runContext bloat on each stepSlow loops that trickle tokens
Dollar breakerSet per session, below your incident thresholdAnything the token count missedDelayed by your cost accounting lag
Duplicate fingerprintThird identical call in 6Tight reasoning loopsLoops that vary arguments slightly

The dollar breaker is the backstop and should sit at the layer where you already count spend. The token-tracing walkthrough shows the mechanics: tag every model call span with input and output token counts plus a computed cost, increment a per-session counter in a fast store like Redis, and check that counter before each model call. The pattern generalizes regardless of which model or provider you use, which matters if you route different tasks to different providers.

One number worth internalizing from the same source: if step 1 costs $0.002 and the context grows linearly, step 50 at 50,000 tokens can cost roughly $0.625 on its own. The bill is not fifty times the first step; it is closer to the sum of an arithmetic series, and a loop multiplies that by however many iterations it survives.

Rule 3: read the trace, not the error log

Loops rarely produce errors, so your error-based alerting stays quiet. What they produce is repetition in the trace, and that is what to query. This is the monitoring lesson from Google's SRE chapter: alert on what users and budgets actually experience (symptoms), not on every internal counter (causes). A five-minute stretch where one agent emits forty tool spans and no final response is a symptom-level signal.

A trace excerpt from a loop looks like this once the spans are flattened:

span  tool            args_hash   tokens_in  cost_usd  elapsed_ms
2811  search_listings 9f2ac1      4,210      0.006     410
2812  search_listings 9f2ac1      4,980      0.007     388
2813  search_listings 9f2ac1      5,750      0.008     402   <- blocked by fingerprint rule
2814  search_listings 3b81de      6,520      0.009     431   <- slightly different args, slipped through
2815  search_listings 3b81de      7,300      0.010     395
2816  search_listings 3b81de      8,090      0.011     418   <- step ceiling trips here

Two things to notice. First, the exact-duplicate rule caught 2813, but the agent re-planned with slightly different arguments and produced a second fingerprint cluster. That is the reasoning-loop behavior no client-side breaker sees. Second, tokens in grow every call, which is the context bloat signature. A single query for "tool spans per workflow with no final-response span in the same trace" surfaces this pattern across your fleet.

The Drata guide to agent governance frames the same point from the compliance side: most executives report lacking complete visibility into agent tool usage and data access, and agent behavior can shift between one day's review and the next day's incident. Logs that capture tool name, canonicalized arguments, token counts and outcome per span are the minimum evidence you need to answer "what did this agent actually do."

For triage, the AgentCenter guide to triaging agent failures draws a useful distinction: stuck or looping failures are sneaky precisely because nothing flags them automatically, whereas crashes are loud. That argues for a dedicated loop alert rather than expecting your crash alerts to cover it. Their priority matrix is worth borrowing wholesale: blocking other agents, corrupting output or customer-facing puts a failure at the top of the queue; auto-recovering failures can be monitored.

Failing safe: what the breaker should do when it trips

Halting silently is a bad outcome, and so is retrying. A tripped breaker is an incident, and it should follow the same structure you already use for security incidents. Fortinet's guide to incident response documents separates three artifacts that map cleanly onto agent loops: a policy that sets the rules (what the breaker enforces, who owns it), a plan that covers detection through recovery, and playbooks for specific scenarios. Your loop preemption is the detection event; the playbook says what happens next.

A workable escalation ladder for a tripped breaker:

  1. Halt the workflow and persist partial state, including the fingerprint history, so the loop is reproducible.
  2. Return a structured failure to the calling system, not a generic 500. Include the rule that fired, the fingerprint and the step count.
  3. Notify the workflow owner. If the agent is customer-facing, notify through your normal channel rather than automated retry logic.
  4. Route the trace to a human reviewer. The fix is usually a tool-response wording change, a prompt stop criterion, or a missing success state, all of which need a person.
  5. Add the exact fingerprint or the argument pattern to a regression test so the same loop cannot ship again.

Deciding who gets paged is the part teams skip. On-call design guidance is consistent that escalation policies must not dead-end: an unacknowledged alert that nobody owns is a silent failure. The escalation policy guide makes the case that written rules remove hesitation and catch silence, and notes that a large share of major outages trace back to procedures that were ignored or badly written. The on-call best practices guide adds the sustainability angle: repeated high-pressure pages without recovery time are a burnout driver, which is why a loop alert should page once with a clear owner, not fire on every blocked call. If your agent platform spans many providers, routing those alerts from a single ingestion point is the natural move, and Quanta Inference exposes text, image, video, audio and embedding models behind one API key so token and cost accounting lives in one place.

Rehearse the loop before it happens to you

The trigger path is easy to leave untested until production finds it. Fix that the way security teams fix theirs: run a tabletop exercise. CISA's tabletop exercise packages are free, customizable templates with scenarios and discussion questions, and the Bitsight definition describes the format: a discussion-based simulation of an incident, no systems touched, focused on decisions and communication rather than hands-on action. Sophos's guidelines give concrete shapes: rapid-fire scenarios run 10 to 30 minutes, technical-only scenarios run one to two hours with a seed event that you deepen as the scenario unfolds.

Write one scenario for a reasoning loop and walk the team through it: the fingerprint rule fires at step 40, the workflow owner is asleep, the customer-facing agent is stuck mid-checkout. Who kills the workflow? Who tells the customer? What is the rollback if the loop already wrote partial data? The AlertMedia template walkthrough notes that organizations which had rehearsed kept operating during real incidents, including a healthcare network that ran on paper backups through a ransomware event. A dry run of your breaker path is cheap; discovering the breaker has no owner at 3 AM is not.

The Google Cloud symptoms-over-causes essay supplies the design principle for the exercise itself: build automation that handles the predictable failure, and keep alerting for the cases that need a human. The loop fingerprint rule is automation. The escalation to the owner is the human case. Keep them separate and your alert volume stays sane.

A deployment checklist

Before you ship loop detection, confirm each line has an owner and a test:

  • Every tool call passes through a single chokepoint where the fingerprint check runs. If tools are registered in three places, the rule will miss one.
  • Tool responses return explicit terminal states. Search your tool code for phrases like "more results may be available" and rewrite them; the Strands demo shows that wording alone caused a 14-call loop.
  • Wall-clock, step and token ceilings are set per workflow type, not globally, and the values are documented next to the workflow.
  • The dollar breaker reads a counter that updates on every model call, with the lag measured. A breaker that reacts an hour late is a reporting tool, not a breaker.
  • Traces carry tool name, canonicalized argument hash, token counts and outcome per span, so the "spans without a final response" query returns results.
  • A tripped breaker produces a named incident with an owner and a persisted partial state.
  • One tabletop exercise per quarter covers the reasoning-loop scenario, following the CISA package structure.
  • The fingerprint history for each incident is added to a regression suite, so a fix is verified, not hoped for.

If you are weighing which tools or models get to run your agents at all, the decision rule is to pick a harness that exposes a pre-tool-execution hook. Frameworks without one force you to wrap each tool individually, which is where coverage gaps creep in, as the IAL paper observes: the termination mechanisms exist in most frameworks, but they are omitted or placed outside the feedback path. If your team needs help wiring the breaker into a multi-agent setup or standardizing the trace schema, a free 30-minute discovery call is a low-cost way to get a tailored recommendation before you build.

FAQ

FAQ

How many repeated tool calls should trigger the breaker?

Block the third identical call in a sliding window of about six for read-only tools, and allow up to four repeats for idempotent write tools where confirming state is legitimate. The exact-duplicate rule tuned this way is the one demonstrated in the Strands loop demo. If you need a higher threshold, suspect the tool's response wording before raising the limit.

Why did my loop detector miss the loop?

Most misses come from the agent re-planning with slightly different arguments, which produces a new fingerprint and resets the duplicate count. That is the reasoning-loop behavior described in the circuit-breaker guide. Catch it with the step and token ceilings layered on top of the fingerprint rule, and alert on traces with many tool spans and no final response.

Is a step limit enough on its own?

No. A step limit misses expensive individual steps where each call carries a huge context, and a wall-clock limit misses loops that finish quickly but repeat many times. Run wall-clock, step and token ceilings together, as the same guide recommends. The dollar breaker is the backstop when cost accounting for all three is in place.

What should the agent receive when the breaker trips?

A terminal-looking message that names the block and tells the model the previous result is authoritative, plus an instruction to finish or choose a different action. Soft errors that suggest retrying later invite another cycle. Then escalate to the workflow owner, following the escalation guidance that unacknowledged alerts must not dead-end.

How do we prove to auditors or leadership that agents stay in bounds?

Capture per-span evidence: tool name, canonicalized arguments, token counts, cost and outcome, plus the fingerprint history for any preempted run. The Drata governance guide notes that continuous verification, not periodic review, is the standard, and that most leaders currently lack that visibility. Rehearsing the preemption path with a CISA-style tabletop gives you a documented answer to "what happens when it fires."

Sources

Sources

  1. The Agent Loop Decoded | developers
  2. Uncovering Infinite Agentic Loops in LLM Agents
  3. AI Agents Don't Crash, They Spend: LLM Cost Control - sanj.dev
  4. AI Agent Timeout & Circuit Breaker Patterns | 2026 Guide
  5. How to Prevent AI Agent Reasoning Loops from Wasting ...
  6. Chapter 6 - Monitoring Distributed Systems
  7. Are Your AI Agents Behaving as Expected? Here's How to Know for ...
  8. How to Triage AI Agent Failures by Priority | AgentCenter
  9. A Guide to Incident Response Plans, Playbooks, and Policy - Fortinet
  10. On-Call Rotation and Escalation Policy Guide
  11. On-call best practices: handoffs, schedules, and alert fatigue
  12. CISA Tabletop Exercise Packages
  13. What is a Tabletop Exercise in Cybersecurity? - Bitsight
  14. Security Tabletop Exercises - Sophos Trust Center
  15. Cybersecurity Tabletop Exercise Template & Scenarios - AlertMedia
  16. Why Focus on Symptoms, Not Causes?
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles