Rubric
Contents — domains, guide and mocks

Observability at scale

CCAR-P 3.413 min read · checked 21 September 2026

Task statementAnalyze observability challenges and select monitoring strategies at scale

Layers of an LLM observability design

Top: is it useful? → bottom: is it up?

  1. Business outcomeresolution rate, escalations, user feedback
  2. Answer qualitysampled grading, refusals, stop reasons
  3. Cost and tokensper tenant, feature, model; cache hit ratio
  4. Agent traceseach model call and tool call in a run
  5. Service healthlatency percentiles, 429 / 529 / 5xx rates
Classic monitoring covers the bottom two layers. Claude systems also need the top three, because a request can succeed technically, cost too much, and still give the wrong answer.

Why Claude systems are hard to observe

Anthropic’s multi-agent research post is candid about the problem: agents behave differently across runs with identical prompts, small failures compound over long runs, and debugging without full production tracing is guesswork. At scale, six challenges recur, and each one points to a strategy.

ChallengeWhat it looks likeStrategy it calls for
Non-determinismA customer’s bad answer cannot be reproduced by re-running itCapture the run as it happened: trace with model, config and prompt versions
Silent quality failureHTTP 200, low latency, wrong answerQuality signals: sampled grading, stop-reason and refusal rates, user feedback
Long multi-step runsFailure appears at step 20, cause was step 3Hierarchical traces linking every model and tool call, including subagents
Volatile costToken use per task varies widely; multi-agent runs use far morePer-request usage, attributed by tenant, feature and model
Sensitive contentPrompts and tool results contain customer dataStructural telemetry by default; content only in approved, access-controlled stores
Volume and cardinalityMillions of calls; session IDs explode metric storageLow-cardinality metrics; IDs on sampled traces and events

Two of these deserve emphasis. Silent quality failure is what makes LLM monitoring different in kind: the transport layer succeeds, so every classic health check stays green. And cost volatility is real — the same post reports that multi-agent research used about fifteen times the tokens of a chat interaction, and that token usage alone explained most of the variance in quality. A cost spike may be a bug, or it may be the system doing more work because the task demanded it; only per-run data can tell you which.

What classic monitoring sees versus what you need

Classic APM alone

  • Uptime, error codes and mean latency
  • One request equals one unit of work
  • Full request logging is cheap and harmless
  • A green dashboard means users are fine

LLM-aware monitoring

  • Plus stop_reason, refusals, tool-call patterns, graded quality
  • One run spans many model and tool calls
  • Content is sensitive: structure by default, content by approval
  • Outcome metrics and sampled review confirm usefulness

Signal by signal: what to capture

Metrics answer “is something wrong?” cheaply, for every request. Track latency percentiles (time to first token and total), error rates by type — 429 rate limiting, 529 overloaded, 5xx, and errors that arrive mid-stream after a 200 — and tokens split into uncached input, cache reads, cache writes and output. Track the distribution of stop_reason: a rise in max_tokens or model_context_window_exceeded means truncated answers, and a rise in refusal means something changed in inputs or prompts. Rate-limit headers such as anthropic-ratelimit-input-tokens-remaining show headroom before you hit a wall. Keep metric labels low-cardinality — model, feature, tenant tier — so storage stays affordable.

Traces answer “what happened in this run?”. For agents built on the Claude Agent SDK, the CLI it runs can export OpenTelemetry spans: claude_code.interaction for a turn, claude_code.llm_request for each API call with model, latency and tokens, and claude_code.tool for each tool call, with subagent spans nested under the parent’s tool span so a whole delegation chain is one trace. The SDK propagates W3C trace context (TRACEPARENT), so the agent’s spans appear inside your application’s own trace rather than as a disconnected root. Tracing is enabled with CLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1 and is in beta.

Events and logs answer “exactly which request?”. Every API response carries a request-id header (the Python SDK exposes it as _request_id), which support needs and which joins your logs to Anthropic’s. Log it with the model, prompt and module versions, effort, stop_reason and usage. In Claude Code and the Agent SDK, events such as tool_result, api_request, api_error and tool_decision share a prompt.id that links everything one prompt caused.

Instrument each call with structure, not contentpython
from opentelemetry import trace
tracer = trace.get_tracer("claims-assistant")

def ask(messages, tenant, feature):
    with tracer.start_as_current_span("claude.request") as span:
        span.set_attribute("app.tenant_tier", tenant.tier)   # low cardinality
        span.set_attribute("app.feature", feature)
        span.set_attribute("app.prompt_version", PROMPT_VERSION)
        resp = client.messages.create(model=MODEL, max_tokens=2000,
                                      system=SYSTEM, messages=messages)
        u = resp.usage
        span.set_attribute("claude.request_id", resp._request_id)
        span.set_attribute("claude.stop_reason", resp.stop_reason)
        for key in ("cache_read_input_tokens", "cache_creation_input_tokens",
                    "input_tokens", "output_tokens"):
            span.set_attribute(f"claude.usage.{key}", getattr(u, key) or 0)
        # No prompt or answer text here: content goes only to an
        # approved, access-controlled store, if anywhere.
        return resp

One trace across the application and the agent

Your app
Agent SDK / CLI
Claude API
Tools
OTel collector
Step 1: Your app to Agent SDK / CLI: query() with active span
Step 2: Agent SDK / CLI : Reads TRACEPARENT
Step 3: Agent SDK / CLI to Claude API: llm_request span
Step 4: Agent SDK / CLI to Tools: tool span, subagents nested
Step 5: Agent SDK / CLI to OTel collector: Spans, metrics, events
Step 6: Your app to OTel collector: Parent span, same trace ID
Trace context flows from your service into the agent process, so model calls, tool calls and subagents appear under the user’s original request.

Scale: sample, attribute, and keep content under control

At millions of requests, keeping every trace in full is expensive and rarely useful. A common pattern is to keep metrics for everything, keep full traces for every error, truncation, refusal, unusually slow or unusually expensive run, and sample the healthy remainder. Quality needs its own sample: route a slice of production traffic to an automated grader — code checks where possible, a model-based rubric where necessary — and a smaller slice to human reviewers, as the evals post describes for offline testing. Read transcripts of failures; the evals post notes that reading them is what shows what the agent got wrong and why.

Attribution turns cost from a surprise into a signal. Tag every request with the tenant, feature and prompt version that caused it. In the Agent SDK, end-user and tenant identity can be added as OTEL_RESOURCE_ATTRIBUTES, because by default identity attributes describe your service’s credential, not the person the agent acted for — which also turns tool and permission events into a per-user audit trail for a SIEM. For the organisation’s authoritative numbers, the Usage and Cost Admin API reports usage grouped by model, workspace, API key and more, typically within about five minutes, and daily cost in USD. Use near-real-time telemetry for alerts and the Admin API to reconcile against the bill.

Content is the hardest call. The Agent SDK’s telemetry is structural by default: durations, model names, tool names and token counts, but not prompts, tool arguments, tool output or API bodies — each of those needs its own opt-in variable, and the docs advise leaving them off unless your pipeline is approved to store that data. Anthropic’s own research system monitors agent decision patterns and interaction structures without monitoring conversation contents. Follow that default: prove you need content for a specific diagnosis, capture it for a sample, redact it, restrict access and set retention (governance is covered in domain 5).

Which signal answers this question?

What do you need to know?
  • Is it up and fast?
    Metricsp95, error types, headroom
  • Why did this run fail?
    Tracemodel and tool spans, versions
  • Are answers still good?
    Sampled gradingcode, model and human review
  • Who is spending what?
    Attributed usagetelemetry plus Admin API
Choose the cheapest signal that answers the question at hand. Content capture is the last resort, not the default.

Traps the wrong answers are built from

Tempting but wrongDo this instead
Treating green uptime and error dashboards as proof the system worksAdd quality signals: stop reasons, tool-call patterns, sampled grading and outcomes.
Logging every prompt and response in full by defaultCapture structure everywhere; capture content only for approved, sampled, access-controlled use.
Debugging agent failures by re-running the inputKeep traces of the original run, tagged with model, config and prompt versions.
Putting session or user IDs on every metricKeep metric labels low-cardinality; put IDs on traces and events.
One shared key and no request tags in a multi-tenant systemAttribute every request by tenant, feature and version; split workloads by workspace.

You should now be able to

  • Explain why non-determinism, silent failures and multi-step runs make LLM systems hard to observe.
  • Select metrics, traces, events and sampled grading to match each observability question.
  • Propagate trace context so agent model and tool calls appear inside application traces.
  • Design cost attribution with request tags, workspaces and the Usage and Cost Admin API.
  • Control sensitive content in telemetry with structural defaults and opt-in, approved capture.
  • Keep observability affordable at scale with sampling and low-cardinality metrics.

Practice questions

Original questions written for this lesson, in the exam’s style. Answer first, then open the reasoning — every option is explained, including why the wrong ones are tempting.

  1. Question 1

    A travel company’s booking assistant has 99.9% availability and stable p95 latency. Yet the share of conversations ending in a completed booking has fallen by a quarter since a prompt change two weeks ago.

    Which monitoring addition would most directly have caught this earlier?

    1. AAlerting on HTTP 5xx rates with a lower threshold.
    2. BTracking tool-call rates and sampled quality grades per prompt version.
    3. CMeasuring mean latency instead of p95 latency.
    4. DLogging full prompts and responses for every conversation.
    Show answer and reasoning
    1. AIncorrect. The requests are succeeding at the transport level; lower thresholds on errors still see nothing.
    2. BCorrect. Behavioural and quality signals tied to the prompt version reveal a silent regression that uptime metrics cannot.
    3. CIncorrect. Latency is stable, and averages would hide more rather than less.
    4. DIncorrect. It creates a privacy and cost burden without, by itself, telling anyone that quality dropped.
  2. Question 2

    An insurer’s claims agent occasionally approves a claim it should have escalated. When engineers re-run the same claim, the agent escalates correctly every time.

    What should the architect put in place?

    1. ASet a fixed random seed so every run becomes reproducible.
    2. BIncrease the number of re-runs until the failure appears.
    3. CKeep traces of production runs with each model and tool call, tagged with versions.
    4. DRely on customer complaints to identify which runs to investigate.
    Show answer and reasoning
    1. AIncorrect. Re-running is not a reliable way to see what happened in the original run of a non-deterministic agent.
    2. BIncorrect. It may never reappear, and it wastes tokens while the real evidence is gone.
    3. CCorrect. Capturing the run as it happened is the documented answer to non-determinism; the trace shows which step went wrong.
    4. DIncorrect. Complaints arrive late and incomplete, and still leave nothing to inspect.
  3. Question 3

    A hospital group wants detailed monitoring of a clinical-documentation agent built on the Agent SDK. Compliance has not approved storing patient content in the observability platform. What is the best configuration?

    1. AEnable full API body logging but restrict dashboard access to engineers.
    2. BDisable all telemetry so no patient data can reach the platform.
    3. CExport content-free spans, metrics and events; keep content opt-ins off pending approval.
    4. DLog prompts but not responses, since prompts are shorter.
    Show answer and reasoning
    1. AIncorrect. It stores exactly the content compliance has not approved, whoever can view it.
    2. BIncorrect. It removes the structural signals that carry no content and are needed to operate the system.
    3. CCorrect. Telemetry is structural by default, and content capture is a separate opt-in that should stay off until approved.
    4. DIncorrect. Prompts contain patient information too; length is not the issue.
  4. Question 4

    A software company serves 2,000 business customers from one Claude deployment. The platform team proposes adding a customer ID and a session ID as labels on every metric so that finance can see cost per customer.

    What is the best response?

    1. AKeep metric labels low-cardinality; carry the IDs on request events and traces.
    2. BAccept it; metrics should carry every identifier that might be useful.
    3. CReject per-customer cost reporting; the monthly invoice is enough.
    4. DReplace telemetry with the Usage and Cost API grouped by customer.
    Show answer and reasoning
    1. ACorrect. This controls metric storage costs, while per-request events carrying the customer ID and token usage still let finance aggregate cost per customer.
    2. BIncorrect. Unbounded labels multiply metric series and storage costs at scale.
    3. CIncorrect. The invoice cannot attribute spend to customers or features, which finance needs.
    4. DIncorrect. The Admin API groups by model, workspace, key and similar dimensions, not by your customers.

Sources

Drafted with AI assistance and checked against the sources above; expert review is in progress. Spotted an error? Tell us and it gets fixed, dated and listed on how this is written.