Skip to main content

Production-grade silent failure detection for LLM applications — hallucination alerts, PII leak detection, semantic drift, topic guard, and real-time observability

Project description

llm-watchdog

Production-grade silent failure detection for LLM applications.

Traditional monitoring (Datadog, New Relic) shows 200 OK in 1.2 seconds — but it cannot detect hallucinations, PII leaks, topic drift, or quality degradation in your LLM responses. llm-watchdog fills that gap.

pip install llm-watchdog

Why llm-watchdog?

Problem Traditional APM llm-watchdog
Hallucination risk Blind Scored 0–1
PII leaks in output Blind Detected + alerted
Topic drift Blind Keyword + coverage guard
Toxicity Blind Pattern-matched
Quality degradation Blind Refusal + repetition check
Semantic drift over time Blind PSI-based drift detector

Quickstart

from llm_watchdog import LlmWatchdog

watcher = LlmWatchdog()

result = watcher.watch(
    prompt="What is the capital of France?",
    response="The capital of France is Paris.",
)

print(result.passed)          # True
print(result.overall_score)   # 0.0
print(result.overall_risk)    # RiskLevel.LOW

Alert Hooks

from llm_watchdog import LlmWatchdog, AlertEvent

watcher = LlmWatchdog(pii_threshold=0.1)

def my_alert(event: AlertEvent):
    print(f"ALERT: {event.failure_type.value} — score={event.score:.2f}")

watcher.on_alert(my_alert)
watcher.watch("Tell me about John", "Contact john@example.com at 555-555-5555")
# ALERT: pii_leak — score=0.40

Async Support

import asyncio
from llm_watchdog import LlmWatchdog

watcher = LlmWatchdog()

async def main():
    result = await watcher.awatch("prompt", "response")
    print(result.overall_risk)

asyncio.run(main())

Batch Watching

from llm_watchdog import LlmWatchdog, batch_watch, abatch_watch
import asyncio

watcher = LlmWatchdog()
pairs = [("prompt1", "response1"), ("prompt2", "response2")]

# Sync batch
results = batch_watch(watcher, pairs, max_workers=8)

# Async batch
results = asyncio.run(abatch_watch(watcher, pairs, concurrency=8))

Topic Guard

from llm_watchdog import LlmWatchdog

watcher = LlmWatchdog(
    topic_allowed=["python", "code", "programming", "function"],
    topic_blocked=["politics", "religion", "violence"],
)
result = watcher.watch("How do I code?", "This involves violent politics.")
# topic drift detected

Advanced Features

Caching

from llm_watchdog import LlmWatchdog, WatchCache

watcher = LlmWatchdog()
cache = WatchCache(max_size=512, ttl=300)
cached_watch = cache.memoize(watcher)
result = cached_watch("prompt", "response")
print(cache.stats())
# {'hits': 0, 'misses': 1, 'hit_rate': 0.0, 'evictions': 0, 'size': 1}

Pipeline

from llm_watchdog import LlmWatchdog, WatchPipeline

watcher = LlmWatchdog()
result = watcher.watch("prompt", "response")

pipeline = WatchPipeline()
pipeline.add_step("log", lambda r: r)
pipeline.filter(lambda r: r.passed)
out = pipeline.run(result)
print(pipeline.audit())

Validation

from llm_watchdog import LlmWatchdog, WatchValidator, ConfidenceScorer

watcher = LlmWatchdog()
result = watcher.watch("prompt", "response")

validator = WatchValidator().require_pass().max_score(0.8)
violations = validator.validate(result)

scorer = ConfidenceScorer()
print(scorer.score(result))          # 0–1, higher = safer
print(scorer.field_scores(result))   # per-detector breakdown

Drift Detection

from llm_watchdog import DriftDetector

detector = DriftDetector(threshold=0.1)
detector.set_baseline([0.1, 0.2, 0.1, 0.15])
print(detector.is_drifting([0.5, 0.6, 0.4, 0.55]))  # True
print(detector.psi([0.5, 0.6, 0.4, 0.55]))           # PSI value

Streaming

from llm_watchdog import LlmWatchdog, StreamingWatcher

watcher = LlmWatchdog()
sw = StreamingWatcher(watcher)

pairs = [("prompt1", "response1"), ("prompt2", "response2")]
for result in sw.stream(pairs):
    print(result.overall_risk)

Diff & Regression Tracking

from llm_watchdog import LlmWatchdog, WatchDiff, RegressionTracker

watcher = LlmWatchdog()
r1 = watcher.watch("prompt", "safe response")
r2 = watcher.watch("prompt", "Contact john@example.com")

diff = WatchDiff(before=r1, after=r2)
print(diff.score_delta)        # +0.2
print(diff.new_failures)       # ['pii_leak']
print(diff.to_json())

tracker = RegressionTracker(tolerance=0.05)
tracker.record("deploy_v1", 0.10)
tracker.record("deploy_v2", 0.25)
print(tracker.is_regressing())  # True
print(tracker.summary())

Agent Session Monitoring

from llm_watchdog import LlmWatchdog, AgentWatchSession

watcher = LlmWatchdog()
session = AgentWatchSession(watcher, max_risk_budget=2.0)

for prompt, response in agent_turns:
    session.watch_turn(prompt, response)
    if session.is_over_budget():
        raise RuntimeError("Agent risk budget exceeded")

print(session.session_summary())

PII Scrubbing

from llm_watchdog import PIIScrubber

scrubber = PIIScrubber()
clean = scrubber.mask("Email me at alice@example.com or call 555-123-4567")
# "Email me at [REDACTED_EMAIL] or call [REDACTED_PHONE]"

Audit Log

from llm_watchdog import LlmWatchdog, AuditLog

watcher = LlmWatchdog()
audit = AuditLog()

result = watcher.watch("prompt", "response")
audit.record(result)
audit.export_audit("audit.json")
print(audit.entries())

Cost Ledger

from llm_watchdog import CostLedger

ledger = CostLedger(cost_per_watch=0.0001)
ledger.record("default", count=100)
ledger.record("batch", count=500)
print(ledger.total_cost())
print(ledger.report())

Rate Limiter

from llm_watchdog import LlmWatchdog, RateLimiter
import asyncio

rl = RateLimiter(rate=10, capacity=10)  # 10 calls/sec

# Sync
rl.acquire()

# Async
async def main():
    await rl.async_acquire()

asyncio.run(main())

FastAPI Middleware

from fastapi import FastAPI
from llm_watchdog import LlmWatchdog
from llm_watchdog.middleware import create_fastapi_middleware

app = FastAPI()
watcher = LlmWatchdog()
app.add_middleware(create_fastapi_middleware(watcher))

Flask Middleware

from flask import Flask
from llm_watchdog import LlmWatchdog
from llm_watchdog.middleware import create_flask_middleware

app = Flask(__name__)
watcher = LlmWatchdog()
create_flask_middleware(app, watcher)

CLI

llm-watchdog --prompt "What is the capital?" --response "Paris is the capital."
llm-watchdog --prompt "Tell me about John" --response "Call 555-123-4567" --json

Configuration

Parameter Default Description
hallucination_threshold 0.5 Flag score above this
pii_threshold 0.1 Any PII triggers flag
toxicity_threshold 0.3 Toxic content threshold
quality_threshold 0.4 Low-quality response threshold
topic_allowed None Keywords expected in response
topic_blocked None Keywords that always trigger flag
block_on_critical False Raise exception on CRITICAL risk

All Exports

from llm_watchdog import (
    # Core
    LlmWatchdog,
    # Models
    WatchResult, DetectionResult, AlertEvent, DriftSnapshot, RiskLevel, FailureType,
    # Exceptions
    LlmWatchdogError, HallucinationDetectedError, PIILeakDetectedError,
    TopicDriftError, SemanticDriftError, BudgetExceededError, AlertDeliveryError,
    # Detectors
    HallucinationDetector, PIIDetector, TopicGuard, ToxicityDetector, QualityDetector,
    # Advanced
    WatchCache, WatchPipeline, WatchValidator, ConfidenceScorer,
    RateLimiter, batch_watch, abatch_watch,
    OperationProfiler, DriftDetector, StreamingWatcher,
    WatchDiff, RegressionTracker, AgentWatchSession,
    PIIScrubber, AuditLog, CostLedger,
)

Installation

pip install llm-watchdog                    # core only
pip install llm-watchdog[fastapi]           # with FastAPI middleware
pip install llm-watchdog[flask]             # with Flask middleware
pip install llm-watchdog[opentelemetry]     # with OTEL tracing
pip install llm-watchdog[all]               # everything

Keywords

llm monitoring, ai observability, hallucination detection, pii detection, semantic drift, production ai monitoring, llm alerts, ai safety, prompt monitoring, silent failure detection, llm quality, topic drift, ai reliability, llm guardrails, prompt injection, ai production

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_watchdog-1.0.2.tar.gz (23.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

llm_watchdog-1.0.2-py3-none-any.whl (23.8 kB view details)

Uploaded Python 3

File details

Details for the file llm_watchdog-1.0.2.tar.gz.

File metadata

  • Download URL: llm_watchdog-1.0.2.tar.gz
  • Upload date:
  • Size: 23.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for llm_watchdog-1.0.2.tar.gz
Algorithm Hash digest
SHA256 de5aa7d0cc7b047d9e8e71278d446e50b10ed0c49e624e97049aace7e502f850
MD5 1d358c7d0fc8730e381b2d779f98494d
BLAKE2b-256 d0a3fc56523a059d239af0695889c97905942d394c55759afa24a9e93c51da0c

See more details on using hashes here.

File details

Details for the file llm_watchdog-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: llm_watchdog-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 23.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for llm_watchdog-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 76f5ffba175d65c828d2c13fc943b08dd5aeef5c90dac3d011587287fec13756
MD5 57caf25fa6bcb93c8b2c93e808a93cb6
BLAKE2b-256 393d8a9c69abe353dfee0cfe7f543d073d40fc1b061c4f87ee48dbb50a61b6cd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page