Production Evaluation: Monitoring & Online Evals
Offline evals tell you about the cases you thought of. Production tells you the truth. Online evaluation closes the loop — measuring real behavior on real traffic and feeding problems back into your offline suite.
Signals, guardrails, and the silent regression
Live you can collect implicit signals (thumbs, copy, regenerate, edits, abandonment), run an online judge on sampled traffic, and enforce guardrails — real-time checks that block or repair before a response ships. Note the distinction: guardrails enforce in the moment; evals measure over time. The nightmare is the silent regression: quality drops with no crash and no error — the input distribution shifts, or the provider silently updates the model — and you find out only when users churn. Drift detection makes silent failures loud.
Production surfaces a failure → you capture the case → it becomes a new example in your offline set → you fix and prove the fix offline → you ship → production confirms. That loop — production feeding the dataset that guards the next release — is the beating heart of mature AI quality, and a strong senior-interview answer.
What to measure live: explicit vs. implicit signals
Two kinds of signal come off real traffic, and mature teams instrument both. Explicit feedback is what users deliberately give — thumbs up/down, star ratings, a "report" flag. It's clean but rare: on most products only a percent or two of responses get rated, and the raters skew angry or delighted. Implicit feedback is what their behavior reveals, and it's where the volume is:
- Acceptance rate — for an inline suggestion (code completion, reply draft, autocomplete), did the user keep it? A completion product's headline quality number is often "% of suggestions accepted," not any offline score.
- Edit distance — how much did they change an accepted output before shipping it? A suggestion accepted and then rewritten word-for-word wasn't really a win; low post-accept edit distance is strong tacit approval.
- Copy / retry / regenerate / abandon — a copy is tacit approval; a regenerate or a rephrased re-ask is tacit rejection; abandoning mid-conversation is the loudest quiet signal of all.
Implicit signals are noisy per event but overwhelming in aggregate, and they cost no annotation budget — which is why they anchor production quality dashboards. Pair them with an online judge on sampled traffic for the "why," and explicit feedback as ground-truth spot-checks.
Operational metrics: quality isn't free
An eval that reports only quality is half an answer. In production, quality trades off against latency and cost, and at scale that trade-off is the engineering. Track these next to your quality signals — an interviewer at a company serving models at scale will expect them by name:
- TTFT (time to first token) — how long until the user sees anything. For streaming UIs, this (not total time) is perceived responsiveness: sub-second feels instant, multi-second feels broken.
- Tokens/second (throughput) — the streaming rate once output starts, and how many concurrent requests a deployment sustains before it degrades.
- Cost & latency per request — dollars and milliseconds per call, watched against quality. A prompt change that lifts a judge score two points but doubles cost and TTFT can be a net loss.
- Utilization — GPU/accelerator saturation behind self-hosted models; the number that decides whether you need more hardware or just better batching.
The trade-off these metrics expose is model routing: send the easy majority of traffic to a small, cheap, fine-tuned model and escalate only the hard cases to a frontier model — then use your eval harness to prove the router didn't cost you quality. "Here's the quality-versus-cost curve, and here's where I set the operating point" beats any single number.
Catch a silent regression with drift detection
You'll implement PSI (Population Stability Index) and compare last month's score distribution to this week's (pure stdlib, free). The point: no error was thrown, no test failed — but the numbers moved. PSI makes that visible.
Lab code — runs free
from math import log
def histogram(values, edges):
counts = [0] * (len(edges) - 1)
for v in values:
for i in range(len(edges) - 1):
hi_ok = v < edges[i+1] or (i == len(edges) - 2 and v == edges[-1])
if edges[i] <= v and hi_ok:
counts[i] += 1
break
total = sum(counts) or 1
return [c / total for c in counts]
def psi(expected, actual, edges):
e, a = histogram(expected, edges), histogram(actual, edges)
return sum((ai - ei) * log((ai + 1e-6) / (ei + 1e-6)) for ei, ai in zip(e, a))
edges = [0, 0.2, 0.4, 0.6, 0.8, 1.0]
baseline = [0.90, 0.85, 0.80, 0.95, 0.70, 0.88, 0.92, 0.78, 0.83, 0.91] # last month
this_week = [0.50, 0.55, 0.40, 0.60, 0.45, 0.70, 0.30, 0.65, 0.50, 0.42] # quality slipped
d = psi(baseline, this_week, edges)
print(f"PSI = {d:.2f} -> {'DRIFT — investigate' if d > 0.2 else 'stable'}")
PSI = 1.93 -> DRIFT — investigate
Last month's scores clustered high (0.7–0.95); this week's collapsed into the 0.3–0.7 bins. Nothing crashed — the service is up, no exception logged — but the quality distribution moved hard, and PSI (well above the 0.2 rule-of-thumb threshold) flags it loudly. This is the mechanism that turns a silent regression into a page: you watch the score distribution over time, not just uptime. In production you'd also alert on input drift (the questions changed) and feed the worst new cases back into your offline golden set — the flywheel.
Streamline: green offline, bleeding online
Streamline's assistant passed its offline eval at 89% and shipped. Weeks later, support escalations were climbing even though the offline number hadn't budged. The cause was drift: a product launch had changed what users asked, pushing real traffic toward topics the frozen eval set barely covered. Offline, the system looked stable; online, quality on the new question mix had quietly fallen to the 60s. The offline gate was answering "is this change good on last quarter's questions?" — not "is it working now?"
They added online evaluation: monitoring live quality signals, sampling real production conversations, and folding them back into the eval set on a schedule so it tracked reality. The regression became visible in days, not quarters. The lesson: offline evals catch what you anticipated; only online evaluation catches what you didn't — and a static eval set slowly stops describing a moving product.
This chapter: Remi is live. Meridian monitors resolution rate, escalation rate, and wrong-action rate on real traffic. When Meridian launches a new subscription tier, the question mix shifts and Remi's accuracy on the new billing topics drops — invisible to the frozen offline set, caught by sampling production tickets back in. They refresh the eval set and recover. (Ch 11: they make every Remi change pass the eval before it can ship.)
Quiz · Chapter 10
- The difference between guardrails and evals is:
- A "silent regression" is dangerous because:
- An LLM system can degrade with no code change because:
- The production→dataset→fix→ship→verify cycle is best described as:
- The highest-authority evidence that a change helped real users is: