Agent Observability Without Logging Chain-of-Thought
A privacy-preserving observability model for AI agents using structured traces, events, evidence IDs, policy decisions, tool receipts, budgets, and outcomes.
When an agent malfunctions, engineers commonly ask: Show me what the model was considering during its decision-making process. This request merges two distinct requirements. Researchers may analyze model reasoning, while operators need to understand which model version was utilized, the context it observed, the data it accessed, the suggested actions, the rationale behind policy approvals or denials, the tool's execution, budget status, and the termination reason.
Recording the hidden chain-of-thought reasoning does not effectively answer these inquiries. It risks exposing confidential information, fosters a misleading sense of explanation, and may fail to capture the precise code path that generated the external outcome. Agent observability should focus on documenting the execution, rather than trying to interpret a model's thoughts.
To begin, employ three separate records instead of a single comprehensive "agent log." A trace connects the various operations with their respective durations, encompassing model calls, retrieval operations, policy evaluations, tool executions, approvals, checkpoint reads and writes. Events capture specific point-in-time state changes: RUN_ADMITTED, MODEL_PROPOSED, TOOL_POLISHED, POLICY_DENIED, TOOL_STARTED, TOOLS_RECORD_RECEIVED, APPROVAL_GRANTED, CHECKPOINT_WRITTEN, and RUN_COMPLETED.
OpenTelemetry's event guidance specifically recommends using events for checkpoint events, state transitions, lifecycle moments, and outcomes, which aligns well with agent runtime operations.
Audit receipts are crucial for high-impact decisions and effects. They provide proof of canonical request hashes, actor and tenant identities, policy decisions and versions, approval identities and scopes, external transaction or object IDs, committed outcomes, and integrity metadata. Traces assist in diagnosing issues, events elucidate the progression, and receipts ensure accountability. These can share correlation IDs without becoming an identical data store.
Model the agent's runtime as a state machine to establish clear observability. Define states like ADMITTED, PLANNING, WAITING_MODEL, WAITING_TOOL, WAITING_APPROVAL, RUNNABLE, COMPLETED, FAILED, CANCELED, and EXPIRED. Every state transition should record the event name (e.g., agent.state.transition), run ID and task ID, the current and next states, the reason code explaining the transition (e.g., TOOL_RECEIPT_CONFIRMED), the graph version (e.g., support-31), the attempt number, budget delta (e.g., tool_calls: -1, milliseconds: -842), and the trace ID.
This record does not require the model's internal reasoning. Instead, it documents what the runtime performed and why, using a controlled reason code. Operators can then ask critical operational questions: which state accumulates the most wait time? Which transition commonly triggers retries? Which graph version frequently results in cancelations?
Which tool expires its lease most often? Where does cost escalation occur without improving success rates? These are operational questions with clear operational answers.
When recording model calls, treat them as versioned dependencies. The model span should include the provider and model identifier, endpoint or deployment version, prompt-template ID and hash, sampling configuration, input/output token counts, cached tokens where available, finish reason, latency, queue time (if exposed), and any errors.
It is essential not to assume the model name fully identifies its behavior. Hosted deployments can change; prompts, tools, retrieval mechanisms, and policies also influence the outcome. Record every version needed to reproduce the task. Content should be opt-in and scoped according to risk levels. The OpenTelemetry GenAI attribute registry advises using hashes, length buckets, classifications, and controlled references to protect sensitive information.
Telemetry should not be exempt from privacy, retention, or access control restrictions. Raw content should only be captured in a restricted debug lane, accompanied by purpose, expiry, and audit details. Content within this lane should remain separate from the main trace.
Evidence should be treated as a first-class object. A simple statement like "the agent used RAG" is insufficient. For each retrieval operation, record the query ID and safe hash, corpus and index versions, embedding and reranker versions, filters and tenant scope, returned document or chunk IDs, scores and ranking, document version and integrity hash, and whether the final response cited or relied on that evidence.
Large content should reside in governed storage, with the trace retaining references to it. This approach addresses the important counterfactual: did the model fail despite having access to the correct evidence, or did the retrieval process fail before generation? It also distinguishes model regressions from corpus updates. Separating proposal, policy, and execution facts for a tool call is essential.
Clearly record: what the model requested (after safe structural parsing), the deterministic policy conclusion (including decision, reason, and policy version), and what the tool gateway actually performed and what the receipt returned (effect ID, canonical request hash, status). Never merge these facts into a single "agent called refund."
A model may propose an action that policy rightfully denies, which is a valuable quality signal, not a security breach. If execution occurs despite a policy denial, that indicates a control failure. The observability model must allow incident responders to differentiate these situations immediately.
The observability model should use controlled reasons rather than generating human-facing explanations. Provide enumerable codes such as INVALID_TOOL_SCHEMA, POLICY_DENIED, APPROVAL_EXPIRED, DEPENDENCY_TIMEOUT_UNKNOWN, BUDGET_EXHAUSTED, EVIDENCE_INSUFFICIENT, USER_CANCELED, LEASE_LOST, POSTCONDITION_FAILED, etc. These codes enable aggregation and alerting.
Attach a concise redacted summary for human operators, but ensure the authoritative root cause is not the free-form model text. The true cause may reside outside the model itself—such as queue saturation, stale credentials, an index rollout, a policy bug, or duplicate callbacks. Finally, trace cost and budgets meticulously. One user request can generate multiple model calls, retrievals, and tool executions.
Record budget information at admission and the delta per step, including model calls, input/output tokens, retrieval queries and documents, tool calls, retries, wall-clock time, and estimated versus actual costs. Analyze cost per successful terminal outcome rather than per model call. A cheaper model that requires more retries or tool executions might ultimately incur higher costs.
An agent that succeeds only after multiple failures may become prohibitively expensive. By capturing these details, operators can better understand the true cost implications of different agent configurations and operational strategies.
Written by urgent.news from HackerNoon's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.