Stage 7 · Master
Running AI Reliably (LLMOps)
Monitoring the AI Itself
Tracking hallucination rate, drift, latency, and cost as first-class SLIs.
Why Monitor the AI?
AI systems degrade silently. A prompt change reduces accuracy. A model provider changes behavior. User behavior shifts. Without monitoring, you discover these problems when users complain. Monitor the AI with the same rigor you monitor your infrastructure.
Quality SLIs
class QualitySLIs:
def __init__(self):
self.metrics = defaultdict(list)
def record_response(self, feature, response, context):
"""Record quality metrics for a response."""
# Hallucination rate: check if response cites context
grounded = self.check_groundedness(response, context)
self.metrics[f"{feature}_groundedness"].append(grounded)
# Refusal rate: did the model say it does not know?
refused = "I do not have enough information" in response
self.metrics[f"{feature}_refusal"].append(refused)
# Length: track response length for anomalies
self.metrics[f"{feature}_length"].append(len(response))
# User feedback: thumbs up/down
# (Recorded separately via reaction handler)
def check_groundedness(self, response, context):
"""Simple groundedness check: does response share words with context?"""
response_words = set(response.lower().split())
context_words = set(context.lower().split())
overlap = len(response_words & context_words) / len(response_words)
return overlap > 0.3 # At least 30% word overlap
def get_sli_summary(self, feature, window_hours=24):
"""Get SLI summary for a feature."""
return {
"groundedness": np.mean(self.metrics[f"{feature}_groundedness"]),
"refusal_rate": np.mean(self.metrics[f"{feature}_refusal"]),
"avg_length": np.mean(self.metrics[f"{feature}_length"]),
}Track groundedness, refusal rate, and response length as quality SLIs. Changes in these metrics indicate quality degradation.
Drift Detection
from scipy import stats
def detect_output_drift(recent_outputs, baseline_outputs):
"""Detect if model output distribution has changed."""
# Compare response lengths
recent_lengths = [len(o) for o in recent_outputs]
baseline_lengths = [len(o) for o in baseline_outputs]
# KS test for distribution change
ks_stat, p_value = stats.ks_2samp(recent_lengths, baseline_lengths)
# Compare groundedness scores
recent_grounded = [check_groundedness(o) for o in recent_outputs]
baseline_grounded = [check_groundedness(o) for o in baseline_outputs]
grounding_drift = np.mean(recent_grounded) - np.mean(baseline_grounded)
return {
"length_drift": {"ks_statistic": ks_stat, "p_value": p_value},
"grounding_drift": grounding_drift,
"alert": p_value < 0.01 or abs(grounding_drift) > 0.1,
}Use statistical tests to detect when output patterns change. A significant change in response length or groundedness indicates drift.
Cost Monitoring
class CostTracker:
PRICING = {
"gpt-4": {"input": 0.00003, "output": 0.00006},
"gpt-4-turbo": {"input": 0.00001, "output": 0.00003},
"gpt-3.5-turbo": {"input": 0.0000005, "output": 0.0000015},
}
def record_cost(self, feature, model, input_tokens, output_tokens):
"""Record cost for a request."""
pricing = self.PRICING.get(model, {"input": 0, "output": 0})
cost = (input_tokens * pricing["input"] +
output_tokens * pricing["output"])
self.db.record({
"feature": feature,
"model": model,
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"cost_usd": cost,
"timestamp": datetime.utcnow()
})
def get_daily_cost(self, feature=None):
"""Get daily cost breakdown."""
query = "SELECT SUM(cost_usd) FROM ai_costs WHERE date = today()"
if feature:
query += f" AND feature = '{feature}'"
return self.db.execute(query)Track cost per feature per day. Alert when daily cost exceeds budget.
Operational Dashboards
- Quality panel: groundedness rate, refusal rate, hallucination rate over time.
- Performance panel: p50, p95, p99 latency for each feature.
- Cost panel: daily cost by feature, cost per request, token usage trends.
- Reliability panel: error rate, timeout rate, fallback rate.
- Usage panel: requests per minute, active users, popular queries.
Use Grafana, Datadog, or whatever your team already uses. Export AI metrics to Prometheus or your metrics backend and build dashboards alongside infrastructure metrics.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.