# OpenTelemetry and GenAI Semantic Conventions — LLM Observability (Langfuse / LangSmith)

Source: https://www.skillbyai.com/en/llm-observability/lo-otel

> Explain how OpenTelemetry and its GenAI conventions let you send LLM traces to different backends.

## A vendor-neutral way to emit traces

**OpenTelemetry (OTel)** is the open standard for generating and exporting traces, metrics and logs. It defines APIs and SDKs, a wire protocol (**OTLP**) and **semantic conventions**: agreed attribute names so every tool interprets data the same way. The **GenAI semantic conventions** define attributes for model calls, such as `gen_ai.operation.name`, `gen_ai.request.model`, `gen_ai.usage.input_tokens` and `gen_ai.usage.output_tokens`. These conventions are still marked as in development, so some names may change; check the current spec. Why care? With OTel, your instrumentation is not tied to one vendor: the same spans can go to an OTel Collector and then to Langfuse, LangSmith or a general APM backend. Langfuse provides an OTLP endpoint and its newer Python SDK is itself built on OpenTelemetry, and LangSmith also accepts OpenTelemetry traces. Many community instrumentation libraries emit GenAI spans automatically for popular providers and frameworks.

## Manual GenAI attributes on an OTel span

Uses the `opentelemetry-api` package; exporter setup is configured separately (see the next segment).

```python
from opentelemetry import trace

tracer = trace.get_tracer("support-bot")

with tracer.start_as_current_span("chat my-chat-model") as span:
    span.set_attribute("gen_ai.operation.name", "chat")
    span.set_attribute("gen_ai.request.model", "my-chat-model")
    span.set_attribute("gen_ai.request.temperature", 0.2)
    reply, usage = "Your order has shipped.", {"in": 120, "out": 9}  # model call
    span.set_attribute("gen_ai.usage.input_tokens", usage["in"])
    span.set_attribute("gen_ai.usage.output_tokens", usage["out"])
```

## Exporting OTLP to Langfuse

Standard OTel exporter variables. Langfuse authenticates OTLP with HTTP Basic auth built from the public and secret keys; `%20` encodes the space after `Basic`. Langfuse accepts OTLP over HTTP only (not gRPC), so set the protocol explicitly.

```bash
AUTH=$(printf '%s' "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" | base64 | tr -d '\n')

export OTEL_EXPORTER_OTLP_ENDPOINT="https://cloud.langfuse.com/api/public/otel"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic%20${AUTH}"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
```

**Quiz:** What is the main benefit of instrumenting with OpenTelemetry GenAI conventions?

- [ ] It makes model calls faster
- [ ] It removes the need to store prompts
- [ ] It guarantees that attribute names will never change
- [x] The same instrumentation can export to different observability backends

*Answer:* The same instrumentation can export to different observability backends. OTel decouples instrumentation from the backend. The GenAI conventions are still evolving, so names can change, and they do not affect model speed.
