Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

QuartzUnit/agent-loop-guard

Repository files navigation

agent-loop-guard

한국어 문서 · llms.txt

Framework-agnostic agent loop detection — sliding window similarity scoring to catch stuck agents.

Install

pip install agent-loop-guard

Quick Start

from loop_guard import LoopGuard, Action
guard = LoopGuard()
for action in agent_actions:
 decision = guard.check(tool=action.name, args=action.args)
 if decision.action == Action.STOP:
 print(f"Loop detected: {decision.reason}")
 break

Why not just max_iter?

Approach What it catches Limitation
max_iter=10 Runaway agents Kills long legitimate tasks; misses 3-step loops at step 9
agent-loop-guard Exact repeats, fuzzy repeats, A→B→C→A cycles, output stagnation

max_iter is a blunt timeout. agent-loop-guard detects behavioral patterns — the agent doing the same thing over and over, even with slight variations.

Detection Strategies

Strategy What it detects Confidence signal
Exact Repeat Same (tool, args) called repeatedly Consecutive identical calls
Fuzzy Repeat Near-identical args (Jaccard + edit distance) Similarity > threshold
Cycle Detection A→B→C→A→B→C repeating sequences Pattern repetition count
Output Stagnation Tool returns same output repeatedly Output similarity > threshold

All four strategies run on every call. The highest confidence wins.

flowchart TD
 A["🔄 Agent Tool Call"] --> B["Sliding Window\nHistory Buffer"]
 B --> C["Exact Repeat\nDetector"]
 B --> D["Fuzzy Repeat\nDetector"]
 B --> E["Cycle\nDetector"]
 B --> F["Output Stagnation\nDetector"]
 C --> G{"Max\nConfidence"}
 D --> G
 E --> G
 F --> G
 G -->|"low"| H["✅ ALLOW"]
 G -->|"medium"| I["⚠️ WARN"]
 G -->|"high"| J["🛑 STOP"]
 G -->|"critical"| K["🚨 ESCALATE"]
Loading

API

guard = LoopGuard(
 window_size=10, # actions to keep in memory
 similarity_threshold=0.85, # fuzzy match threshold
)
decision = guard.check(
 tool="web_search", # tool/function name
 args={"query": "python"}, # arguments (dict or str)
 output="Results: ...", # optional: enables stagnation detection
)
decision.action # Action.CONTINUE | WARN | STOP | ESCALATE
decision.reason # "Cycle detected: [search → parse → search] repeated 3 times"
decision.strategy # "cycle_detection"
decision.confidence # 0.0 ~ 1.0
decision.is_loop # True if STOP or ESCALATE
decision.should_warn # True if WARN
guard.reset() # reuse for next session

Action Escalation

Actions escalate with consecutive detections:

from loop_guard import ActionConfig
config = ActionConfig(
 warn_threshold=2, # 2 consecutive hits → WARN
 stop_threshold=4, # 4 consecutive hits → STOP
 escalate_threshold=6, # 6 consecutive hits → ESCALATE
)
guard = LoopGuard(action_config=config)

Generic Callback

from loop_guard.integrations.generic import LoopGuardCallback
callback = LoopGuardCallback(
 on_warn=lambda d: logger.warning(f"Loop warning: {d.reason}"),
 on_stop=lambda d: raise_stop_error(d),
)
# In your agent loop:
decision = callback.before_tool_call("search", {"query": "test"})

Used in

  • watchdeck — Web page monitoring with visual diffs and safety guards

License

MIT


Part of the QuartzUnit ecosystem — composable Python libraries for data collection, extraction, search, and AI agent safety.

About

Framework-agnostic agent loop detection — sliding window similarity scoring, zero dependencies

Resources

License

Contributing

Stars

Watchers

Forks

Packages

Contributors

Languages

  • Python 100.0%

AltStyle によって変換されたページ (->オリジナル) /