cd /news/ai-agents/tracing-ai-agents-what-otels-genai-s… · home › topics › ai-agents › article
[ARTICLE · art-161201] src=pub.towardsai.net ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Tracing AI Agents: What OTel’s GenAI Spans Actually Capture

OpenTelemetry shipped semantic conventions release v1.42.0 on June 12, 2026, deprecating every gen_ai.* attribute, span, metric, and event in its core repository and moving them to a dedicated semantic-conventions-genai repository so the GenAI working group can ship faster than the project's shared release cadence. The new repository had no tagged release as of the article's writing and ships from its main branch against a schema labeled gen-ai/1.42.0, so the article advises pinning instrumentation libraries by commit or exported schema URL rather than a spec version number. The moved vocabulary now covers agent tracing as a span tree — an invoke_agent span (CLIENT-kind across process boundaries, INTERNAL-kind for an agent's own reasoning loop), per-model-call spans named {gen_ai.operation.name} {gen_ai.request.model}, and execute_tool spans for each tool call — with MCP-specific conventions sharing the same gen_ai.* attributes.

by read7 min views1 publishedOct 30, 2026

On June 12, 2026, OpenTelemetry shipped semantic conventions release v1.42.0, and quietly pulled every gen_ai.* attribute, span, metric, and event out of its core repository [1]. If you had dashboards or alerting rules built against the old spec pages, they now redirect to a notice that reads "this page has moved and is no longer maintained" [1]. The conventions didn't disappear. They moved to a dedicated repository, semantic-conventions-genai, so the GenAI working group can ship faster than the rest of OpenTelemetry's release cycle allows [2].

That move matters more than a changelog entry usually would, because these conventions are the only vendor-neutral vocabulary for describing what an LLM call, a tool execution, or an agent run actually did on the wire. Here’s what’s in that vocabulary right now, what changed, and what’s worth building against before the next spec revision moves the furniture again.

In this article:

OpenTelemetry’s semantic conventions are the part of the project that defines shared vocabulary: agreed-upon attribute names so that a trace produced by one instrumentation library means the same thing in any backend that reads it. The GenAI conventions are the subset that covers model calls, embeddings, retrieval, tool execution, and agent orchestration.

Until this spring, that vocabulary lived inside the same repository as HTTP, database, and messaging conventions, and shipped on the same release cadence. The GenAI working group outgrew that cadence. Providers keep adding new request parameters, new token-accounting categories (cached tokens, reasoning tokens, per-modality tokens), and new span types for agents and workflows faster than a shared quarterly-ish release train could absorb them cleanly. The v1.42.0 release notes say as much directly: the gen_ai.* definitions under model/gen-ai/, model/openai/, and model/mcp/ were deprecated in the core repo and moved to semantic-conventions-genai [2]. Notably, the MCP-specific conventions moved with them, which means tool-call spans for MCP servers now share the exact same attribute vocabulary as everything else under gen_ai.*, rather than living as a separate side convention. That's worth knowing if you're designing MCP tools that Claude or another agent will actually call correctly, since the same spans that trace a bad tool call also trace the model call that chose it.

The new repository had no tagged release as of this writing, and ships straight from its main branch against a schema labeled gen-ai/1.42.0 [3]. If you're pinning an instrumentation library today, pin it by commit or by the exported schema URL it emits, not by a spec version number you'd expect from the old repo's release pattern.

A single agent turn doesn’t produce one span. It produces a tree, and the GenAI conventions now describe each layer of it. At the top sits an invoke_agent span, which comes in two flavors: a CLIENT-kind span when one agent calls another across a process boundary, and an INTERNAL-kind span for an agent's own internal reasoning loop [4]. Both are named invoke_agent {gen_ai.agent.name} when the agent has a name, or just invoke_agent when it doesn't.

Underneath that, every model call gets its own span, named {gen_ai.operation.name} {gen_ai.request.model} (so a real span name looks like chat gpt-4 or chat claude-opus-5-5) [5]. Underneath that, each tool call the model triggers gets an execute_tool span of its own, carrying attributes like the tool's name and a call ID so you can match it back to the specific tool-use block that requested it [6]. Stack enough of these and you get a tree that reads, top to bottom, as: the agent was invoked, it made a model call, the model asked for a tool, the tool ran, and the result fed back into the next model call. That's the shape that makes it possible to answer "why did this agent run cost four model calls instead of one," which is the exact question that tends to blow up agent-loop budgets in production.

Two attributes are required on nearly every GenAI span: gen_ai.operation.name (values like chat, embeddings, execute_tool, invoke_agent) and gen_ai.provider.name (openai, anthropic, and so on) [5]. That second one is itself a renamed field. The older gen_ai.system attribute is gone in the current spec, replaced by gen_ai.provider.name, and the old gen_ai.usage.prompt_tokens and gen_ai.usage.completion_tokens fields were replaced by gen_ai.usage.input_tokens and gen_ai.usage.output_tokens [5]. If your dashboards still query the old names, they're silently reading nothing from any instrumentation library that's updated to the current spec.

Beyond the required pair, most of what you’d actually want to query is “Recommended” rather than required: token counts, gen_ai.response.finish_reasons, gen_ai.conversation.id, and a growing list of per-modality usage fields for audio, image, and cached tokens [5]. None of that is captured by default, and deliberately so. The actual prompt and response text live behind gen_ai.input.messages and gen_ai.output.messages, both marked Opt-In, specifically because they can carry personal data that you don't want landing in a trace backend without a conscious decision to put it there [5][6]. That opt-in boundary is the same tension that shows up anywhere you're deciding how much raw context to surface for debugging versus how much context an agent should actually be carrying around in the first place: more captured content makes a trace more useful for debugging and more expensive and riskier to store.

A span carrying the current, non-renamed attributes looks roughly like this once it reaches your trace backend:

{  "name": "chat claude-opus-5-5",  "kind": "CLIENT",  "attributes": {    "gen_ai.operation.name": "chat",    "gen_ai.provider.name": "anthropic",    "gen_ai.request.model": "claude-opus-5-5",    "gen_ai.usage.input_tokens": 842,    "gen_ai.usage.output_tokens": 311,    "gen_ai.response.finish_reasons": ["end_turn"]  }}

Every span, metric, and attribute under the GenAI conventions currently carries a Status of Development, the least mature of OpenTelemetry’s three stability tiers [4][5]. In practice that means the names, the required-versus-recommended split, and even which span a given piece of data lives on can change between releases without the backward-compatibility guarantees OpenTelemetry gives to its Stable conventions. A handful of fields borrowed from core HTTP and network conventions, like error.type, server.address, and server.port, are Stable because they predate the GenAI work entirely, but the GenAI-specific vocabulary itself is not [5].

This isn’t a flaw in the spec so much as an honest label for where a fast-moving convention actually is. The working group has already renamed or removed fields once (the gen_ai.system and gen_ai.prompt/gen_ai.completion changes above), and splitting out a dedicated, faster-moving repository makes it likelier they'll do it again before anything here reaches Stable. Treat a gen_ai.* attribute the way you'd treat an experimental API flag: useful today, not something to build an irreversible dashboard contract on tomorrow.

Adopt the conventions for anything you’re building fresh. The vendor-neutral gen_ai.operation.name and gen_ai.provider.name pair alone is worth it, because it means a trace from an OpenAI call and a trace from an Anthropic call land in your backend with the same two fields to group and filter on, instead of each vendor's SDK inventing its own attribute names. If you're instrumenting agent orchestration specifically, the invoke_agent and execute_tool span shapes already give you the parent-child structure most observability backends need to render a usable flame graph of an agent run, and that structural value doesn't depend on every attribute name staying fixed.

Pin carefully around the parts that are still moving. Record the schema URL your instrumentation library actually emits (gen-ai/1.42.0 as of this writing) rather than assuming a particular spec release, since the new repository ships from main with no tagged releases yet [3]. Treat any dashboard or alert built on a specific attribute name as something you'll revisit, not something you set and forget. And if you're also tracing MCP tool calls, remember they now share this exact vocabulary, so a decision to adopt gen_ai.* for your model-call spans is also a decision to adopt it for your tool-call spans, whether or not you were planning to do both at once [2]. If your agent's tool calls cross process boundaries the way a Logic App workflow's steps cross service boundaries, the same discipline of correlating a trace ID end to end is what makes either kind of system debuggable at 2am.

The honest summary is that OpenTelemetry finally gave agentic systems a shared tracing vocabulary worth adopting, and then immediately admitted, by moving it into its own faster-churning repository, that it isn’t done changing. Build against it. Just don’t act surprised when the next spec revision moves something again.

Sources:

If you enjoyed the article and wish to show your support, make sure to:

Tracing AI Agents: What OTel’s GenAI Spans Actually Capture was originally published in Towards AI on Medium, where people are continuing the conversation by highlighting and responding to this story.

── more in #ai-agents 4 stories · sorted by recency
── more on @opentelemetry 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/tracing-ai-agents-wh…] indexed:0 read:7min 2026-10-30 · —