DEV Community

Jason Shotwell
Jason Shotwell

Posted on

I stopped two AI agents from looping forever, in two lines

If you have run a multi-agent setup, you have probably watched this happen. Two agents get into a loop. One proposes, the other critiques, the first revises, the second critiques again, and they never agree. Every round is a real model call. The loop does not end on its own, and the bill does not stop either.

I wanted a dead-simple, deterministic way to stop that, without rewriting my agent or trusting the models to know when to quit. So I built Tombstone, an open-source guard you wrap around an agent's tools. Here is the whole integration:

from tombstone.easy import Tombstone

tb = Tombstone(budget=6)      # cost ceiling: 6 tool calls
tools = tb.guard_all(tools)    # wrap your tools
Enter fullscreen mode Exit fullscreen mode

That is it. Now the agent cannot exceed the budget, cannot loop on the same call, and (if you pass protect=[...]) cannot delete or overwrite protected data. Every decision is written to a tamper-evident ledger you can verify.

The runaway, for real

To make sure this was not a toy, I wired up two actual Claude agents. A Builder proposes a product tagline. A Reviewer is told to always find one more flaw and never fully approve. Left alone, they loop forever. Here is a real run:

[round 1] Builder: Capture your thoughts before they disappear.
[round 2] Reviewer: The tagline leans too heavily on fear rather than the benefit. Reframe around what users gain.
[round 3] Builder: Your ideas, organized and always at hand.
[round 4] Reviewer: 'Always at hand' is vague. Clarify what problem this solves that other note apps do not.
[round 5] Builder: Transform scattered thoughts into your personal knowledge system.
[round 6] Reviewer: 'Personal knowledge system' is too jargon-heavy for people who just want a simple note app.

[KILLED] runaway stopped at round 7
         step budget exceeded (7 > 6): possible runaway
Enter fullscreen mode Exit fullscreen mode

The Reviewer never gives up. Tombstone does not read the conversation or judge that it went sideways. It counts the actions and enforces a hard ceiling. Round 7 is blocked before it runs.

Two different runaways, one wrapper

There are actually two failure modes, and the same wrapper catches both.

A loop, where the agent repeats the identical call:

STOPPED at round 5: loop detected: 'call:keep going' repeated 5x in a row
Enter fullscreen mode Exit fullscreen mode

A budget blowout, where the agent keeps doing new things forever:

STOPPED at round 6: step budget exceeded (6 > 5): possible runaway
Enter fullscreen mode Exit fullscreen mode

One catches an agent stuck repeating itself. The other catches an agent that never stops exploring. Most guardrail tools give you one, not both.

Do not trust me, verify it

Every decision is one entry in a hash-chained ledger. You can check it yourself:

ok, msg = tb.verify()   # (True, 'chain intact (6 entries verified)')
Enter fullscreen mode Exit fullscreen mode

Or re-run any demo and verify the ledger it wrote, or forge an entry and watch verification catch it. The whole point of the ledger is that you do not have to take the tool's word for what it did.

Honest scope

Because someone will ask: enforcement covers the tools you route through the guard. If you also hand your agent a raw, unguarded capability, it can bypass Tombstone. The rule is simple: give agents only guarded tools for anything risky. This is a wrapper around dangerous tools, not a kernel-level hook. I would rather say that up front than oversell it.

Try it

git clone https://github.com/airblackbox/tombstone
cd tombstone
pip install cryptography
PYTHONPATH=. python3 demo/runaway_agents.py
Enter fullscreen mode Exit fullscreen mode

It is Apache 2.0, runs locally, and works with plain Python tools, LangChain, CrewAI, or a raw OpenAI/Anthropic loop.

I would genuinely like feedback, especially on the runaway budget: is a hard tool-call ceiling the right primitive, or do you want a token-cost ceiling instead? Repo: https://github.com/airblackbox/tombstone

Top comments (0)