diff --git a/packages/opentelemetry-instrumentation-openai/README.md b/packages/opentelemetry-instrumentation-openai/README.md index d18d6e2d64..ca776b9a0e 100644 --- a/packages/opentelemetry-instrumentation-openai/README.md +++ b/packages/opentelemetry-instrumentation-openai/README.md @@ -4,8 +4,18 @@ + This library allows tracing OpenAI prompts and completions sent with the official [OpenAI library](https://github.com/openai/openai-python). +## Meter Attributes + +As of vNEXT, all meter data points now include both the response and request model names: + +* `gen_ai.response.model` — The model name returned in the response (e.g., "gpt-3.5-turbo-0125"). +* `gen_ai.request.model` — The model name specified in the request payload (e.g., "gpt-3.5-turbo"). + +This provides richer context for metrics and observability. + ## Installation ```bash diff --git a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py index 0b8c9d6b84..394b9509b7 100644 --- a/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py +++ b/packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/shared/chat_wrappers.py @@ -888,6 +888,7 @@ def _build_from_streaming_response( shared_attributes = { SpanAttributes.LLM_RESPONSE_MODEL: complete_response.get("model") or None, + "gen_ai.request.model": request_kwargs.get("model") if request_kwargs else None, "server.address": _get_openai_base_url(instance), "stream": True, } @@ -959,6 +960,7 @@ async def _abuild_from_streaming_response( shared_attributes = { SpanAttributes.LLM_RESPONSE_MODEL: complete_response.get("model") or None, + "gen_ai.request.model": request_kwargs.get("model") if request_kwargs else None, "server.address": _get_openai_base_url(instance), "stream": True, } diff --git a/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py b/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py index 12c0933d53..57f7529c1e 100644 --- a/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py +++ b/packages/opentelemetry-instrumentation-openai/tests/metrics/test_openai_metrics.py @@ -47,12 +47,15 @@ def test_chat_completion_metrics(instrument_legacy, reader, openai_client): ] assert len(data_point.attributes["server.address"]) > 0 assert data_point.sum > 0 + # Check request model attribute + assert data_point.attributes["gen_ai.request.model"] == "gpt-3.5-turbo" if metric.name == Meters.LLM_GENERATION_CHOICES: found_choice_metric = True for data_point in metric.data.data_points: assert data_point.value >= 1 assert len(data_point.attributes["server.address"]) > 0 + assert data_point.attributes["gen_ai.request.model"] == "gpt-3.5-turbo" if metric.name == Meters.LLM_OPERATION_DURATION: found_duration_metric = True @@ -66,6 +69,10 @@ def test_chat_completion_metrics(instrument_legacy, reader, openai_client): len(data_point.attributes["server.address"]) > 0 for data_point in metric.data.data_points ) + assert all( + data_point.attributes["gen_ai.request.model"] == "gpt-3.5-turbo" + for data_point in metric.data.data_points + ) assert found_token_metric is True assert found_choice_metric is True