Zenaique

Fill in the OpenTelemetry GenAI attributes that record input and output token counts

Fill in blank·Easy·4.0 · 0·~1 min·Asked atGongRephrase AiStability Ai
Attempt it
Per the OpenTelemetry GenAI semantic conventions, the standard span attribute for prompt tokens is and the standard attribute for completion tokens is .
TL;DR

gen_ai.usage.input_tokens and gen_ai.usage.output_tokens. The convention uses input/output (not prompt/completion) so chat and streaming shapes fit the same names.

Memory aid
Sign in to see the mnemonic that makes this stick.
Easy to grasp

Imagine every shipping company uses a slightly different label for 'how heavy is the box' and 'how heavy is the return package'. Customs gets a headache reading every shipment. OpenTelemetry is like a global standard that says: everyone calls the incoming weight input_tokens and the outgoing weight output_tokens, and they all live under the same gen_ai.usage shelf so any tool can find them. Once the names match, dashboards built for one provider work for another with zero changes.

Concept explanation~2 min read

Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.

Token counts are the most important attribute on any LLM span because cost, latency proxy, and capacity planning all derive from them. The OpenTelemetry GenAI semantic conventions standardize the names so dashboards and cost calculators work across providers without translation. The two stable attributes are gen_ai.usage.input_tokens for what went in and gen_ai.usage.output_tokens for what came out.

This deep dive explains the naming choice (why input/output and not prompt/completion), the stable versus incubating distinction (why pinning dashboards to incubating keys is a future-breakage risk), how the convention handles modern shapes like chat streaming and prompt caching, and what to do when legacy SDKs emit non-standard keys.

Mental model: input_tokens and output_tokens are the universal language. Once your traces speak it, any OTel-native backend can compute cost, alert on regressions, and aggregate per-model spend with zero custom code.

The stable attribute names and namespace

The two attributes are part of a larger gen_ai semantic family.

gen_ai.usage.input_tokens

Stable. Integer. Counts the tokens that entered the model on this call. For chat, this is the tokenized concatenation of the message history (system, user, assistant, tool messages). For embedding, this is the tokenized input text. For completion, this is the prompt string.

gen_ai.usage.output_tokens

Stable. Integer. Counts the tokens the model generated. For chat and completion, this is the new content the model produced. For embedding, this is conventionally zero or omitted (the output is a vector, not text).

The wider gen_ai family

Other stable attributes on the same span include gen_ai.system (provider id like 'openai', 'anthropic'), gen_ai.request.model (model name), gen_ai.request.temperature, gen_ai.response.finish_reasons (array of stop reasons), and gen_ai.operation.name (chat, completion, embedding). Together they form the standard LLM span schema.

Namespace conventions

Dot-separated. The first segment (gen_ai) scopes everything; the second (usage, request, response) sub-scopes. Backends use this prefix to identify LLM spans and apply LLM-specific dashboards. Custom attributes outside this namespace should use your own organization prefix to avoid collisions.

Why input/output instead of prompt/completion
Stable versus incubating attributes
What you do with these attributes
Sign in to unlock the full deep dive.

Situations where this technique stops working.

Sign in to see when this approach fails.

2–4 min · Everything important, quickly.

Sign in to see the quick scan of the deep dive.

Real products, models, and research that use this idea.

  • OpenAI Python SDK with OpenLLMetry instrumentation emits gen_ai.usage.input_tokens and gen_ai.usage.output_tokens on every chat completion span.
  • Anthropic SDK with OpenLLMetry follows the same OTel convention, so the same dashboard works across OpenAI and Anthropic.
Sign in to see more production examples.

What an interviewer would ask next. Try answering before peeking at the approach.

QWhat is the difference between stable and incubating attributes?
A

Stable attributes carry a compatibility guarantee: name will not change across SDK versions. Incubating attributes can be renamed in a non-breaking SDK upgrade. Pin dashboards to stable; treat incubating as best-effort.

2 more follow-ups an interviewer would ask next. Sign in to reveal them.

Red flags & common mistakes

The phrases that signal junior thinking. Click to expand.

Most common mistake

Writing gen_ai.usage.prompt_tokens or gen_ai.usage.completion_tokens. Those names match the older OpenAI API field names but are not the OTel standard; the stable convention uses input and output.

Sign in to see all red flags and common mistakes.

60 second bullets to scan on the way to the call.

  • The two stable attribute names and the namespace they live under

  • Why the convention picked input/output over prompt/completion

Sign in to unlock the revision sheet.

Primary sources. Browse if you want the original framing.

Similar questions

Same topic, related formats. Practice these next.

4 curated
Next question
Describe how end user thumbs up/down should flow back onto a trace
Flashcard·Easy