Responsible Deployment › Building a Monitoring Dashboard
Language AI HandbookAll chapters Responsible Deployment › Building a Monitoring DashboardOne section · Sections in this chapter6 / 10 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
A concrete monitoring dashboard makes abstract principles tangible. The following implementation builds a minimal dashboard that tracks the key metrics discussed above: safety classifier scores, request volume by category, and distribution shift indicators. This represents the kind of system that a small team might build to maintain operational visibility over a deployed language model.
from collections import defaultdict, deque
from dataclasses import dataclass
import numpy as np
@dataclass
class RequestRecord:
timestamp: float
user_tier: str
input_length: int
output_length: int
latency_ms: float
safety_score: float # 0 = safe, 1 = unsafe (from safety classifier)
category: str # request category label
blocked: bool # whether the request was blocked by a filter
class DeploymentMonitor:
"""
Minimal deployment monitor that tracks key metrics over a rolling window.
In production this would be backed by a time-series database.
"""
def __init__(self, window_size: int = 1000):
self.window_size = window_size
self.records: deque = deque(maxlen=window_size)
self.safety_threshold = 0.7
def record_request(self, record: RequestRecord) -> None:
self.records.append(record)
def compute_metrics(self) -> dict:
if not self.records:
return {}
records_list = list(self.records)
n = len(records_list)
block_rate = sum(r.blocked for r in records_list) / n
mean_latency = np.mean([r.latency_ms for r in records_list])
p95_latency = np.percentile([r.latency_ms for r in records_list], 95)
safety_scores = [r.safety_score for r in records_list]
mean_safety_score = np.mean(safety_scores)
high_risk_rate = (
sum(s >= self.safety_threshold for s in safety_scores) / n
)
category_counts: dict = defaultdict(int)
for r in records_list:
category_counts[r.category] += 1
tier_counts: dict = defaultdict(int)
for r in records_list:
tier_counts[r.user_tier] += 1
return {
"n_requests": n,
"block_rate": block_rate,
"mean_latency_ms": mean_latency,
"p95_latency_ms": p95_latency,
"mean_safety_score": mean_safety_score,
"high_risk_rate": high_risk_rate,
"category_distribution": dict(category_counts),
"tier_distribution": dict(tier_counts),
}
def check_alerts(self) -> list[str]:
metrics = self.compute_metrics()
alerts = []
if metrics.get("high_risk_rate", 0) > 0.05:
alerts.append(
f"SAFETY ALERT: High-risk rate {metrics['high_risk_rate']:.1%} exceeds 5% threshold"
)
if metrics.get("block_rate", 0) > 0.15:
alerts.append(
f"FILTER ALERT: Block rate {metrics['block_rate']:.1%} exceeds 15% threshold"
)
if metrics.get("p95_latency_ms", 0) > 2000:
alerts.append(
f"LATENCY ALERT: p95 latency {metrics['p95_latency_ms']:.0f}ms exceeds 2000ms"
)
return alertsThe DeploymentMonitor class maintains a rolling window of request records and computes aggregate metrics over that window. In a production system, the records deque would be replaced by queries to a time-series database such as InfluxDB or a columnar store like ClickHouse, which can handle millions of records per day with efficient rolling window aggregation. The alert logic would be connected to a paging system such as PagerDuty rather than just printed to a console.
Deployment Monitor Dashboard (500 requests) ======================================================= Reliability Mean latency: 273 ms p95 latency: 555 ms Block rate: 0.00% Safety Mean safety score: 0.0686 High-risk rate: 0.00% Category Distribution factual_lookup 114 (22.8%) analysis 105 (21.0%) code_generation 102 (20.4%) general_qa 94 (18.8%) creative_writing 85 (17.0%) Tier Distribution public 305 (61.0%) standard 160 (32.0%) enterprise 35 (7.0%) Alerts: None
The dashboard captures the key dimensions of monitoring in a single view: reliability (latency, block rate), safety (safety score distribution, high-risk rate), and usage patterns (category and tier distribution). Alerts surface when any dimension exceeds its threshold, allowing quick human review of potential issues. The category distribution is particularly useful because unexpected shifts in the distribution of query categories often precede safety problems: a sudden surge in code generation queries might indicate that the model is being used to automate some task, and the nature of that task is worth investigating.
