Skip to main content
Agents can get stuck in infinite loops, repeating the same actions without making progress. Loop detection catches these patterns and breaks out.

Types of Loops

Loop TypePatternDetection
Repeated OutputSame response 3+ timesOutput hash matching
No State ChangeAgent runs but nothing changesState diff tracking
Action CycleA → B → C → A → B → CAction sequence matching

Basic Usage

from splinter.types import LoopDetectionConfig

config = LoopDetectionConfig(
    max_repeated_outputs=3,   # Same output 3x = loop
    max_no_state_change=5,    # No progress 5x = loop
)

s = Splinter(openai_key="sk-...", loop_detection=config)

With Workflow

from splinter.workflow import Workflow
from splinter.types import LoopDetectionConfig

workflow = Workflow(
    workflow_id="pipeline",
    loop_detection=LoopDetectionConfig(
        max_repeated_outputs=3,
        max_no_state_change=5,
        action_window=10,  # Look at last 10 actions
    ),
)

Loop Detector API

For more control, use the LoopDetector directly:
from splinter.control import LoopDetector

detector = LoopDetector(
    max_repeated_outputs=3,
    max_no_state_change=5,
)

# Record outputs
detector.record_output(agent_id="researcher", output="result")

# Check for loops
if detector.is_looping("researcher"):
    print("Loop detected!")
    detector.break_loop("researcher")

Handling Loop Errors

from splinter.exceptions import LoopDetectedError

try:
    result = await s.run("agent", "task")
except LoopDetectedError as e:
    print(f"Loop detected in {e.agent_id}")
    print(f"Pattern: {e.pattern}")
    print(f"Iterations: {e.iterations}")

Loop Breaking Strategies

from splinter.control import LoopBreaker, BreakStrategy

breaker = LoopBreaker(strategy=BreakStrategy.INJECT_PROMPT)

# When loop detected
breaker.break_loop(
    agent_id="researcher",
    context={
        "last_outputs": [...],
        "state": {...},
    }
)

# Strategies:
# - INJECT_PROMPT: Add "You seem stuck. Try a different approach."
# - RESET_STATE: Clear agent's short-term memory
# - FORCE_STOP: Stop the agent entirely

Detecting Subtle Loops

Sometimes loops aren’t exact repeats:
config = LoopDetectionConfig(
    max_repeated_outputs=3,
    similarity_threshold=0.9,  # 90% similar = same output
    state_fields=["research.*", "content.*"],  # Only watch these fields
)

Best Practices

Agents running without human oversight will get stuck. It’s a matter of when, not if.
Too low = false positives. Too high = loops run too long. 3 repeated outputs is a good default.
If loops are common, your prompts might need work.
Repeated outputs alone isn’t enough. An agent might output different text but make no progress.