Skip to content

[OTel] Emit gen_ai.response.model on LLM node spans (GenAI semconv conformance) #40635

Description

@caiovaale

Summary

The native OTel instrumentation (api/extensions/otel/) sets
gen_ai.request.model on LLM node spans but never sets gen_ai.response.model.

gen_ai.response.model is a first-class attribute in the OpenTelemetry GenAI
semantic conventions registry
(https://github.com/open-telemetry/semantic-conventions-genai). Several
observability backends key their GenAI model-level aggregations on
gen_ai.response.model specifically, not on gen_ai.request.model. In
practice this means the model breakdown views in those backends render empty
for Dify workloads, even though Dify is emitting otherwise-correct GenAI spans.

We hit this while building an open-source OTel conformance bridge for Dify
(https://github.com/obs-plugins/dynatrace-otel-bridge) and currently patch it
in the OTel Collector with an OTTL processor. Fixing it at the source in Dify
would benefit every backend, not just ours.

Proposed change

Add RESPONSE_MODEL = "gen_ai.response.model" to LLMAttributes in
api/extensions/otel/semconv/gen_ai.py, and set it in
api/extensions/otel/parser/llm.py alongside the existing REQUEST_MODEL.

This is purely additive — no existing attribute is renamed or removed — so it
is backward-compatible with all current consumers (Langfuse, Arize Phoenix,
Opik) and does not require an OTEL_SEMCONV_STABILITY_OPT_IN gate.

Known limitation (worth discussing)

Dify currently derives the model name from process_data["model_name"], which
is the requested model. The model actually returned by the provider
(LLMResult.model) is not surfaced in NodeRunResult. The GenAI spec allows
gen_ai.response.model to be set on the instrumentation's best knowledge, so
using the same source is valid and immediately useful. The complete fix would
be for graphon to expose LLMResult.model in process_data. Happy to follow
up with a separate issue there if maintainers agree.

Scope

I have a broader GenAI semconv conformance audit of the current OTel layer
(missing gen_ai.workflow.name, singular gen_ai.response.finish_reason vs.
the spec's plural array, absent GenAI metrics, non-spec gen_ai.operation.name
values). I'm intentionally keeping this issue narrow and additive. If
maintainers are open to it, I'd be glad to open a tracking issue for the rest.

Request

Please assign this issue to me so I can open the PR, per CONTRIBUTING.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions