Skip to content

fix(instrumentation): updated GenAI token usage attributes #3138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def _handle_message_event(
event: PromptEvent, span: Span, event_logger: Optional[EventLogger], kwargs
):
if span.is_recording():
_set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model"))
_set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model"))

if should_emit_events():
return emit_event(event, event_logger)
Expand All @@ -86,9 +86,9 @@ def _handle_completion_event(event: CompletionEvent, span, event_logger, respons
span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, input_tokens + output_tokens
)
_set_span_attribute(
span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, output_tokens
span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens
)
_set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens)
_set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)

if should_emit_events():
emit_event(event, event_logger)
Expand Down Expand Up @@ -157,7 +157,7 @@ def _wrap(
name,
kind=SpanKind.CLIENT,
attributes={
SpanAttributes.LLM_SYSTEM: "AlephAlpha",
SpanAttributes.GEN_AI_SYSTEM: "AlephAlpha",
SpanAttributes.LLM_REQUEST_TYPE: llm_request_type.value,
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ def set_prompt_attributes(event: PromptEvent, span: Span):
return

if should_send_prompts():
_set_span_attribute(span, f"{SpanAttributes.LLM_PROMPTS}.0.role", "user")
_set_span_attribute(span, f"{SpanAttributes.GEN_AI_PROMPT}.0.role", "user")
_set_span_attribute(
span,
f"{SpanAttributes.LLM_PROMPTS}.0.content",
f"{SpanAttributes.GEN_AI_PROMPT}.0.content",
event.content[0].get("data"),
)

Expand All @@ -36,9 +36,9 @@ def set_completion_attributes(event: CompletionEvent, span: Span):
if should_send_prompts():
_set_span_attribute(
span,
f"{SpanAttributes.LLM_COMPLETIONS}.0.content",
f"{SpanAttributes.GEN_AI_COMPLETION}.0.content",
event.message["content"],
)
_set_span_attribute(
span, f"{SpanAttributes.LLM_COMPLETIONS}.0.role", "assistant"
span, f"{SpanAttributes.GEN_AI_COMPLETION}.0.role", "assistant"
)
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ def test_alephalpha_completion(
together_span.attributes.get("gen_ai.completion.0.content")
== response.completions[0].completion
)
assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 9
assert together_span.attributes.get("gen_ai.usage.input_tokens") == 9
assert together_span.attributes.get(
"llm.usage.total_tokens"
) == together_span.attributes.get(
"gen_ai.usage.completion_tokens"
) + together_span.attributes.get("gen_ai.usage.prompt_tokens")
"gen_ai.usage.output_tokens"
) + together_span.attributes.get("gen_ai.usage.input_tokens")

logs = log_exporter.get_finished_logs()
assert (
Expand All @@ -66,12 +66,12 @@ def test_alephalpha_completion_with_events_with_content(
assert together_span.attributes.get("gen_ai.system") == "AlephAlpha"
assert together_span.attributes.get("llm.request.type") == "completion"
assert together_span.attributes.get("gen_ai.request.model") == "luminous-base"
assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 9
assert together_span.attributes.get("gen_ai.usage.input_tokens") == 9
assert together_span.attributes.get(
"llm.usage.total_tokens"
) == together_span.attributes.get(
"gen_ai.usage.completion_tokens"
) + together_span.attributes.get("gen_ai.usage.prompt_tokens")
"gen_ai.usage.output_tokens"
) + together_span.attributes.get("gen_ai.usage.input_tokens")

logs = log_exporter.get_finished_logs()
assert len(logs) == 2
Expand Down Expand Up @@ -116,12 +116,12 @@ def test_alephalpha_completion_with_events_with_no_content(
assert together_span.attributes.get("gen_ai.system") == "AlephAlpha"
assert together_span.attributes.get("llm.request.type") == "completion"
assert together_span.attributes.get("gen_ai.request.model") == "luminous-base"
assert together_span.attributes.get("gen_ai.usage.prompt_tokens") == 9
assert together_span.attributes.get("gen_ai.usage.input_tokens") == 9
assert together_span.attributes.get(
"llm.usage.total_tokens"
) == together_span.attributes.get(
"gen_ai.usage.completion_tokens"
) + together_span.attributes.get("gen_ai.usage.prompt_tokens")
"gen_ai.usage.output_tokens"
) + together_span.attributes.get("gen_ai.usage.input_tokens")

logs = log_exporter.get_finished_logs()
assert len(logs) == 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ async def _aset_token_usage(
input_tokens,
attributes={
**metric_attributes,
SpanAttributes.LLM_TOKEN_TYPE: "input",
SpanAttributes.GEN_AI_TOKEN_TYPE: "input",
},
)

Expand All @@ -154,7 +154,7 @@ async def _aset_token_usage(
completion_tokens,
attributes={
**metric_attributes,
SpanAttributes.LLM_TOKEN_TYPE: "output",
SpanAttributes.GEN_AI_TOKEN_TYPE: "output",
},
)

Expand All @@ -175,18 +175,18 @@ async def _aset_token_usage(
},
)

set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens)
set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)
set_span_attribute(
span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens
span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens
)
set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens)

set_span_attribute(
span, SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens
span, SpanAttributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens
)
set_span_attribute(
span,
SpanAttributes.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS,
SpanAttributes.GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS,
cache_creation_tokens,
)

Expand Down Expand Up @@ -220,7 +220,7 @@ def _set_token_usage(
input_tokens,
attributes={
**metric_attributes,
SpanAttributes.LLM_TOKEN_TYPE: "input",
SpanAttributes.GEN_AI_TOKEN_TYPE: "input",
},
)

Expand All @@ -245,7 +245,7 @@ def _set_token_usage(
completion_tokens,
attributes={
**metric_attributes,
SpanAttributes.LLM_TOKEN_TYPE: "output",
SpanAttributes.GEN_AI_TOKEN_TYPE: "output",
},
)

Expand All @@ -266,18 +266,18 @@ def _set_token_usage(
},
)

set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens)
set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)
set_span_attribute(
span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens
span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens
)
set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens)

set_span_attribute(
span, SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens
span, SpanAttributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens
)
set_span_attribute(
span,
SpanAttributes.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS,
SpanAttributes.GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS,
cache_creation_tokens,
)

Expand Down Expand Up @@ -397,7 +397,7 @@ def _wrap(
name,
kind=SpanKind.CLIENT,
attributes={
SpanAttributes.LLM_SYSTEM: "Anthropic",
SpanAttributes.GEN_AI_SYSTEM: "Anthropic",
SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value,
},
)
Expand Down Expand Up @@ -494,7 +494,7 @@ async def _awrap(
name,
kind=SpanKind.CLIENT,
attributes={
SpanAttributes.LLM_SYSTEM: "Anthropic",
SpanAttributes.GEN_AI_SYSTEM: "Anthropic",
SpanAttributes.LLM_REQUEST_TYPE: LLMRequestTypeValues.COMPLETION.value,
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ async def _dump_content(message_index, content, span):
async def aset_input_attributes(span, kwargs):
from opentelemetry.instrumentation.anthropic import set_span_attribute

set_span_attribute(span, SpanAttributes.LLM_REQUEST_MODEL, kwargs.get("model"))
set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_MODEL, kwargs.get("model"))
set_span_attribute(
span, SpanAttributes.LLM_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample")
span, SpanAttributes.GEN_AI_REQUEST_MAX_TOKENS, kwargs.get("max_tokens_to_sample")
)
set_span_attribute(
span, SpanAttributes.LLM_REQUEST_TEMPERATURE, kwargs.get("temperature")
span, SpanAttributes.GEN_AI_REQUEST_TEMPERATURE, kwargs.get("temperature")
)
set_span_attribute(span, SpanAttributes.LLM_REQUEST_TOP_P, kwargs.get("top_p"))
set_span_attribute(span, SpanAttributes.GEN_AI_REQUEST_TOP_P, kwargs.get("top_p"))
set_span_attribute(
span, SpanAttributes.LLM_FREQUENCY_PENALTY, kwargs.get("frequency_penalty")
)
Expand All @@ -92,7 +92,7 @@ async def aset_input_attributes(span, kwargs):
if should_send_prompts():
if kwargs.get("prompt") is not None:
set_span_attribute(
span, f"{SpanAttributes.LLM_PROMPTS}.0.user", kwargs.get("prompt")
span, f"{SpanAttributes.GEN_AI_PROMPT}.0.user", kwargs.get("prompt")
)

elif kwargs.get("messages") is not None:
Expand All @@ -101,28 +101,28 @@ async def aset_input_attributes(span, kwargs):
has_system_message = True
set_span_attribute(
span,
f"{SpanAttributes.LLM_PROMPTS}.0.content",
f"{SpanAttributes.GEN_AI_PROMPT}.0.content",
await _dump_content(
message_index=0, span=span, content=kwargs.get("system")
),
)
set_span_attribute(
span,
f"{SpanAttributes.LLM_PROMPTS}.0.role",
f"{SpanAttributes.GEN_AI_PROMPT}.0.role",
"system",
)
for i, message in enumerate(kwargs.get("messages")):
prompt_index = i + (1 if has_system_message else 0)
set_span_attribute(
span,
f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.content",
f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.content",
await _dump_content(
message_index=i, span=span, content=message.get("content")
),
)
set_span_attribute(
span,
f"{SpanAttributes.LLM_PROMPTS}.{prompt_index}.role",
f"{SpanAttributes.GEN_AI_PROMPT}.{prompt_index}.role",
message.get("role"),
)

Expand All @@ -146,7 +146,7 @@ def _set_span_completions(span, response):
from opentelemetry.instrumentation.anthropic import set_span_attribute

index = 0
prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}"
prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}"
set_span_attribute(span, f"{prefix}.finish_reason", response.get("stop_reason"))
if response.get("role"):
set_span_attribute(span, f"{prefix}.role", response.get("role"))
Expand Down Expand Up @@ -177,7 +177,7 @@ def _set_span_completions(span, response):
)
# increment the index for subsequent content blocks
index += 1
prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}"
prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}"
# set the role to the original role on the next completions
set_span_attribute(
span,
Expand Down Expand Up @@ -213,15 +213,15 @@ def set_response_attributes(span, response):

if not isinstance(response, dict):
response = response.__dict__
set_span_attribute(span, SpanAttributes.LLM_RESPONSE_MODEL, response.get("model"))
set_span_attribute(span, SpanAttributes.GEN_AI_RESPONSE_MODEL, response.get("model"))
set_span_attribute(span, GEN_AI_RESPONSE_ID, response.get("id"))

if response.get("usage"):
prompt_tokens = response.get("usage").input_tokens
completion_tokens = response.get("usage").output_tokens
set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, prompt_tokens)
set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_INPUT_TOKENS, prompt_tokens)
set_span_attribute(
span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens
span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens
)
set_span_attribute(
span,
Expand All @@ -245,7 +245,7 @@ def set_streaming_response_attributes(span, complete_response_events):
try:
for event in complete_response_events:
index = event.get("index")
prefix = f"{SpanAttributes.LLM_COMPLETIONS}.{index}"
prefix = f"{SpanAttributes.GEN_AI_COMPLETION}.{index}"
set_span_attribute(
span, f"{prefix}.finish_reason", event.get("finish_reason")
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,21 @@ def _set_token_usage(
input_tokens = prompt_tokens + cache_read_tokens + cache_creation_tokens
total_tokens = input_tokens + completion_tokens

set_span_attribute(span, SpanAttributes.LLM_USAGE_PROMPT_TOKENS, input_tokens)
set_span_attribute(span, SpanAttributes.GEN_AI_USAGE_INPUT_TOKENS, input_tokens)
set_span_attribute(
span, SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, completion_tokens
span, SpanAttributes.GEN_AI_USAGE_OUTPUT_TOKENS, completion_tokens
)
set_span_attribute(span, SpanAttributes.LLM_USAGE_TOTAL_TOKENS, total_tokens)

set_span_attribute(
span, SpanAttributes.LLM_RESPONSE_MODEL, complete_response.get("model")
span, SpanAttributes.GEN_AI_RESPONSE_MODEL, complete_response.get("model")
)
set_span_attribute(
span, SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens
span, SpanAttributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cache_read_tokens
)
set_span_attribute(
span,
SpanAttributes.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS,
SpanAttributes.GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS,
cache_creation_tokens,
)

Expand All @@ -107,7 +107,7 @@ def _set_token_usage(
input_tokens,
attributes={
**metric_attributes,
SpanAttributes.LLM_TOKEN_TYPE: "input",
SpanAttributes.GEN_AI_TOKEN_TYPE: "input",
},
)

Expand All @@ -116,7 +116,7 @@ def _set_token_usage(
completion_tokens,
attributes={
**metric_attributes,
SpanAttributes.LLM_TOKEN_TYPE: "output",
SpanAttributes.GEN_AI_TOKEN_TYPE: "output",
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def shared_metrics_attributes(response):
return {
**common_attributes,
GEN_AI_SYSTEM: GEN_AI_SYSTEM_ANTHROPIC,
SpanAttributes.LLM_RESPONSE_MODEL: response.get("model"),
SpanAttributes.GEN_AI_RESPONSE_MODEL: response.get("model"),
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ def test_anthropic_completion_legacy(

anthropic_span = spans[0]
assert (
anthropic_span.attributes[f"{SpanAttributes.LLM_PROMPTS}.0.user"]
anthropic_span.attributes[f"{SpanAttributes.GEN_AI_PROMPT}.0.user"]
== f"{HUMAN_PROMPT}\nHello world\n{AI_PROMPT}"
)
assert anthropic_span.attributes.get(f"{SpanAttributes.LLM_COMPLETIONS}.0.content")
assert anthropic_span.attributes.get(f"{SpanAttributes.GEN_AI_COMPLETION}.0.content")
assert (
anthropic_span.attributes.get("gen_ai.response.id")
== "compl_01EjfrPvPEsRDRUKD6VoBxtK"
Expand Down
Loading