{"slug": "ai-agent-observability-with-opentelemetry", "title": "AI Agent Observability with OpenTelemetry", "summary": "OpenTelemetry, a CNCF graduated project, provides vendor-neutral tracing, metrics and logs that engineers can use to capture each step of an AI agent's execution path, according to an explainer on AI agent observability. The piece argues that agents chain multiple non-deterministic LLM calls, so a single user request can spawn dozens of internal steps, making silent failures, unpredictable cost and latency, and run-to-run variance hard to diagnose without full tracing of tool selection, context and model outputs.", "body_md": "# AI Agent Observability with OpenTelemetry\n\nAI agents don't just call a model and return its response. Instead, they orchestrate entire workflows that involve selecting tools for LLMs to use, evaluating guardrails, routing between LLM calls, and managing context across conversation turns. This means that a single user request can spawn dozens of internal steps, each one a potential point of failure, latency, or unexpected cost.\n\nAI agent observability is the practice of capturing these execution flows so you can understand *what* the agent did, *why* it chose that path, and *how* it performed. In practice, this means tracing an agent run's execution path, capturing inputs and outputs at each step, and tracking cost, token usage, latency, and error rates.\n\nAI agent tracing builds the foundation for AI agent observability. Without tracing, debugging an AI agent becomes a game of trying to guess which event triggered what decision in the agent workflow, and why.\n\n## Why do AI agents need observability?\n\nA request can return successfully while the agent gives an incorrect answer, takes too long on a particular step, or triggers duplicate LLM or tool calls. Agent observability gives engineers the evidence to investigate these problems and compare behavior across runs.\n\nLet's look at some of these problems in more detail.\n\n### LLM non-determinism compounds across agent steps\n\nA single LLM call is already non-deterministic: the same prompt can produce different outputs across runs. Agents amplify this because they chain multiple LLM calls together, where the output of one step determines the input of the next.\n\nThis means variance doesn't just exist at one point. Rather, it compounds across the workflow. A slightly different model response in step one can cause the agent to select a completely different tool in step two, which changes the context passed to step three, and so on. Reproducing a specific agent run becomes nearly impossible without capturing the full execution path.\n\n### Agents can silently produce incorrect results\n\nTraditional software can also return incorrect results without throwing an error. With agents, these failures can be harder to catch because each run can take a different path: the workflow completes without any error, but the agent selected the wrong tool, retrieved stale context, or returned a response that is confidently incorrect.\n\nWithout observability, these silent failures only surface when a user complains or when downstream systems consume bad output. Tracing each decision in the agentic loop, such as which tool was selected, what context was available, what the model actually returned, is the only reliable way to evaluate whether an agent's \"successful\" run was actually logically correct.\n\n### Cost and latency are unpredictable by design\n\nAgents decide at runtime how many tools to call and how many LLM roundtrips to make. A simple user query might resolve in one LLM call, while a similar query might trigger several tool calls and model invocations depending on the agent's reasoning.\n\nThis makes cost and latency inherently unpredictable. Observability lets engineers track token usage, tool call frequency, and per-step latency across runs to identify expensive patterns early. For example, if two models with different pricing tiers perform comparably for a given workload, engineers can switch to the cheaper option — but only if they have the data to make that comparison.\n\n## How does OpenTelemetry enable AI agent observability?\n\n[OpenTelemetry](https://signoz.io/opentelemetry/) (OTel) is a CNCF graduated project for instrumenting applications to emit telemetry data (primarily [traces, metrics, and logs](https://signoz.io/blog/three-pillars-of-observability/)) in a vendor-neutral format. What makes it uniquely suited for agentic applications is that your visibility extends beyond the AI agent to the entire request: what endpoint did the user call, what DB queries ran, were any background jobs enqueued, did the application make any downstream API calls?\n\n## Setting up AI agent observability with OpenTelemetry\n\n### Prerequisites\n\n- Python 3.12 or newer. Download the [latest version](https://www.python.org/downloads/) .\n- A [SigNoz Cloud account](https://signoz.io/teams/) for visualizing telemetry data.\n- An [OpenAI API key](https://platform.openai.com/api-keys) to run the agent.\n- An API client like [Bruno](https://www.usebruno.com/) or[Postman](https://www.postman.com/) to test endpoints.\n\n### Setting up SigNoz Cloud\n\nSigNoz Cloud is an OpenTelemetry-native observability platform that unifies traces, metrics, and logs in a single interface.\n\n- [Sign up](https://signoz.io/teams/) for a free SigNoz Cloud account.\n- [Follow the documentation](https://signoz.io/docs/ingestion/signoz-cloud/keys/) to generate an ingestion key.\n- Keep your workspace region (e.g., `us` ,`in` ,`eu` ) and ingestion key handy for the application configuration.\n\n### Running the Demo Application\n\nClone and navigate to the demo application:\n\n```\ngit clone --filter=blob:none --sparse https://github.com/SigNoz/examples.git\ngit -C examples sparse-checkout set python/otel-ai-agent-observability-demo\ncd examples/python/otel-ai-agent-observability-demo\n```\n\nCreate and activate a Python virtual environment:\n\n```\npython3.12 -m venv .venv\nsource .venv/bin/activate\n```\n\nInstall the application and [OpenTelemetry Python](https://signoz.io/opentelemetry/python/) dependencies:\n\n```\npip install -r requirements.txt\n```\n\nThe [`requirements.txt` file](https://github.com/SigNoz/examples/blob/main/python/otel-ai-agent-observability-demo/requirements.txt) pins the following OTel packages:\n\n- `opentelemetry-distro` : Provides a convenient mechanism to configure some of the more common options for Python auto-instrumentation.\n- `opentelemetry-exporter-otlp` : Installs[the OTLP exporters](https://signoz.io/blog/what-is-otlp/) needed to deliver telemetry data to any[OpenTelemetry-compatible backend](https://signoz.io/blog/opentelemetry-backend/) .\n- `opentelemetry-instrumentation-genai-openai` and`opentelemetry-instrumentation-genai-openai-agents` : Modern OpenAI Agents and OpenAI Python API instrumentation packages from the dedicated[OpenTelemetry GenAI repository](https://github.com/open-telemetry/opentelemetry-python-genai) .\n\nNext, run `opentelemetry-bootstrap` to detect widely used Python libraries (like the [FastAPI web framework](https://signoz.io/blog/opentelemetry-fastapi/) and HTTPX client library) and install their corresponding instrumentation packages:\n\n```\nopentelemetry-bootstrap --action=install\n```\n\nStart the application using `opentelemetry-instrument` to automatically instrument our application, including the AI agent workflow:\n\n```\nOPENAI_API_KEY=\"<your-openai-api-key>\" \\\nOTEL_EXPORTER_OTLP_ENDPOINT=\"https://ingest.<your-region>.signoz.cloud:443\" \\\nOTEL_EXPORTER_OTLP_HEADERS=\"signoz-ingestion-key=<your-ingestion-key>\" \\\nOTEL_SERVICE_NAME=\"otel-ai-agent-observability-demo\" \\\nOTEL_RESOURCE_ATTRIBUTES=\"service.version=1.0.0,deployment.environment=dev\" \\\nOTEL_EXPORTER_OTLP_PROTOCOL=\"http/protobuf\" \\\nOTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=span_only \\\nopentelemetry-instrument fastapi run --port 8085 --workers 1\n```\n\nHere is what these [OpenTelemetry environment variables](https://signoz.io/blog/otel-environment-variables/) configure:\n\n- `OTEL_SERVICE_NAME=\"otel-ai-agent-observability-demo\"` : Uniquely identifies the application in SigNoz Cloud.\n- `OTEL_RESOURCE_ATTRIBUTES` : Attaches metadata (version`1.0.0` , environment`dev` ) to all exported telemetry. This is used to organize and filter telemetry in the OpenTelemetry backend.\n- `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=span_only` : Captures model prompts, completions, and tool definitions as span attributes on LLM model spans.\n\nThe FastAPI server starts on port 8085. Calling `/` returns a quick health check response:\n\n```\n(.venv)  ❯ curl \"http://127.0.0.1:8085/\"\n{\"message\":\"OpenTelemetry NBA agent demo is running\"}\n```\n\nThe demo is now running. Before exploring the agent code, let’s look at the OpenTelemetry conventions and instrumentation packages used to capture AI agent workflows.\n\n### Understanding OpenTelemetry’s evolving GenAI conventions\n\nWhile early instrumentation discussions focused solely on \"LLM tracing\", OpenTelemetry standardizes AI telemetry under the broader umbrella of `Generative AI` (GenAI), using [semantic conventions prefixed with `gen_ai.*`](https://github.com/open-telemetry/semantic-conventions-genai/blob/4f85037ef86e92c510d2ef881a58f1076f6fc0e4/docs/gen-ai/README.md).\n\nBecause GenAI patterns and agentic harnesses evolve far more rapidly than traditional HTTP or database libraries, OpenTelemetry created a dedicated repository, [`open-telemetry/opentelemetry-python-genai`](https://github.com/open-telemetry/opentelemetry-python-genai), to enable maintainers to independently develop and publish these libraries.\n\nThis migration introduced a cleaner, **split-scope architecture**:\n\n1. **`opentelemetry.instrumentation.genai.openai_agents`** : Instruments the agent orchestration harness, emitting spans for workflow execution (`invoke_workflow` ) and agent routing (`invoke_agent` ).\n2. **`opentelemetry.instrumentation.genai.openai`** : A companion package that instruments the underlying model calls (`chat` ), capturing token usage (`gen_ai.usage.input_tokens` ,`gen_ai.usage.output_tokens` ), model parameters, and prompt context.\n\nThe [earlier Agents instrumentation](https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2) combined workflow and model-call tracing in a single package.\n\nAdditionally, because `opentelemetry-bootstrap` has not yet added these dedicated GenAI packages to its automated discovery list, you must install and track them separately through your `requirements.txt` or `pyproject.toml` files.\n\n### How the NBA agent uses tools, guardrails, and sessions\n\nNow that we've seen how OpenTelemetry separates agent orchestration from model calls, let's look at the code behind the NBA agent's workflow. [Skip to the next section](#visualizing-ai-agent-workflows-with-opentelemetry) if you want to jump directly to generating and inspecting traces.\n\nFastAPI serves our HTTP endpoints, the [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) manages the agent loop, and the OpenAI Python API library handles the underlying model calls. This separation is why we instrument both the Agents SDK and the API library: one captures the workflow, while the other captures each model call.\n\n#### The core agentic setup\n\nOur web application exposes an NBA Reporter agent that answers questions on NBA topics (e.g., `general` news or `finals`), performs web research, calculates team win percentages, and retains conversation history across turns via server-managed session persistence.\n\nThe [`agent_service.py` file](https://github.com/SigNoz/examples/blob/main/python/otel-ai-agent-observability-demo/app/agent_service.py) defines the agent configuration and the execution function used by our FastAPI endpoint.\n\nWe initialize the agent with a system prompt, tools, input guardrails, and model selection. The application uses **`gpt-6-luna`** (` OPENAI_MODEL = \"gpt-6-luna\"` in `app/config.py`), which delivers consistent multi-turn reasoning and tool formatting:\n\n```\nNBA_AGENT = Agent(\n    name=\"NBA_Reporter\",\n    instructions=NBA_INTERACTIVE_PROMPT,\n    tools=[WebSearchTool(), calculate_win_percentage],\n    input_guardrails=[nba_content_guardrail],\n    model=OPENAI_MODEL,\n)\n```\n\nThe `calculate_win_percentage` function tool gives the agent a deterministic way to calculate and display team win percentages without the risk of arithmetic hallucinations:\n\n``` php\n@function_tool\ndef calculate_win_percentage(wins: int, losses: int) -> str:\n    \"\"\"Calculates the winning percentage for an NBA team given their wins and losses.\"\"\"\n \n    total_games = wins + losses\n    if total_games == 0:\n        return \".000\"\n \n    return f\"{wins / total_games:.3f}\".lstrip(\"0\")\n```\n\nTo prevent misuse or off-topic queries, we define an input guardrail. When a user prompt does not match relevant basketball keywords, the function returns a `GuardrailFunctionOutput` with `tripwire_triggered=True`:\n\n```\napp/guardrails.py\npython\n@input_guardrail()\ndef nba_content_guardrail(\n    context: RunContextWrapper[None],\n    agent: Agent,\n    input_data: str | list,\n) -> GuardrailFunctionOutput:\n    \"\"\"Ensures the user query is relevant to basketball/NBA.\"\"\"\n \n    keywords = [\n        \"nba\",\n        \"basketball\",\n        \"player\",\n        ... # truncated for brevity\n    ]\n \n    # extract the last user message from chat history\n    if isinstance(input_data, list):\n        latest_user_message = next(\n            (\n                item.get(\"content\", \"\")\n                for item in reversed(input_data)\n                if isinstance(item, dict) and item.get(\"role\") == \"user\"\n            ),\n            \"\",\n        )\n        input_query = latest_user_message\n    else:\n        input_query = input_data\n \n    input_query = input_query.lower()\n    is_relevant = any(keyword in input_query for keyword in keywords)\n \n    if len(input_query) < 5 or is_relevant:\n        return GuardrailFunctionOutput(tripwire_triggered=False, output_info=None)\n \n    return GuardrailFunctionOutput(\n        tripwire_triggered=True,\n        output_info={\n            \"reason\": \"The request is off-topic. Please ask questions relevant to NBA or basketball.\"\n        },\n    )\n```\n\nSetting `tripwire_triggered=True` instructs the Agents SDK to abort execution and raise an `InputGuardrailTripwireTriggered` exception. We intercept this in a FastAPI exception handler to record the exception event directly on the active OpenTelemetry span before returning an HTTP 400 response:\n\n```\n@app.exception_handler(InputGuardrailTripwireTriggered)\nasync def handle_guardrail_block(\n    request: Request,\n    exc: InputGuardrailTripwireTriggered,\n) -> JSONResponse:\n    guardrail_msg = exc.guardrail_result.output.output_info\n    span = trace.get_current_span()\n \n    span.record_exception(exc)\n    return JSONResponse(status_code=400, content={\"detail\": guardrail_msg})\n```\n\n#### Managing session context across turns\n\nThe `run_agent_turn` function completes our implementation. The agent uses the `OpenAIConversationsSession` object to persist and gather conversation context across turns.\n\nIf no `session_id` was passed, the session object triggers the creation of a new conversation session. In a follow-up request, the user can attach this ID to ensure the agent has context of the conversation thus far.\n\n```\napp/agent_service.py\npython\ndef run_agent_turn(\n    topic: str,\n    user_message: str | None,\n    session_id: str | None,\n) -> dict:\n    nba_topic = _validate_topic(topic)\n    prompt = build_nba_turn_prompt(nba_topic, user_message)\n \n    # if no session ID was given, the sdk internally creates a session_id during the turn\n    # subsequent calls which pass the ID maintain the conversation context\n    session = OpenAIConversationsSession(conversation_id=session_id)\n    result = Runner.run_sync(NBA_AGENT, prompt, session=session)\n \n    message = sanitize_agent_message((result.final_output or \"\").strip())\n    ... # truncated for brevity\n \n    return {\n        \"topic\": topic,\n        \"session_id\": session.session_id,\n        \"message\": message,\n        \"model\": OPENAI_MODEL,\n        \"usage\": usage,\n    }\n```\n\n## Visualizing AI agent workflows with OpenTelemetry\n\nLet’s send the agent a few requests to generate traces, then inspect how tool calls, conversation history, and guardrail failures appear in SigNoz Cloud.\n\n### Interacting with the agent\n\nLet’s start by asking the NBA Reporter agent a question about the Lakers' win percentage in the 2025-26 season, as well as LeBron and his future with the team. This query asks three distinct questions, setting us up for follow-up questions in the next turn, and the win percentage ask should trigger the `calculate_win_percentage` tool.\n\nThe agent responds first with the win percentage calculation — the format matches our tool's response shape. It makes a prediction about the upcoming NBA season, and informs us that LeBron is no longer with the LA Lakers.\n\nThe response JSON also contains the model name, token usage details at a glance, and the `session_id` to continue the conversation in follow-up requests.\n\nLet's now add the `session_id` to our request payload and ask why LeBron switched teams. We'll refer to LeBron as `he` to test the agent's context retrieval capabilities.\n\nThe agent correctly identifies `he` as LeBron in the context of the conversation, and outlines why he moved to a new team. It also returns the same `session_id` in the response, further confirming continuation of the previous conversation.\n\nFinally, let’s ask an off-topic question to see whether the input guardrails trigger to prevent users from abusing our agent:\n\nBecause the prompt lacks basketball-related keywords, the tripwire fires immediately. This helps the agent abort execution before executing tools or calling the model, preventing unneeded API spend and latency.\n\n### Exploring the trace hierarchy in SigNoz Cloud\n\nNow let's visualize in SigNoz Cloud the multi-step trace that invoked tool use:\n\nModern OpenTelemetry GenAI instrumentation structures the request into a clean, hierarchical span tree:\n\n```\nPOST /agent/turn                                     [fastapi]              Server   26.00s\n├─ POST /agent/turn http receive                     [asgi]                 Internal\n├─ POST /v1/conversations                            [httpx]                Client\n├─ GET  /v1/conversations/{id}/items?order=asc       [httpx]                Client\n├─ invoke_workflow Agent workflow                    [genai.openai_agents]  Internal 24.41s\n│  ├─ POST /v1/conversations/{id}/items              [httpx]                Client\n│  └─ invoke_agent NBA_Reporter                      [genai.openai_agents]  Internal 23.71s\n│     ├─ chat gpt-6-luna                             [genai.openai]         Client    3.94s\n│     │  └─ POST /v1/responses                       [httpx]                Client    3.84s\n│     ├─ execute_tool calculate_win_percentage       [genai.openai_agents]  Internal\n│     ├─ execute_tool calculate_win_percentage       [genai.openai_agents]  Internal\n│     ├─ POST /v1/conversations/{id}/items           [httpx]                Client\n│     ├─ chat gpt-6-luna                             [genai.openai]         Client   18.21s\n│     │  └─ POST /v1/responses                       [httpx]                Client   17.90s\n│     └─ POST /v1/conversations/{id}/items           [httpx]                Client\n├─ POST /v1/traces/ingest  ×3                         [httpx]                Client\n└─ POST /agent/turn http send  ×2                    [asgi]                 Internal\n```\n\nThis trace highlights several key structural details of the agentic loop:\n\n1. **Full-stack request lifecycle** : The trace begins at the FastAPI boundary (`POST /agent/turn` ). Before the agent workflow executes, child HTTP spans show the session layer fetching conversation history (`GET /v1/conversations/{id}/items` ).\n2. **Dedicated agentic scopes** : The agent orchestration harness is captured under`opentelemetry.instrumentation.genai.openai_agents` via the`invoke_workflow` and`invoke_agent` spans, defining the agent's decision boundary.\n3. **Iterative tool execution loop** : Rather than a single model completion, the trace maps the full multi-step loop:\n  - **Initial model call (`chat gpt-6-luna`, 3.94s)** : The model processes the turn, detects the win percentage query, and emits tool call instructions.\n  - **Tool execution (`execute_tool calculate_win_percentage` ×2)** : The agent loop executes our tools, followed by an HTTP span persisting the tool results to the conversation session.\n  - **Final synthesis call (`chat gpt-6-luna`, 18.21s)** : The model receives the tool outputs and generates the comprehensive user-facing response.\n4. **Standardized GenAI attributes** : Selecting either`chat gpt-6-luna` span reveals attributes for:\n  - **Provider and model** :`gen_ai.provider.name` ,`gen_ai.request.model` , and`gen_ai.response.model` .\n  - **Operation and outcome** :`gen_ai.operation.name` and`gen_ai.response.finish_reasons` .\n  - **Token usage** :`gen_ai.usage.input_tokens` and`gen_ai.usage.output_tokens` .\n\n#### Inspecting message content and privacy controls\n\nBecause we set `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=span_only`, the instrumentation populates `gen_ai.input.messages`, `gen_ai.output.messages`, `gen_ai.system_instructions`, and `gen_ai.tool.definitions` directly as span attributes. This allows engineers to inspect the exact prompts, system instructions, and model completions for each turn during debugging.\n\nIn environments with sensitive data or strict PII compliance, prompt content capture can be turned off entirely by setting:\n\n```\nexport OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=no_content\n```\n\nThis retains model timing, token counts, and span hierarchies while omitting raw message payloads and input/output values from the exported telemetry.\n\n#### Handling guardrail failures in traces\n\nWhen an off-topic query triggers the input guardrail tripwire, the agent stops execution before calling the model.\n\nIn our FastAPI exception handler, intercepting `InputGuardrailTripwireTriggered` and invoking `span.record_exception(exc)` captures the exception event on the root span.\n\n### Monitoring agent performance and metrics\n\nWhile individual traces let you debug specific agent executions, understanding production behavior requires aggregated metrics across turns, models, and sessions.\n\nThe OpenTelemetry GenAI instrumentation automatically emits standard metrics—such as `gen_ai.client.operation.duration` and token usage counters—alongside your traces. SigNoz Cloud captures this telemetry in a dedicated AI Observability interface that aggregates operational health, latency percentiles, and agent loop behaviors in one unified view.\n\n#### Executive KPIs and contextual drilldowns\n\nThe top-level overview surfaces high-level operational indicators across your agent infrastructure:\n\n- **Total cost and token volume** : Tracks spend and token consumption across services to help identify expensive workloads.\n- **Latency percentiles and TTFT** : Tracks tail latency and Time to First Token (TTFT) for streaming responses.\n- **LLM call volume and error rates** : Monitors traffic spikes and model failure rates across services.\n\nUse the dashboard's **trace and log drilldowns** to track the corresponding telemetry responsible for the numbers. Break down individual metrics by attributes such as model name or service, then combine those breakdowns with dashboard-level filters to answer questions like:\n\n- Which model cost you the most for a particular service in the given time frame?\n- How does LLM latency compare between staging and production over time?\n  - Could differences between your team's test requests and customer requests explain the gap?\n\n#### Evaluating model latency and response times\n\nMulti-turn reasoning and tool selection introduce variable latency across agent interactions. The **LLM latency by model** table and time-series charts track execution performance across percentiles:\n\n- **Percentile breakdowns** : Compare p50, p90, and p95 latencies by model to see whether slow responses affect typical requests or only the tail.\n- **Interactive time-series** : Drill into traces around a latency spike to inspect how much time was spent in model calls and tool execution.\n\n#### Diagnosing agent loops with finish reasons\n\nThe **Finish reasons** panel shows how model invocations end:\n\n- **`[\"stop\"]`** : Indicates the model finished generating a final response to the user.\n- **`[\"tool_calls\"]`** : Indicates the model requested one or more tool executions, prompting the agent loop to execute the tool and start another turn.\n\nSpikes in `[\"tool_calls\"]` relative to `[\"stop\"]` can be signals of recursive agent behavior, repetitive tool retries, or agents struggling to synthesize an answer.\n\n#### Tool call performance and span distribution\n\nThe **Tool calls** section aggregates telemetry from the tools invoked by the agent:\n\n- **Tool call rate and error tracking** : Shows how often each tool runs and fails, helping identify repeated calls or unreliable tools.\n- **Tool duration** : Shows which tools contribute the most latency to an agent run.\n- **Top span names** : Compares agent, model, and tool span counts. Unexpected differences, such as a large gap between agent spans and LLM spans, can guide further trace inspection.\n\n## Conclusion\n\nAs AI applications evolve from simple model prompts into autonomous, multi-turn agents, traditional debugging approaches fall short. Agent workflows are non-deterministic, span multiple tool calls, and rely on dynamic context that can silently degrade in quality.\n\nInstrumenting your agents with OpenTelemetry delivers end-to-end visibility across every layer:\n\n- **Full request context** : Correlate incoming HTTP requests, session storage lookups, agent decision loops, and downstream API calls in a single trace.\n- **Vendor-neutral GenAI standards** : Leverage official OpenTelemetry semantic conventions (`gen_ai.*` ) to standardize metrics, attributes, and span structures without proprietary lock-in.\n- **Unified debugging in SigNoz Cloud** : Combine traces, metrics, and logs in one interface to diagnose hallucinated tool calls, identify latency bottlenecks, and govern token spend across production runs.\n\nIf you’re building agentic applications, [sign up for a free SigNoz Cloud trial](https://signoz.io/teams/) to start observing your AI agents with OpenTelemetry today.", "url": "https://wpnews.pro/news/ai-agent-observability-with-opentelemetry", "canonical_source": "https://signoz.io/blog/opentelemetry-ai-agent-observability", "published_at": "2026-10-19 00:00:00+00:00", "updated_at": "2026-10-19 12:47:03.435586+00:00", "lang": "en", "topics": ["ai-agents", "artificial-intelligence", "mlops", "developer-tools", "large-language-models"], "entities": ["OpenTelemetry", "CNCF"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/ai-agent-observability-with-opentelemetry", "markdown": "https://wpnews.pro/news/ai-agent-observability-with-opentelemetry.md", "text": "https://wpnews.pro/news/ai-agent-observability-with-opentelemetry.txt", "jsonld": "https://wpnews.pro/news/ai-agent-observability-with-opentelemetry.jsonld"}}