Skip to main content

savi-loop-guard

A zero-dependency Python library that detects when an AI agent is stuck in a loop: calling the same tool over and over, or firing calls far faster than any real workflow would. Drop it into your own agent code. No account, no API key, no network call, ever.

Built by SAVI as a standalone, dependency-free package, so you can detect these patterns in your own agent code without an account, an API key, or a dependency on SAVI's platform.


Install

pip install savi-loop-guard

No dependencies. Nothing else gets installed alongside it.


Quick start

Record each call as your agent makes it, then check for loops whenever you want (after every call, on a timer, whatever fits your loop):

from loop_guard import LoopGuard, CallEvent
from datetime import datetime, timezone

guard = LoopGuard()

guard.record(CallEvent(
    span_id="call_1",
    agent_id="doc-extractor",
    timestamp=datetime.now(timezone.utc),
    tool_call="search_web",
))

issues = guard.check()
for issue in issues:
    print(issue["type"], issue["agent_id"])

An issue looks like:

{"type": LoopType.VELOCITY, "agent_id": "doc-extractor", "elapsed_s": 12.4, "call_count": 6}
# or
{"type": LoopType.STRUCTURAL, "agent_id": "doc-extractor",
 "tool_call": "search_web", "tool_variants": ["search_web", "search_web_v2"], "call_count": 7}

Prevent the call instead of just observing it

check_before_call() records the event and raises immediately if it would trip a threshold, for callers who want to stop the loop rather than find out about it afterwards:

from loop_guard import LoopGuard, CallEvent, LoopDetected

guard = LoopGuard()

try:
    guard.check_before_call(event)
except LoopDetected as e:
    print(f"Blocked: {e.loop_type}")  # "velocity_loop" or "structural_loop"
    print(e.details)                  # the same dict check() would have returned

What it detects

Two independent checks:

  • Velocity loop: more than 5 calls from the same agent_id within a 30-second window.
  • Structural loop: the same tool called more than 5 times, with fuzzy matching so a broken agent can't dodge detection by alternating between near-identical tool names (search_web vs search_web_v2 vs web_search count as the same tool if their name tokens overlap enough).

All four numbers are configurable:

guard = LoopGuard(
    velocity_window_seconds=30,
    velocity_call_limit=5,
    structural_call_limit=5,
    tool_fuzzy_similarity_threshold=0.70,
)

How this compares

A few other standalone Python packages exist for this: agent-loop-detector, agent-loop-guard, agentguard-kit. All of them, like savi-loop-guard's record()/check() API, are post-hoc/observational; they analyze calls after they happen. savi-loop-guard adds check_before_call() on top for callers who want to prevent the call rather than just observe it, which none of those currently offer.


Known limitations

LoopGuard keeps every recorded event in memory for the life of the instance; nothing is ever pruned automatically. That's deliberate: structural-loop detection is a total call count with no time bound by design (a tool called 6 times over 3 hours is still a loop, not just a tool called 6 times in 30 seconds), so silently dropping "old" events would blind it to exactly the slow, steady loops it exists to catch.

In practice this means: for a short-lived task, a single LoopGuard() is fine as-is. For a long-running process, create a fresh LoopGuard() per logical unit of work (e.g. per agent run) rather than holding one open indefinitely, so memory doesn't grow without bound.


License

MIT. See LICENSE.

Metadata

Release files for savi-loop-guard 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for savi-loop-guard 0.1.0
File Size Uploaded Provenance Actions
savi_loop_guard-0.1.0.tar.gz 10.5 kB With provenance Details for savi_loop_guard-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for savi-loop-guard 0.1.0
File Interpreter ABI Platform Actions
savi_loop_guard-0.1.0-py3-none-any.whl Python 3 none any Details for savi_loop_guard-0.1.0-py3-none-any.whl

Total release size: 18.1 kB

Release files / savi_loop_guard-0.1.0.tar.gz

Download URL savi_loop_guard-0.1.0.tar.gz
Size 10.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c07b36cbc2f3141b6b6da021fd32c27ac0d2159db523fdb55c8c2d5486bd6c65
BLAKE2b-256 checksum
How to use checksums
4bcc6d4692f1fb80f708dfb11822be7ae2827424e76a7f419205e11deb7805be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Release files / savi_loop_guard-0.1.0-py3-none-any.whl

Download URL savi_loop_guard-0.1.0-py3-none-any.whl
Size 7.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4bdc3a817fc9e24c13fb137c6d8615659b75f2e0d79c1ee43d1ee46ae7334bc3
BLAKE2b-256 checksum
How to use checksums
7571c6765a040ab6f318cf693ea47c428db12b224e13bf16ad8c1d0464fa772b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

Security for savi-loop-guard 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for savi_loop_guard-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page