Runtime pathology detection for AI agents. Diagnoses loops, stalls, oscillation, drift, and silent abandonment.
Project description
agent-patrol
Runtime pathology detection for AI agents. Diagnoses loops, stalls, oscillation, drift, and silent abandonment.
The Problem
Your AI agents get stuck. They loop, oscillate, stall, drift from their task, and silently abandon their mission -- and you don't know until the token bill arrives.
Current solutions are blunt instruments:
- max_steps / timeout -- kills productive and unproductive agents equally
- Observability platforms -- trace what happened but not why it went wrong
- Framework-specific guards -- locked to one framework, not portable
agent-patrol diagnoses what kind of failure your agent is experiencing, in real time, across any framework.
Five Agent Pathologies
| # | Pathology | What It Looks Like | What agent-patrol Does |
|---|---|---|---|
| 1 | Futile Cycle | Agent repeats the same action with minor variations | Measures semantic similarity between consecutive actions. Flags when iterations stop producing new information. |
| 2 | Oscillation | Agent alternates between two contradictory sub-goals | Clusters actions into goal-groups. Detects when the agent is "double-minded" -- switching between conflicting objectives. |
| 3 | Stall | Agent is active but making no progress toward its goal | Tracks semantic distance to declared milestones over time. Distinguishes "legitimately slow" from "stuck." |
| 4 | Drift | Agent gradually wanders from its original task | Compares current action context to the original task embedding. Flags when intent has shifted beyond threshold. |
| 5 | Abandonment | Agent silently stops working on its task and does something else | Detects combined low-similarity-to-original-task + high-coherence-with-novel-objective. |
Installation
pip install agent-patrol
Zero hard dependencies. Works with Python stdlib alone. Optional enhancements:
# For embedding-based detection (recommended for production)
pip install agent-patrol[embeddings]
# For LLM-based semantic analysis
pip install agent-patrol[llm]
Quick Start
Option 1: Decorator
from agent_patrol import patrol
@patrol(on_pathology="log", sensitivity="medium")
def agent_step(state: dict) -> dict:
# Your agent logic here
return new_state
Option 2: Monitor
from agent_patrol import PatrolMonitor
monitor = PatrolMonitor(
task_description="Research and summarize recent economic data",
milestones=["Find GDP data", "Find inflation data", "Write summary"],
)
for step in agent_loop():
report = monitor.observe(step.action, step.result)
if report.pathology:
print(f"DETECTED: {report.pathology} at step {report.step_detected}")
print(f"Evidence: {report.evidence}")
print(f"Action: {report.recommended_action}")
Option 3: CI Gate
# Run agent-patrol on a recorded trace file
agent-patrol check trace.jsonl --fail-on FUTILE_CYCLE,STALL
Output
PatrolReport(
pathology="FUTILE_CYCLE",
confidence=0.87,
step_detected=14,
evidence=["Steps 12-14: repeated 'search for X' with <0.05 semantic variance"],
recommended_action="HALT",
total_steps_observed=14,
token_estimate_wasted=3400,
)
Framework Integration
Works with any agent framework. No lock-in.
- LangGraph -- wrap your node functions
- CrewAI -- wrap agent step callbacks
- OpenAI Agents SDK -- wrap tool execution
- Anthropic Claude Agent SDK -- wrap tool use blocks
- Raw loops -- wrap your iteration function
See examples/ for integration guides.
Configuration
from agent_patrol import PatrolConfig
config = PatrolConfig(
# Detection sensitivity (low = fewer false positives, high = catches more)
sensitivity="medium", # "low" | "medium" | "high"
# Which pathologies to detect
detect=["FUTILE_CYCLE", "OSCILLATION", "STALL", "DRIFT", "ABANDONMENT"],
# What to do when pathology is detected
on_pathology="log", # "log" | "raise" | "halt" | "callback"
# Similarity backend
similarity_backend="tfidf", # "tfidf" | "embeddings" | "llm"
# Custom thresholds
cycle_similarity_threshold=0.92,
stall_window=5,
drift_threshold=0.60,
oscillation_min_switches=3,
)
How It Works
agent-patrol maintains a rolling window of agent actions (text descriptions + optional state). For each new action, it runs five lightweight detectors:
-
Futile Cycle Detector -- Computes pairwise similarity in a sliding window. If the last N actions are all >0.92 similar, the agent is cycling.
-
Oscillation Detector -- Clusters actions by semantic similarity. If the agent alternates between 2+ clusters more than 3 times, it is oscillating.
-
Stall Detector -- If milestones are declared, computes distance to each milestone at every step. If the minimum distance is non-decreasing for 5+ steps, the agent is stalled.
-
Drift Detector -- Maintains the original task embedding. Computes cosine similarity between current action context and original task. If below 0.60, intent has drifted.
-
Abandonment Detector -- Combines drift detection with novel-cluster detection. If the agent is far from its original task AND close to a new coherent objective, it has silently abandoned its task.
Why This Exists
Every team running AI agents in production has experienced stuck agents. The token cost of a stuck agent looping for 200 steps before a timeout kills it can be $5-50 per incident. Multiply by hundreds of daily agent runs and the cost is material.
More importantly: stuck agents produce bad output. A stalled research agent returns incomplete results. A drifted coding agent implements the wrong feature. An oscillating planning agent produces an incoherent plan. These failures are silent -- the agent returns output that looks complete but isn't.
agent-patrol makes these failures visible and actionable.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_patrol-0.1.0.tar.gz.
File metadata
- Download URL: agent_patrol-0.1.0.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dfbebd3458a7d4db08ec3846fccedd7824d2b9f668bc473249af4b56bb4f368
|
|
| MD5 |
8f4762ddf0578fdbcd1e0cd70c787a99
|
|
| BLAKE2b-256 |
cd931f5bf100e87185d9938b4702c6674ec6c86772e935897fab6df330ca5254
|
File details
Details for the file agent_patrol-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agent_patrol-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d394189be194276e18647b40f3f1e1248f08d10a8d806d1f61590fb12cacbb2e
|
|
| MD5 |
534abc1d90e395a4664f94346681c4f1
|
|
| BLAKE2b-256 |
4a3fab3d7c7a6cd554c4a77d379f82538f490f84403445fa3a96ab4c1fde7606
|