From dbf10e05ba696d1199f46638edd9c5f2a509d142 Mon Sep 17 00:00:00 2001 From: Liudmila Molkova Date: Tue, 7 May 2024 22:26:23 -0700 Subject: [PATCH] clean up and add gen-ai specific temp attribute for payload --- docs/attributes-registry/gen-ai.md | 39 ++++----- docs/attributes-registry/llm.md | 33 -------- docs/gen-ai/README.md | 8 +- docs/gen-ai/llm-spans.md | 126 ++++++++++++++++++++++------- model/registry/gen-ai.yaml | 28 ++----- model/trace/gen-ai.yaml | 11 +++ 6 files changed, 137 insertions(+), 108 deletions(-) diff --git a/docs/attributes-registry/gen-ai.md b/docs/attributes-registry/gen-ai.md index 9f8a83cf6c..b192d44a50 100644 --- a/docs/attributes-registry/gen-ai.md +++ b/docs/attributes-registry/gen-ai.md @@ -10,28 +10,23 @@ This document defines the attributes used to describe telemetry in the context of LLM (Large Language Models) requests and responses. -| Attribute | Type | Description | Examples | Stability | -| -------------------------------- | ------ | -------------------------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------- | -| `gen_ai.completion` | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.operation.name` | string | The name of the operation being performed. | `chat`; `completion` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.prompt` | string | The full prompt sent to an LLM. [2] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.request.max_tokens` | int | The maximum number of tokens the LLM generates for a request. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.request.model` | string | The name of the LLM a request is being made to. | `gpt-4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.request.temperature` | double | The temperature setting for the LLM request. | `0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.request.top_p` | double | The top_p sampling setting for the LLM request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.response.finish_reason` | string | The reason the model stopped generating tokens. | `stop`; `content_filter`; `tool_calls` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.response.id` | string | The unique identifier for the completion. | `chatcmpl-123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.response.model` | string | The name of the LLM a response was generated from. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.system` | string | The Generative AI product as identified by the client instrumentation. [3] | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.token.type` | string | The type of token being counted. | `input`; `output` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.usage.completion_tokens` | int | The number of tokens used in the LLM response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the LLM prompt. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - -**[2]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - -**[3]:** The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. +| Attribute | Type | Description | Examples | Stability | +| -------------------------------- | ------ | -------------------------------------------------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------- | +| `gen_ai.event.content` | string | The GenAI event payload serialized into JSON string. | `[{'content': 'What is the capital of France?'}]`; `plain string` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.operation.name` | string | The name of the operation being performed. | `chat`; `completion` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.max_tokens` | int | The maximum number of tokens the LLM generates for a request. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.model` | string | The name of the LLM a request is being made to. | `gpt-4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.temperature` | double | The temperature setting for the LLM request. | `0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.request.top_p` | double | The top_p sampling setting for the LLM request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.finish_reason` | string | The reason the model stopped generating tokens. | `stop`; `content_filter`; `tool_calls` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.id` | string | The unique identifier for the completion. | `chatcmpl-123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.response.model` | string | The name of the LLM a response was generated from. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.system` | string | The Generative AI product as identified by the client instrumentation. [1] | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.token.type` | string | The type of token being counted. | `input`; `output` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.completion_tokens` | int | The number of tokens used in the LLM response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | +| `gen_ai.usage.prompt_tokens` | int | The number of tokens used in the LLM prompt. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. `gen_ai.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. diff --git a/docs/attributes-registry/llm.md b/docs/attributes-registry/llm.md index ca0ae32f48..90fa8674f0 100644 --- a/docs/attributes-registry/llm.md +++ b/docs/attributes-registry/llm.md @@ -24,25 +24,6 @@ linkTitle: LLM -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`gen_ai.request.max_tokens`](/docs/attributes-registry/.md) | int | The maximum number of tokens the LLM generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.request.model`](/docs/attributes-registry/.md) | string | The name of the LLM a request is being made to. | `gpt-4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.request.temperature`](/docs/attributes-registry/.md) | double | The temperature setting for the LLM request. | `0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.request.top_p`](/docs/attributes-registry/.md) | double | The top_p sampling setting for the LLM request. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.system`](/docs/attributes-registry/.md) | string | The Generative AI product as identified by the client instrumentation. [1] | `openai` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** The actual GenAI product may differ from the one identified by the client. For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. - - - -`gen_ai.system` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used. - -| Value | Description | Stability | -|---|---|---| -| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - - @@ -60,10 +41,7 @@ linkTitle: LLM | Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | |---|---|---|---|---|---| -| [`gen_ai.response.id`](/docs/attributes-registry/.md) | string | The unique identifier for the completion. | `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.response.model`](/docs/attributes-registry/.md) | string | The name of the LLM a response was generated from. | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | | [`gen_ai.usage.completion_tokens`](/docs/attributes-registry/.md) | int | The number of tokens used in the LLM response (completion). | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.usage.prompt_tokens`](/docs/attributes-registry/.md) | int | The number of tokens used in the LLM prompt. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | @@ -80,17 +58,6 @@ linkTitle: LLM -| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | -|---|---|---|---|---|---| -| [`gen_ai.completion`](/docs/attributes-registry/.md) | string | The full response received from the LLM. [1] | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | -| [`gen_ai.prompt`](/docs/attributes-registry/.md) | string | The full prompt sent to an LLM. [2] | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) | - -**[1]:** It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - -**[2]:** It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - - - diff --git a/docs/gen-ai/README.md b/docs/gen-ai/README.md index 17d5ef099d..11191bd0be 100644 --- a/docs/gen-ai/README.md +++ b/docs/gen-ai/README.md @@ -10,12 +10,13 @@ path_base_for_github_subdir: **Status**: [Experimental][DocumentStatus] **Warning**: -The semantic conventions for GenAI and LLM are currently in development. +The semantic conventions for GenAI are currently in development. We encourage instrumentation libraries and telemetry consumers developers to use the conventions in limited non-critical workloads and share the feedback -This document defines semantic conventions for the following kind of Generative AI systems: +Semantic conventions for Generative AI operations are defined for the following signals: +<<<<<<< HEAD * LLMs Semantic conventions for Generative AI operations are defined for the following signals: @@ -25,5 +26,8 @@ Semantic conventions for Generative AI operations are defined for the following Semantic conventions for LLM operations are defined for the following signals: * [LLM Spans](llm-spans.md): Semantic Conventions for LLM requests - *spans*. +======= +* [Generative AI Spans](llm-spans.md): Semantic Conventions for Generative AI *spans*. +>>>>>>> 1d913bc7 (clean up and add gen-ai specific temp attribute for payload) [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.26.0/specification/document-status.md diff --git a/docs/gen-ai/llm-spans.md b/docs/gen-ai/llm-spans.md index d071c0de1c..3ce89f8fc8 100644 --- a/docs/gen-ai/llm-spans.md +++ b/docs/gen-ai/llm-spans.md @@ -1,8 +1,8 @@ -# Semantic Conventions for LLM requests +# Semantic Conventions for Generative AI spans **Status**: [Experimental][DocumentStatus] @@ -11,7 +11,7 @@ linkTitle: LLM requests - [Configuration](#configuration) -- [LLM Request attributes](#llm-request-attributes) +- [LLM Request attributes](#generative-ai-request-attributes) - [Events](#events) - [System message](#system-message) - [User message](#user-message) @@ -21,13 +21,14 @@ linkTitle: LLM requests - [Tool message](#tool-message) - [Chat response](#chat-response) - [`Message` object](#message-object) + - [Recording GenAI events as span events](#recording-genai-events-as-span-events) - [Examples](#examples) - [Chat completion](#chat-completion) - [Tools](#tools) -A request to an LLM is modeled as a span in a trace. +A request to a Generative AI system is modeled as a span in a trace. **Span kind:** MUST always be `CLIENT`. @@ -46,7 +47,7 @@ This is for three primary reasons: 2. Data size concerns. Although there is no specified limit to sizes, there are practical limitations in programming languages and telemetry systems. Some LLMs allow for extremely large context windows that end users may take full advantage of. 3. Performance concerns. Sending large amounts of data to a telemetry backend may cause performance issues for the application. -## LLM Request attributes +## Generative AI Request attributes These attributes track input data and metadata for a request to an LLM. Each attribute represents a concept that is common to most LLMs. @@ -97,14 +98,10 @@ These attributes track input data and metadata for a request to an LLM. Each att In the lifetime of an GenAI span, an event for each message application sends to GenAI and receives in response from it MAY be created, depending on the configuration of the instrumentation. The generic events applicable to multiple GenAI models follow `gen_ai.{type}.message` naming pattern. -GenAI vendor-specific instrumentations SHOULD follow `gen_ai.{gen_ai.system}.{type}.message` pattern to record events that apply to their system only. +GenAI vendor-specific instrumentations SHOULD follow `gen_ai.{gen_ai.system}.{type}.message` pattern to record system-specific events. It's RECOMMENDED to use [Event API](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/event-api.md) to record GenAI events once it's implemented in corresponding language. -If, however Event API is not supported yet, events SHOULD be recorded as span events. - -TODO: There [will be](https://github.com/open-telemetry/semantic-conventions/pull/954) a standard mapping between Span Events and Events. Add link once merged. - The event payload describes message content sent to or received from GenAI and depends on specific messages described in the following sections. Instrumentations for individual GenAI systems MAY add system specific fields into corresponding events payload. @@ -149,7 +146,6 @@ The event name MUST be `gen_ai.system.message`. | Body Field | Type | Description | Examples | Requirement Level | Sensitive | |---|---|---|---|---|---| -| `role` | string | The role of the messages author | `system` | `Opt-In` | | | `content` | string | The contents of the system message. | `"You're a friendly bot that answers questions about OpenTelemetry."` | `Opt-In` | ![Sensitive](https://img.shields.io/badge/-sensitive-red) | ### User message @@ -158,6 +154,7 @@ This event describes the prompt message specified by the user. It's NOT RECOMMENDED to report this event when capturing sensitive content is disabled, unless there are additional system-specific properties instrumentation adds to the event payload. + @@ -190,7 +187,6 @@ The event name MUST be `gen_ai.user.message`. | Body Field | Type | Description | Examples | Requirement Level | Sensitive | |---|---|---|---|---|---| -| `role` | string | The role of the messages author | `user` | `Opt-In` | | | `content` | `AnyValue` | The contents of the user message. | `What telemetry is reported by OpenAI instrumentations?` | `Opt-In` | ![Sensitive](https://img.shields.io/badge/-sensitive-red) | ### Assistant message @@ -229,7 +225,6 @@ The event name MUST be `gen_ai.assistant.message`. | Body Field | Type | Description | Examples | Requirement Level | Sensitive | |---|---|---|---|---|---| -| `role` | string | The role of the messages author | `assistant` | `Conditionally Required`: when the message is returned by GenAI model. | | | `content` | `AnyValue` | The contents of the assistant message. | `Spans, events, metrics defined by the GenAI semantic conventions.` | `Opt-In` | ![Sensitive](https://img.shields.io/badge/-sensitive-red) | | `tool_calls` | [ToolCall](#toolcall-object)[] | The tool calls generated by the model, such as function calls. | `[{"id":"call_mszuSIzqtI65i1wAUOE8w5H4", "function":{"name":"get_link_to_otel_semconv", "arguments":"{\"semconv\":\"gen_ai\"}"}, "type":"function"}]` | `Conditionally Required`: if available | ![Mixed](https://img.shields.io/badge/-mixed-orange) | @@ -288,10 +283,9 @@ The event name MUST be `gen_ai.tool.message`. | `content` | string | The contents of the tool message. | `opentelemetry.io` | `Opt-In` | ![Sensitive](https://img.shields.io/badge/-sensitive-red) | | `tool_call_id` | string | Tool call that this message is responding to. | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Required` | | -### Chat response +### Choice message This event describes the model-generated chat response message (choice). - If GenAI model returns multiple choices, each of the message SHOULD be recorded as an individual event. ### Assistant response @@ -330,7 +324,8 @@ The event name MUST be `gen_ai.choice`. When response is streamed, instrumentations that report response events MUST reconstruct and report the full message and MUST NOT report individual chunks as events. -If the request to GenAI model fails with an error before content is received, instrumentation SHOULD report an event with truncated content it was able to receive. +If the request to GenAI model fails with an error before content is received, instrumentation SHOULD report an event with truncated content it was able to receive and if `finish_reason` is not +yet received, it MUST set it to `error`. Response event payload has the following fields: @@ -338,7 +333,7 @@ Response event payload has the following fields: |---|---|---|---|---|---| | `finish_reason` | string | The reason the model stopped generating tokens. | `stop`, `tool_calls`, `content_filter` | `Required` | | | `index` | int | The index of the choice in the list of choices. | `1` | `Required` | | -| `message` | [Message](#message-object) | GenAI response message | `{"role":"assistant", "content":"The OpenAI semantic conventions are available at opentelemetry.io"}` | `Recommended` | ![Mixed](https://img.shields.io/badge/-mixed-orange) | +| `message` | [Message](#message-object) | GenAI response message | `{"content":"The OpenAI semantic conventions are available at opentelemetry.io"}` | `Recommended` | ![Mixed](https://img.shields.io/badge/-mixed-orange) | #### `Message` object @@ -347,6 +342,37 @@ The message structure matches one of the messages defined in this document depen - [Assistant message](#assistant-message) - [Tool message](#tool-message) +### Recording GenAI events as span events + + + +> Note: +> It is NOT RECOMMENDED to report GenAI events as span events. It MAY only be done for prototyping and experimentation when +> neither Event nor Log API are available in the corresponding language or don't yet support structured payload data. + +Use the following attribute to record payload of the GenAI event on the span event + + + + + + + + +| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability | +|---|---|---|---|---|---| +| [`gen_ai.event.content`](/docs/attributes-registry/gen-ai.md) | string | The GenAI event payload serialized into JSON string. | `[{'content': 'What is the capital of France?'}]`; `plain string` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) | + +**[1]:** If and only if recording GenAI events as span events. It is NOT RECOMMENDED to record GenAI events with span event API and SHOULD only be used if Event API is not yet available in the corresponding OpenTelemetry API package. + + + + + + + + + ## Examples ### Chat completion @@ -399,8 +425,8 @@ Events: | Property | Value | |---------------------|-------------------------------------------------------| | `gen_ai.system` | `"openai"` | - | Event payload (with sensitive content) | `{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"Follow GenAI semantic conventions available at opentelemetry.io."}}` | - | Event payload (without sensitive content) | `{"index":0,"finish_reason":"stop","message":{"role":"assistant"}}` | + | Event payload (with sensitive content) | `{"index":0,"finish_reason":"stop","message":{"content":"Follow GenAI semantic conventions available at opentelemetry.io."}}` | + | Event payload (without sensitive content) | `{"index":0,"finish_reason":"stop","message":{"content":"REDACTED"}}` | ### Tools @@ -448,8 +474,8 @@ Here's the telemetry generated for each step in this scenario: | Property | Value | |---------------------|-------------------------------------------------------| | `gen_ai.system` | `"openai"` | - | Event payload (with sensitive content) | `{"index":0,"finish_reason":"tool_calls","message":{"role":"assistant","tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","arguments":"{\"semconv\":\"GenAI\"}"},"type":"function"}]}` | - | Event payload (withput sensitive content) | `{"index":0,"finish_reason":"tool_calls","message":{"role":"assistant","tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv"},"type":"function"}]}` | + | Event payload (with sensitive content) | `{"index":0,"finish_reason":"tool_calls","message":{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","arguments":"{\"semconv\":\"GenAI\"}"},"type":"function"}]}` | + | Event payload (without sensitive content) | `{"index":0,"finish_reason":"tool_calls","message":{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","arguments":"REDACTED"},"type":"function"}]}` | 2. Application executes the tool call. Application may create span which is not covered by this semantic convention. 3. Final chat completion call @@ -475,30 +501,74 @@ Here's the telemetry generated for each step in this scenario: | Property | Value | |---------------------|-------------------------------------------------------| | `gen_ai.system` | `"openai"` | - | Event payload | `{"role":"user","content":"How to instrument GenAI library with OTel?"}` | + | Event payload | `{"content":"How to instrument GenAI library with OTel?"}` | - `gen_ai.assistant.message` (could be reported when capturing sensitive content is disabled) | Property | Value | |---------------------|-------------------------------------------------------| | `gen_ai.system` | `"openai"` | - | Event payload (with sensitive content) | `{"role":"assistant","tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","arguments":"{\"semconv\":\"GenAI\"}"},"type":"function"}]}` | - | Event payload (without sensitive content) | `{"role":"assistant","tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","type":"function"}]}` | + | Event payload (with sensitive content) | `{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","arguments":"{\"semconv\":\"GenAI\"}"},"type":"function"}]}` | + | Event payload (without sensitive content) | `{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","arguments":"REDACTED"},"type":"function"}]}` | - `gen_ai.tool.message` (could be reported when capturing sensitive content is disabled) | Property | Value | |---------------------|-------------------------------------------------------| | `gen_ai.system` | `"openai"` | - | Event payload (with sensitive content) | `{"role":"tool","content":"opentelemetry.io/semconv/gen-ai","tool_call_id":"call_VSPygqKTWdrhaFErNvMV18Yl"}` | - | Event payload (without sensitive content) | `{"role":"tool","tool_call_id":"call_VSPygqKTWdrhaFErNvMV18Yl"}` | + | Event payload (with sensitive content) | `{"role":"tool","content":"opentelemetry.io/semconv/gen-ai","tool_call_id":"call_VSPygqKTWdrhaFErNvMV18Yl"}` | + | Event payload (without sensitive content) | `{"role":"tool","content":"REDACTED","tool_call_id":"call_VSPygqKTWdrhaFErNvMV18Yl"}` | - `gen_ai.choice` (could be reported when capturing sensitive content is disabled) | Property | Value | |---------------------|-------------------------------------------------------| | `gen_ai.system` | `"openai"` | - | Event payload (with sensitive content) | `{"index":0,"finish_reason":"stop","message":{"role":"assistant","content":"Follow OTel semconv available at opentelemetry.io/semconv/gen-ai"}}` | - | Event payload (without sensitive content) | `{"index":0,"finish_reason":"stop","message":{"role":"assistant"}}` | + | Event payload (with sensitive content) | `{"index":0,"finish_reason":"stop","message":{"content":"Follow OTel semconv available at opentelemetry.io/semconv/gen-ai"}}` | + | Event payload (without sensitive content) | `{"index":0,"finish_reason":"stop","message":{"content":"REDACTED"}}` | + +### Chat completion with multiple choices + +This example covers the following scenario: + +- user requests 2 chat completion from OpenAI GPT-4 model for the following prompt: + + - System message: `You're a friendly bot that answers questions about OpenTelemetry.` + - User message: `How to instrument GenAI library with OTel?` + +- The model responds with two choices + - `"Follow GenAI semantic conventions available at opentelemetry.io."` message + - `"Use OpenAI instrumentation library."` message + +Span: + +| Attribute name | Value | +|---------------------|-------------------------------------------------------| +| Span name | `"chat.completion gpt-4"` | +| `gen_ai.system` | `"openai"` | +| `gen_ai.request.model`| `"gpt-4"` | +| `gen_ai.request.max_tokens`| `200` | +| `gen_ai.request.top_p`| `1.0` | +| `gen_ai.response.id`| `"chatcmpl-9J3uIL87gldCFtiIbyaOvTeYBRA3l"` | +| `gen_ai.response.model`| `"gpt-4-0613"` | +| `gen_ai.usage.completion_tokens`| `77` | +| `gen_ai.usage.prompt_tokens`| `52` | +| `gen_ai.response.finish_reason`| `"stop"` | + +Events: + +1. `gen_ai.system.message`: the same as in the previous example +2. `gen_ai.user.message`: the same as in the previous example +3. `gen_ai.choice` + | Property | Value | + |---------------------|-------------------------------------------------------| + | `gen_ai.system` | `"openai"` | + | Event payload (with sensitive content) | `{"index":0,"finish_reason":"stop","message":{"content":"Follow GenAI semantic conventions available at opentelemetry.io."}}` | +4. `gen_ai.choice` + | Property | Value | + |---------------------|-------------------------------------------------------| + | `gen_ai.system` | `"openai"` | + | Event payload (with sensitive content) | `{"index":1,"finish_reason":"stop","message":{"content":"Use OpenAI instrumentation library."}}` | [DocumentStatus]: https://github.com/open-telemetry/opentelemetry-specification/tree/v1.31.0/specification/document-status.md + diff --git a/model/registry/gen-ai.yaml b/model/registry/gen-ai.yaml index c3a65a53d7..58a7b31f6b 100644 --- a/model/registry/gen-ai.yaml +++ b/model/registry/gen-ai.yaml @@ -20,55 +20,46 @@ groups: For example, when using OpenAI client libraries to communicate with Mistral, the `gen_ai.system` is set to `openai` based on the instrumentation's best knowledge. examples: 'openai' - tag: llm-generic-request - id: request.model stability: experimental type: string brief: The name of the LLM a request is being made to. examples: 'gpt-4' - tag: llm-generic-request - id: request.max_tokens stability: experimental type: int brief: The maximum number of tokens the LLM generates for a request. examples: [100] - tag: llm-generic-request - id: request.temperature stability: experimental type: double brief: The temperature setting for the LLM request. examples: [0.0] - tag: llm-generic-request - id: request.top_p stability: experimental type: double brief: The top_p sampling setting for the LLM request. examples: [1.0] - tag: llm-generic-request - id: response.id stability: experimental type: string brief: The unique identifier for the completion. examples: ['chatcmpl-123'] - tag: llm-generic-response - id: response.model stability: experimental type: string brief: The name of the LLM a response was generated from. examples: ['gpt-4-0613'] - tag: llm-generic-response - id: response.finish_reason stability: experimental type: string brief: The reason the model stopped generating tokens. examples: ['stop', 'content_filter', 'tool_calls'] - tag: llm-generic-event - id: usage.prompt_tokens stability: experimental type: int brief: The number of tokens used in the LLM prompt. examples: [100] - tag: llm-generic-response - id: usage.completion_tokens stability: experimental type: int @@ -89,22 +80,13 @@ groups: brief: 'Output tokens (completion, response, etc.)' brief: The type of token being counted. examples: ['input', 'output'] - - id: prompt - stability: experimental - type: string - brief: The full prompt sent to an LLM. - note: It's RECOMMENDED to format prompts as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - examples: ["[{'role': 'user', 'content': 'What is the capital of France?'}]"] - tag: llm-generic-events - - id: completion - stability: experimental - type: string - brief: The full response received from the LLM. - note: It's RECOMMENDED to format completions as JSON string matching [OpenAI messages format](https://platform.openai.com/docs/guides/text-generation) - examples: ["[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]"] - tag: llm-generic-events - id: operation.name stability: experimental type: string brief: The name of the operation being performed. examples: ['chat', 'completion'] + - id: event.content + stability: experimental + type: string + brief: The GenAI event payload serialized into JSON string. + examples: ["[{'content': 'What is the capital of France?'}]", "plain string"] diff --git a/model/trace/gen-ai.yaml b/model/trace/gen-ai.yaml index 5c78821e8f..51ad3b7dac 100644 --- a/model/trace/gen-ai.yaml +++ b/model/trace/gen-ai.yaml @@ -88,3 +88,14 @@ groups: This event describes the Gen AI response message. extends: gen_ai.common.event.attributes + - id: gen_ai.span.event.content + type: attribute_group + brief: > + Describes the content of a span event. + attributes: + - ref: gen_ai.event.content + requirement_level: + conditionally_required: > + If and only if recording GenAI events as span events. It is NOT RECOMMENDED to record + GenAI events with span event API and SHOULD only be used if Event API is not yet + available in the corresponding OpenTelemetry API package.