From Local Traces to Production Observability for Google AI Agents A developer detailed a strategy for bringing observability to Google AI agents, moving from local trace trees to production monitoring via OpenTelemetry. The approach emphasizes capturing decision paths with spans and events, using application-owned attributes and reason codes to explain agent behavior without exposing sensitive chain-of-thought data. Most difficult agent incidents begin with one question: Why did the agent do that? Why did it call this tool? Why did it retry? Why did it skip the notification? Why did it trust stale data? Why was an action blocked even though every API call succeeded? Traditional logs often answer a narrower question: what executed? agent started model called tool called tool completed response sent That timeline is useful, but it loses causation. Agent systems are decision workflows. A run may include routing, model calls, tools, validation, memory, approval checks, retries, suppressions, and user feedback. Production observability must reconstruct that decision path without turning your telemetry system into a second database of sensitive prompts. During local development, I want to see the run as a tree before I want to search a production dashboard. proactive-hotel-agent 1,842 ms ├─ load-user-policy 18 ms ├─ detect-intent 312 ms ├─ search-hotels 486 ms ├─ compare-price 201 ms ├─ notification-policy 11 ms │ └─ blocked: quiet-hours └─ final-response 604 ms The tree immediately exposes parent-child relationships, missing steps, unexpected retries, and the point where the run changed direction. This is the local-to-production path I aim for: ADK / Genkit / Gemini application │ ├── model and tool spans ├── policy decision events ├── metrics and safe logs ▼ OpenTelemetry pipeline │ ┌─────┴───────────┐ ▼ ▼ Local trace view Cloud Trace / Logging / Monitoring │ ▼ alerts, dashboards, and analytics The tools can differ between development and production. The event shape should not. Create a span for an operation with measurable duration: an agent run, model request, tool execution, memory lookup, or policy evaluation. Attach an event when something meaningful happens inside that operation: a retry is scheduled, an action is blocked, confirmation is requested, or a fallback is selected. js import { SpanStatusCode, trace } from "@opentelemetry/api"; const tracer = trace.getTracer "travel-agent" ; async function tracedToolCall