Statistical anomaly detection for AI agent workflows
Project description
Drift
Statistical anomaly detection for AI agent workflows.
Catch silent failures, hallucination drift, and off-script behavior before they corrupt your data.
Your AI agents are failing silently. A tool call takes 10x longer than usual. The agent calls delete_file when it's never done that before. Output quality gradually degrades over hundreds of runs. Traditional monitoring tools weren't built for non-deterministic systems — Drift is.
What it does
Drift hooks into your agent's execution and applies statistical anomaly detection to the event stream:
-
Latency & token SPC — Flags when a tool call or LLM response takes significantly longer or uses significantly more tokens than its rolling baseline. Catches hung API calls, runaway generation, and upstream provider issues.
-
Sequence anomaly detection — Builds a transition matrix of tool-call sequences and flags when the agent takes a path that's never or rarely been seen. Catches agents going off-script, skipping required steps, or entering novel execution paths.
-
Output drift detection — Tracks output length, vocabulary diversity, and structural patterns over time. Flags when outputs shift significantly from baseline. Catches hallucination drift, prompt injection effects, and gradual quality degradation.
Install
pip install driftguard
With LangChain support:
pip install driftguard[langchain]
Quickstart
With LangChain
from drift import DriftGuard
from drift.callbacks.langchain import DriftCallbackHandler
guard = DriftGuard(on_anomaly=lambda a: print(f"🚨 {a}"))
handler = DriftCallbackHandler(guard)
# Use with any LangChain agent, chain, or LLM
agent.run("your query", callbacks=[handler])
# See what happened
guard.report()
Standalone (no framework required)
from drift import DriftGuard, AgentEvent, EventType
guard = DriftGuard(on_anomaly=lambda a: print(f"🚨 {a}"))
# Feed events from any source
guard.ingest(AgentEvent(
event_type=EventType.TOOL_END,
name="search_web",
latency_ms=150.0,
token_count=85,
output_text="Found 3 results for query...",
))
guard.report()
Run the demo
python examples/demo.py
This simulates normal agent operation, builds baselines, then injects latency spikes, sequence anomalies, and output drift — showing each detector catching real failure modes.
Architecture
drift/
├── core.py # DriftGuard engine — orchestrates detectors
├── models.py # AgentEvent, Anomaly, Severity data models
├── detectors/
│ ├── latency.py # Statistical process control on latency/tokens
│ ├── sequence.py # Action transition probability anomalies
│ └── output_drift.py # Output distribution shift detection
└── callbacks/
└── langchain.py # LangChain callback integration
Design principles:
- Zero-overhead default — Detectors use numpy for fast rolling statistics. No embedding models, no external services, no network calls.
- Per-tool baselines — Each tool and model gets its own statistical baseline, so a slow tool won't pollute the baseline for a fast one.
- Framework-agnostic core — The detection engine works with raw
AgentEventobjects. Framework integrations (LangChain, CrewAI, etc.) are thin adapters that translate framework callbacks into events. - Non-blocking — Drift never throws exceptions that would crash your agent. Detector errors are caught and logged to stderr.
Detectors
| Detector | What it catches | Method |
|---|---|---|
LatencyDetector |
Hung calls, slow APIs, runaway generation | Rolling z-score on latency and token counts |
SequenceDetector |
Off-script behavior, unexpected tool calls | First-order Markov transition probabilities |
OutputDriftDetector |
Hallucination drift, prompt injection, quality degradation | Output length, vocab diversity, structural pattern tracking |
Configuration
Each detector is independently configurable:
from drift import DriftGuard
from drift.detectors.latency import LatencyDetector, LatencyDetectorConfig
from drift.detectors.sequence import SequenceDetector, SequenceDetectorConfig
guard = DriftGuard(detectors=[
LatencyDetector(LatencyDetectorConfig(
window_size=100, # Longer baseline window
z_threshold=2.5, # More sensitive
min_samples=10, # Require more data before alerting
)),
SequenceDetector(SequenceDetectorConfig(
min_observations=20, # Require more transitions before flagging
)),
])
Roadmap
- CrewAI callback handler
- OpenAI Agents SDK integration
- Slack / PagerDuty alerting
- Persistent baselines (save/load detector state)
- Embedding-based output drift (optional dependency)
- Web dashboard
- Cost anomaly detection (track spend per run)
Contributing
Issues and PRs welcome. Run tests with:
pip install -e ".[dev]"
pytest
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 drift_detection-0.1.0.tar.gz.
File metadata
- Download URL: drift_detection-0.1.0.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
513b8301e89611d362e23096a69ab724692c49e2667a18f2f60d9e570789c9e6
|
|
| MD5 |
4f7647fb53a328fbaa81b016106d3a0f
|
|
| BLAKE2b-256 |
5e416c31773799a3690204c58c0e41227b75d67895983d0ee6faf1bf20bd2573
|
Provenance
The following attestation bundles were made for drift_detection-0.1.0.tar.gz:
Publisher:
publish.yml on dombinic/Drift
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drift_detection-0.1.0.tar.gz -
Subject digest:
513b8301e89611d362e23096a69ab724692c49e2667a18f2f60d9e570789c9e6 - Sigstore transparency entry: 1809110256
- Sigstore integration time:
-
Permalink:
dombinic/Drift@ec1042ed08f5c03efb8b9020d53065c411b268ff -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dombinic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec1042ed08f5c03efb8b9020d53065c411b268ff -
Trigger Event:
push
-
Statement type:
File details
Details for the file drift_detection-0.1.0-py3-none-any.whl.
File metadata
- Download URL: drift_detection-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a90eb92b950b8b2bf3af6e275827c27658cdf4ed7327bbe4a6b50de67275ea91
|
|
| MD5 |
8705e0148933fed271446b71dbf0c864
|
|
| BLAKE2b-256 |
5a66f16d8d87cec261f41c972d2ae3d0292df1dba21809e316dcc117e35e653f
|
Provenance
The following attestation bundles were made for drift_detection-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on dombinic/Drift
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
drift_detection-0.1.0-py3-none-any.whl -
Subject digest:
a90eb92b950b8b2bf3af6e275827c27658cdf4ed7327bbe4a6b50de67275ea91 - Sigstore transparency entry: 1809110273
- Sigstore integration time:
-
Permalink:
dombinic/Drift@ec1042ed08f5c03efb8b9020d53065c411b268ff -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/dombinic
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ec1042ed08f5c03efb8b9020d53065c411b268ff -
Trigger Event:
push
-
Statement type: