Skip to content
GuideAI Ops
Xither Staff13 min read

AI Ops · Operations guide

LLM Observability and Safe Releases: Logging, Metrics, Canary, and A/B Testing

Treat every model, prompt, or routing change as a production release: structured logs for every invocation, four metric families (latency, tokens and cost, output quality, drift), canary rollouts with automated rollback criteria, and A/B tests reserved for proving effectiveness once stability is proven. The platform tooling already exists; this guide covers what to capture, what to alert on, and when to promote or roll back.

In this guide · 8 steps
  1. 01By the numbers
  2. 02Why LLM observability is not service observability
  3. 03The logging layer: capture everything, redact before it lands
  4. 04Metrics that matter: latency, tokens, quality, drift
  5. 05Safe releases: canary first, with rollback criteria you wrote down in advance
  6. 06A/B testing: proving better, not just proving safe
  7. 07Honest objections
  8. 08The read

An LLM system changes constantly — new model versions, edited prompts, retrieval tweaks — and each change can regress quality without throwing an error. The answer is one pipeline: log every invocation in structured form, watch the few metrics that predict failure, ship changes behind a canary, and use A/B tests to prove a change is better, not just stable.

1. By the numbers

Off by default

Amazon Bedrock's model invocation logging — the capability that captures full request and response data per call — is disabled by default and must be explicitly enabled with a CloudWatch Logs or S3 destination.[^aws-bedrock-invocation-logging]

Amazon Bedrock User Guide

100 KB

The inline size cap on input and output JSON bodies in each Bedrock invocation log record; larger payloads and binary data are written to S3 as separate objects instead.[^aws-bedrock-invocation-logging]

Amazon Bedrock User Guide

~5 minutes

How quickly usage and cost data typically appears in Anthropic's Usage and Cost Admin API after an API request completes — recent enough to drive near-real-time spend and rate-limit dashboards.[^anthropic-usage-cost-api]

Anthropic API docs

2 steps vs. n steps

SageMaker's canary traffic shifting moves traffic to a new fleet in two steps (canary portion, then the rest), while linear shifting extends this to n linearly spaced steps — each guarded by CloudWatch alarms during a baking period.[^aws-sagemaker-guardrails]

Amazon SageMaker Developer Guide

2. Why LLM observability is not service observability

Classic service monitoring assumes failures are loud: error codes, timeouts, saturated queues. LLM systems add a class of quiet failures — a response that is fluent, fast, HTTP 200, and wrong. A prompt edit that improves one workflow can silently degrade another. A vendor-side model update can shift tone, verbosity, or refusal behavior with no change in your code. So the observability stack has to capture what the model actually said, not just whether it answered, and the release process has to gate on quality signals, not just availability signals.

DimensionTraditional serviceLLM system
Failure modeErrors, timeouts, crashes — visible in status codesPlausible-but-wrong output at HTTP 200; quality regressions invisible to infrastructure metrics
What logs must captureRequest path, status, durationFull prompt, full response, model/version, token counts, caller identity, request metadata
Regression detectionError-rate and latency alarmsEval suites, drift statistics, human review samples — alarms alone miss quality loss
Release riskMostly deterministic: same input, same behaviorNon-deterministic output; behavior shifts across model versions and even prompt phrasing
Rollback triggerAlarm on 5xx rate or latencyAlarm on those plus quality metrics scored against the canary's live traffic
What changes when the deployable artifact is a model-plus-prompt rather than code.

That difference drives everything else in this guide. The logging layer exists so that quality regressions are reconstructable after the fact. The metrics layer exists so that some of them are catchable in near real time. Canary and A/B mechanics exist so that the blast radius of a bad change is a slice of traffic, not all of it. This piece stays at the LLM layer; for classical model monitoring (feature drift, retraining triggers) see /guides/model-monitoring-production-guide, and for the CI/CD scaffolding these releases ride on, see /guides/production-ml-pipelines-guide.

3. The logging layer: capture everything, redact before it lands

Structured logging is the foundation the rest of the stack sits on. Console strings and free-text app logs cannot answer the questions that matter after an incident: which prompt version produced this output, at what temperature, for which caller, at what cost. Every LLM invocation should emit one structured record with, at minimum: the full prompt (including system messages), the full response, model identifier and version, request and response timestamps, input and output token counts, a request ID that correlates across your distributed trace, the caller's identity or session (pseudonymized), configuration parameters, and any error detail. Machine-readable formats — JSON events into your existing log pipeline — beat bespoke text formats because every downstream consumer, from cost dashboards to eval harnesses, parses the same record.

The major platforms now ship this capture layer as configuration rather than code. Amazon Bedrock's model invocation logging collects "the full request data, response data, and metadata" for supported calls in an account and Region, publishing to CloudWatch Logs, S3, or both — and it is disabled by default, so enabling it is an explicit setup step, not something you inherit.[1] Each log entry is a JSON object carrying the model ID, the request ID, input and output bodies (up to 100 KB inline; larger bodies go to S3), and — usefully for chargeback — automatic capture of the caller's IAM principal in an identity field, plus an optional caller-supplied requestMetadata object for tags like team or environment.[1] Token counts per request come along for free, which means a CloudWatch Logs Insights query grouped on the identity field is a working cost-attribution report before you build anything.

On Azure, the same discipline applies with a different mechanism: platform metrics are collected automatically, but resource logs "aren't collected and stored until you create a diagnostic setting" routing them to Log Analytics or another destination — another default-off capture layer that teams discover is empty exactly when they need it.[4] Whatever the platform, the operational rule is the same: turn on invocation-level capture on day one, in every environment, because you cannot retroactively log the incident that already happened.

Redaction happens before the log store, not after

Inline guardrails do not sanitize your logs. AWS documents that even when a Bedrock guardrail masks PII in a conversation, "the input field in Amazon CloudWatch Logs always contains the original, unmodified request regardless of guardrail intervention," and PII the model writes into tool-call arguments, tool results, or tool definitions "is neither blocked nor masked."[5] Your logging pipeline needs its own redaction pass upstream of the log store — and assume the equivalent gap on any platform until its documentation proves otherwise. The full data-plane redaction playbook is at /guides/personal-data-protection-ai.

Two design decisions deserve deliberate answers rather than defaults. First, sampling: full-fidelity logging of every prompt and response is the right starting posture, but at high volume the storage and query bill becomes material, and a policy of logging all flagged or errored requests plus a sampled share of the rest is a defensible steady state — as long as the sampling decision is itself logged. Second, retention: invocation logs are a compliance asset (traceability of what was sent to and returned from a model) and a liability (a growing store of user content), so retention windows belong in your data-governance policy, not in whatever the log platform happens to default to.

4. Metrics that matter: latency, tokens, quality, drift

Dashboards fail by measuring what is easy instead of what predicts failure. Four metric families cover the failure modes that actually occur in production LLM systems.

Latency — measured the way streaming makes it feel

A single end-to-end latency number misleads for streaming LLMs, because the user's experience is dominated by time to first token, then by the steadiness of the stream. Microsoft's monitoring guidance for Azure OpenAI makes this explicit, steering teams to three purpose-built latency metrics — Time to Response, Time to Last Byte, and Time Between Tokens — rather than the legacy aggregate latency metric.[4] Track those (or their equivalents from client-side instrumentation) at tail percentiles per model and endpoint, because average latency hides exactly the requests your users complain about. And instrument on your side of the wire as well as the vendor's: queueing, retries, and guardrail passes all add latency the provider's dashboard never sees.

Tokens and cost — the meter that is also the throttle

Token telemetry serves two masters: finance and capacity. On the finance side, first-party usage APIs have matured to the point that scraping response objects is no longer the only option. Anthropic's Usage and Cost Admin API, for example, reports token consumption bucketed at one-minute, one-hour, or one-day granularity, filterable and groupable by API key, workspace, model, and service tier, with separate counts for uncached input, cached input, cache-creation, and output tokens, plus a daily cost endpoint reporting USD amounts.[2] That per-workspace grouping is the chargeback mechanism: one workspace per team or product, and attribution falls out of the API rather than out of a spreadsheet.

On the capacity side, the same telemetry is your early warning for throttling. Anthropic enforces rate limits per model class in requests, input tokens, and output tokens per minute; exceeding any of them returns a 429 with a retry-after header, and every response carries anthropic-ratelimit-* headers reporting the limit, remaining budget, and reset time.[6] Log those headers on every call — they are free observability. Cache behavior belongs on the same dashboard: for most Claude models, cached input tokens do not count toward the input-token rate limit, so cache hit rate directly buys effective throughput as well as cost.[6] The full cost-optimization playbook — caching, batching, model right-sizing — lives at /guides/llm-finops-guide; the observability requirement here is simply that token and cost data reach the same dashboard as latency and errors, at the same granularity, attributed to the same teams.

Output quality and hallucination — the metric without a free ground truth

Fabricated-but-fluent output is the risk that most distinguishes generative systems, prominent enough that NIST's Generative AI Profile (NIST AI 600-1, published July 2024) exists as a dedicated companion to the AI Risk Management Framework for exactly this class of generative-AI-specific risk.[7] The measurement problem is structural: in live traffic there is usually no reference answer to score against. Production practice therefore layers proxies: automated checks that need no ground truth (does the cited document exist in the retrieval corpus, does the extracted field appear in the source text, does the JSON parse against schema), LLM-as-judge or classifier scoring on a sampled slice, and a small, steady stream of human review on flagged and random samples. None of these is a hallucination rate in the strict sense; together they are a trend line, and the trend line is what release decisions need. The essential engineering choice is to compute these scores from the structured logs you are already writing, so every quality metric is reconstructable and re-scorable when your eval method improves.

Drift — inputs move even when the model doesn't

Drift in LLM systems has two directions. Input drift: users bring new topics, languages, and phrasings, and your prompts and retrieval corpus quietly fall out of coverage — detectable with embedding-distribution comparisons between a reference window and current traffic, plus mundane proxies like retrieval-miss rate and out-of-scope classification rate. Behavior drift: the model's own outputs shift, either because a vendor updated the model behind an alias or because your accumulated context changed. The defense is the same for both: pin model versions explicitly wherever the platform allows, record the exact model identifier in every log record, and re-run a fixed eval suite on a schedule so that a shift in scores with an unchanged suite is unambiguous evidence the system moved. Statistical drift tooling from classical ML monitoring carries over largely intact; /guides/model-monitoring-production-guide covers that machinery in depth.

5. Safe releases: canary first, with rollback criteria you wrote down in advance

A canary deployment is a progressive rollout of an application that splits traffic between an already-deployed version and a new version, rolling it out to a subset of users before rolling out fully.[^gcp-clouddeploy-canary]
Google Cloud Deploy documentation

The canary pattern transfers directly from software delivery to LLM releases — and matters more, because non-determinism means pre-production testing can never fully predict live behavior. The managed implementations are worth studying even if you build your own. SageMaker's deployment guardrails run blue/green deployments with three traffic-shifting modes: all-at-once, canary — which "shifts one small portion of your traffic" to the new fleet and monitors it for a baking period before shifting the rest — and linear, which generalizes the shift to n evenly spaced steps; in every mode, pre-specified CloudWatch alarms watch the new fleet during the baking period, and a tripped alarm triggers automatic rollback before the old fleet is terminated.[3] Google Cloud Deploy structures the same idea as named phases — configure increments of 25, 50, and 75 percent and the rollout advances through canary-25, canary-50, and canary-75 phases before a final stable phase at full traffic.[8]

What changes for LLMs is not the traffic mechanics but the promotion criteria. An LLM canary that only alarms on error rate and latency will happily promote a model version that answers faster and worse. The canary window is where your quality metrics earn their keep: score the canary's live outputs with the same automated checks and judge models you run in monitoring, compare against the baseline fleet over the same window, and make those scores part of the written promotion criteria alongside the infrastructure alarms. Two further LLM-specific rules: keep the prompt and the model from changing in the same release, because a confounded canary teaches you nothing; and hold back a shadow option — replaying or teeing traffic to the candidate without serving its responses — for changes too risky to expose to any users at all.

Rollback is a capability you build, not a button you hope for

Automatic rollback only works if the old version still exists and still serves. Keep the previous model version, prompt version, and configuration deployable at all times; version prompts as artifacts with the same rigor as code; and rehearse the rollback path before the release, not during the incident. Managed platforms terminate the old fleet only after the baking period passes cleanly — mirror that discipline in anything you self-host.[3]

6. A/B testing: proving better, not just proving safe

Canary and A/B testing use the same traffic-splitting machinery and are routinely conflated, but they answer different questions. A canary asks: does the new version misbehave? It is short-lived, weighted small, and biased toward rollback. An A/B test asks: is the new version better on the outcomes we care about? It needs balanced assignment, a pre-registered metric, and enough volume and time to separate signal from noise. Run them in sequence — canary to establish safety, then an A/B test to establish superiority — rather than letting one masquerade as the other.

AspectCanary releaseA/B testShadow test
Question answeredIs the new version safe at production scale?Is the new version measurably better?How would it behave, without user exposure?
Traffic splitSmall, temporary, ramping upwardFixed shares, held stable for the test windowDuplicate traffic; candidate responses not served
AssignmentAny slice (weighted, cohort, region)Randomized per user/session, sticky for multi-turnN/A — mirrored requests
Primary metricsErrors, latency, live quality scores vs. baselineTask success, user outcomes, business KPIsOutput diffs, quality scores, cost and latency profile
Ends withPromote or roll backAdopt, reject, or iterateGo/no-go for a canary
Three release-testing patterns that share infrastructure but answer different questions.

The statistics of LLM A/B tests are standard experimentation practice with two sharp edges. First, assignment consistency: in multi-turn applications, users must be sticky to one variant for a whole session, or you are testing a chimera neither version produced. Second, metric choice: automated quality scores are noisy proxies, so anchor the test on the closest available measure of task success — resolution rate, edit distance on accepted drafts, task completion, escalation rate — and treat judge-model scores as supporting evidence. Decide the sample size, test duration, and significance threshold before the test starts; a test whose stopping rule is "when the numbers look good" is a coin flip with paperwork. And log the variant identifier into the same structured invocation record as everything else, so the analysis is a query, not an archaeology project.

7. Honest objections

The strongest counterargument to all of this is cost and drag. Full invocation logging at volume is a real storage and egress bill; judge-model scoring spends tokens to watch tokens; canary infrastructure means running two model fleets, which for self-hosted LLMs can mean double the accelerator footprint during every release window. A small team shipping a low-stakes internal assistant can reasonably run on the provider's built-in dashboards, a fixed eval suite in CI, and manual staged rollouts — and many should. The graduation trigger is consequence, not sophistication: the day model output touches customers, revenue, or regulated decisions, quiet failures become expensive, and the pipeline above becomes cheaper than the incidents it prevents.

A second objection: A/B testing LLM versions is statistically treacherous — high output variance, noisy quality metrics, novelty effects — and a poorly designed test can bless a regression. True, and the answer is to narrow claims, not to skip testing. Prefer coarse, robust outcome metrics over fine-grained quality scores; run longer than intuition suggests; and when traffic volume genuinely cannot support inference, say so and fall back to offline evals plus canary-with-human-review rather than dressing anecdotes in confidence intervals. Finally, some will object that vendor-managed platforms make half this guide someone else's job. The capture layers, usage APIs, and deployment guardrails cited here are genuinely good — but note that every one of them ships default-off, scoped to its own silo, and blind to your prompts, retrieval, and business outcomes. What the vendor operates is the telemetry; what remains irreducibly yours is the decision layer on top of it.

8. The read

The decision this supports: fund LLM observability and release engineering as one capability, not two projects. The same structured invocation log feeds the cost dashboard, the quality trend line, the canary promotion decision, and the A/B analysis — build it once, on day one, with redaction upstream and versions pinned. Buy the capture and traffic layers from your platform (they are configuration, and they are good); build the quality-scoring and promotion-criteria layer yourself, because it encodes what your business means by "better." And measure the whole effort against one standard: when a bad release ships — and one will — how many minutes pass before you know, and how many more before the previous version is serving again.

How to apply this

  • Enable invocation-level logging on every platform you use, in every environment — Bedrock invocation logging, Azure diagnostic settings, or your own middleware — and verify records actually land; most platform capture layers are off by default.
  • Define one structured log schema per LLM call: prompt, response, model ID and version, prompt version, timestamps, token counts, request ID, pseudonymized caller, parameters, error detail, and (during tests) variant ID.
  • Put a redaction pass upstream of the log store; do not assume inline guardrails sanitize logs — documented behavior says they don't (see /guides/personal-data-protection-ai).
  • Dashboard four metric families side by side: streaming-aware latency at tail percentiles, tokens and cost attributed per team via provider usage APIs, output-quality trend lines from automated checks plus sampled review, and input/behavior drift against a pinned baseline.
  • Log rate-limit headers and alert on remaining-budget burn, not just on 429s.
  • Write promotion and rollback criteria before each release: infrastructure alarms plus quality-score thresholds versus baseline over the canary window.
  • Roll out via canary or linear traffic shifting with a baking period and automated rollback; never change model and prompt in the same release.
  • Keep the previous model, prompt, and configuration hot and deployable; rehearse rollback quarterly.
  • Reserve A/B tests for effectiveness questions: randomized sticky assignment, pre-registered outcome metric, fixed duration — then adopt, reject, or iterate.
  • Revisit sampling and retention policies quarterly as volume grows; log the sampling decision itself.

Sources

Every quantitative or attributed claim above is linked to a primary source. Last verified at publication.

  1. [1]
  2. [2]
    Usage and Cost API — Anthropic API documentation
    Anthropic · accessed
  3. [3]
  4. [4]
    Monitor Azure OpenAI — Microsoft Learn
    Microsoft · accessed
  5. [5]
  6. [6]
    Rate limits — Anthropic API documentation
    Anthropic · accessed
  7. [7]
  8. [8]
Steps8