
Instrument Every LLM Call Once and Route Traces Anywhere: OpenTelemetry's GenAI Semantic Conventions
Chris Harper
2 min read
Aug 3, 2026 · 12:03 UTC
OpenTelemetry's GenAI semantic conventions let you add standard gen_ai.* attributes to every LLM call in three lines of Python, then route traces to any OTel-compatible backend without changing your instrumentation.
Every observability tool — LangSmith, Arize Phoenix, W&B Weave, Langfuse — has its own SDK you install, wrap your LLM calls with, and maintain. Switch tools and you rewrite your instrumentation. OpenTelemetry's 2026 GenAI semantic conventions fix that: they define exactly what a "LLM call span" looks like across any provider, so one instrumentation pass works everywhere.
What you'll be able to do after this:
- Add standard
gen_ai.system,gen_ai.request.model,gen_ai.usage.input_tokens, and tool-call spans to every LLM call and agent step with three lines of setup — no manual span creation - Swap observability backends (LangSmith → Arize Phoenix → Grafana → Jaeger) by changing one env var without touching instrumentation code
- Track per-call token costs, model latency, and agent step timing in structured trace data that any OTel-compatible backend can ingest
The key span attributes
| Attribute | What it captures |
|---|---|
gen_ai.system | Provider (anthropic, openai, cohere) |
gen_ai.request.model | Model string |
gen_ai.usage.input_tokens | Tokens consumed from prompt |
gen_ai.usage.output_tokens | Tokens consumed in completion |
gen_ai.tool.name | Tool/function name on tool-call spans |
Walk-through: instrument any LLM client in 3 lines
OpenLLMetry is an open-source library that auto-instruments OpenAI, Anthropic, LangChain, and 15+ other providers with the GenAI conventions — no manual span creation required.
pip install traceloop-sdk
from traceloop.sdk import Traceloop
# One call at startup — every subsequent LLM and agent call is traced
Traceloop.init(app_name="my-agent", disable_batch=True)
That's the entire instrumentation. Every call to LangChain, the Anthropic SDK, or OpenAI automatically gets gen_ai.* spans with token counts, latency, inputs, and outputs.
Swap backends by setting one env var — no code change needed:
# Route to LangSmith
export TRACELOOP_BASE_URL="https://api.smith.langchain.com"
# Route to Arize Phoenix (local)
export TRACELOOP_BASE_URL="http://localhost:6006"
# Route to any OTel collector
export TRACELOOP_BASE_URL="http://otel-collector:4318"
What you get: a trace tree for each agent run — top-level agent span → LLM call spans (with token counts) → tool-call spans (with inputs and outputs). Every step is addressable for cost analysis, latency debugging, and regression detection, regardless of which backend you're currently using.
Sources: OpenTelemetry Blog — GenAI Observability 2026, OpenLLMetry Video Tutorial, SigNoz — Observing LLM Applications with OpenTelemetry