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.
Summary
The native OTel instrumentation (
api/extensions/otel/) setsgen_ai.request.modelon LLM node spans but never setsgen_ai.response.model.gen_ai.response.modelis a first-class attribute in the OpenTelemetry GenAIsemantic conventions registry
(https://github.com/open-telemetry/semantic-conventions-genai). Several
observability backends key their GenAI model-level aggregations on
gen_ai.response.modelspecifically, not ongen_ai.request.model. Inpractice 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"toLLMAttributesinapi/extensions/otel/semconv/gen_ai.py, and set it inapi/extensions/otel/parser/llm.pyalongside the existingREQUEST_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_INgate.Known limitation (worth discussing)
Dify currently derives the model name from
process_data["model_name"], whichis the requested model. The model actually returned by the provider
(
LLMResult.model) is not surfaced inNodeRunResult. The GenAI spec allowsgen_ai.response.modelto be set on the instrumentation's best knowledge, sousing the same source is valid and immediately useful. The complete fix would
be for
graphonto exposeLLMResult.modelinprocess_data. Happy to followup 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, singulargen_ai.response.finish_reasonvs.the spec's plural array, absent GenAI metrics, non-spec
gen_ai.operation.namevalues). 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.