diff --git a/.chloggen/1469.yaml b/.chloggen/1469.yaml
new file mode 100644
index 0000000000..7d7b4ba5cc
--- /dev/null
+++ b/.chloggen/1469.yaml
@@ -0,0 +1,5 @@
+change_type: 'enhancement'
+component: gen_ai
+note: Yamlify gen_ai events and clean up examples.
+
+issues: [1469]
diff --git a/docs/attributes-registry/gen-ai.md b/docs/attributes-registry/gen-ai.md
index 844a947bdf..c5b103e6a0 100644
--- a/docs/attributes-registry/gen-ai.md
+++ b/docs/attributes-registry/gen-ai.md
@@ -14,28 +14,42 @@
This document defines the attributes used to describe telemetry in the context of Generative Artificial Intelligence (GenAI) Models requests and responses.
-| Attribute | Type | Description | Examples | Stability |
-| ------------------------------------------------------------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------ | -------------------------------- | ---------------------------------------------------------------- |
-| `gen_ai.operation.name` | string | The name of the operation being performed. [1] | `chat`; `text_completion` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.frequency_penalty` | double | The frequency penalty setting for the GenAI request. | `0.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.max_tokens` | int | The maximum number of tokens the model generates for a request. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.model` | string | The name of the GenAI model a request is being made to. | `gpt-4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.presence_penalty` | double | The presence penalty setting for the GenAI request. | `0.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.stop_sequences` | string[] | List of sequences that the model will use to stop generating further tokens. | `["forest", "lived"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.temperature` | double | The temperature setting for the GenAI request. | `0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.top_k` | double | The top_k sampling setting for the GenAI request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.request.top_p` | double | The top_p sampling setting for the GenAI request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.response.finish_reasons` | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]`; `["stop", "length"]` | ![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 model that generated the response. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.system` | string | The Generative AI product as identified by the client or server instrumentation. [2] | `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.input_tokens` | int | The number of tokens used in the GenAI input (prompt). | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.usage.output_tokens` | int | The number of tokens used in the GenAI response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-
-**[1]:** If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value.
-
-**[2]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+| Attribute | Type | Description | Examples | Stability |
+| ------------------------------------------------------------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------- | ---------------------------------------------------------------- |
+| `gen_ai.agent.description` | string | Free-form description of the GenAI agent provided by the application. | `Helps with math problems`; `Generates fiction stories` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.agent.id` | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.agent.name` | string | Human-readable name of the GenAI agent provided by the application. | `Math Tutor`; `Fiction Writer` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.message.id` | string | Identifies message sent to or received from Generative AI model or agent. [1] | `msg_sLMd7grQfjFXgu5ZeHCXmBr7`; `chatcmpl-123` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.message.status` | string | The status of the message. | `in_progress`; `completed`; `incomplete` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.operation.name` | string | The name of the operation being performed. [2] | `chat`; `text_completion`; `create_agent` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.frequency_penalty` | double | The frequency penalty setting for the GenAI request. | `0.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.max_input_tokens` | int | The maximum number of prompt tokens the model can use. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.max_output_tokens` | int | The maximum number of completion tokens the model generates in response. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.model` | string | The name of the GenAI model a request is being made to. | `gpt-4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.presence_penalty` | double | The presence penalty setting for the GenAI request. | `0.1` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.response_format` | string | The response format that is requested. | `text`; `json_object`; `json_schema` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.stop_sequences` | string[] | List of sequences that the model will use to stop generating further tokens. | `["forest", "lived"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.temperature` | double | The temperature setting for the GenAI request. | `0.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.top_k` | double | The top_k sampling setting for the GenAI request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.request.top_p` | double | The top_p sampling setting for the GenAI request. | `1.0` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.response.finish_reasons` | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]`; `["stop", "length"]` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.response.model` | string | The name of the model that generated the response. | `gpt-4-0613` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.system` | string | The Generative AI product as identified by the client or server instrumentation. [3] | `openai` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.thread.id` | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.thread.run.id` | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.thread.run.status` | string | The thread run status | `queued`; `in_progress`; `completed` | ![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.tool.call.id` | string | The tool call identifier. | `call_mszuSIzqtI65i1wAUOE8w5H4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.tool.name` | string | The tool call identifier. | `call_mszuSIzqtI65i1wAUOE8w5H4` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.usage.input_tokens` | int | The number of tokens used in the GenAI input (prompt). | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.usage.output_tokens` | int | The number of tokens used in the GenAI response (completion). | `180` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[1]:** For inference operations such as `chat` or `text_completion`, it SHOULD be the completion identifier returned by the GenAI system and may not be unique if multiple choices are returned.
+If message history is managed by the application, agent, or framework, it SHOULD match the identifier used by the message history management system.
+
+**[2]:** If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value.
+
+**[3]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
by `gen_ai.request.model` and `gen_ai.response.model` attributes.
The actual GenAI product may differ from the one identified by the client.
@@ -45,12 +59,50 @@ is set to `openai` based on the instrumentation's best knowledge.
For custom model, a custom friendly name SHOULD be used.
If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+`gen_ai.message.status` 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 |
+| ------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------- |
+| `completed` | The message has been completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `in_progress` | The message is in progress | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `incomplete` | The message has ended due to reaching maximum number of input or output tokens | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
`gen_ai.operation.name` 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 |
-| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
-| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| Value | Description | Stability |
+| --------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
+| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[4]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[5]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[6]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[7]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[8]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
+`gen_ai.request.response_format` 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 |
+| ------------- | --------------------------- | ---------------------------------------------------------------- |
+| `json_object` | JSON object response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `json_schema` | JSON schema response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `text` | Text response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
`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.
@@ -62,6 +114,19 @@ If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+`gen_ai.thread.run.status` 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 |
+| ----------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
+| `canceled` | The thread run has been canceled | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `completed` | The thread run has completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `expired` | The thread run has expired | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `failed` | The thread run has failed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `in_progress` | The thread run is in progress | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `incomplete` | The thread run has ended due to reaching maximum number of input or output tokens | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `queued` | The thread run is queued | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `requires_action` | The thread run requires action. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
`gen_ai.token.type` 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 |
@@ -73,20 +138,11 @@ If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
Thie group defines attributes for OpenAI.
-| Attribute | Type | Description | Examples | Stability |
-| --------------------------------------------------------------------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------- | ------------------ | ---------------------------------------------------------------- |
-| `gen_ai.openai.request.response_format` | string | The response format that is requested. | `json` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.openai.request.seed` | int | Requests with same seed value more likely to return same result. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.openai.request.service_tier` | string | The service tier requested. May be a specific tier, detault, or auto. | `auto`; `default` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `gen_ai.openai.response.service_tier` | string | The service tier used for the response. | `scale`; `detault` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-
-`gen_ai.openai.request.response_format` 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 |
-| ------------- | --------------------------- | ---------------------------------------------------------------- |
-| `json_object` | JSON object response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `json_schema` | JSON schema response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `text` | Text response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| Attribute | Type | Description | Examples | Stability |
+| --------------------------------------------------------------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------- | ------------------ | ---------------------------------------------------------------- |
+| `gen_ai.openai.request.seed` | int | Requests with same seed value more likely to return same result. | `100` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.openai.request.service_tier` | string | The service tier requested. May be a specific tier, detault, or auto. | `auto`; `default` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `gen_ai.openai.response.service_tier` | string | The service tier used for the response. | `scale`; `detault` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
`gen_ai.openai.request.service_tier` 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.
@@ -99,9 +155,20 @@ Thie group defines attributes for OpenAI.
Describes deprecated `gen_ai` attributes.
-| Attribute | Type | Description | Examples | Stability |
-| ------------------------------------------------------------------------------------------------------------------ | ------ | --------------------------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
-| `gen_ai.completion` | string | Deprecated, use Event API to report completions contents. | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. |
-| `gen_ai.prompt` | string | Deprecated, use Event API to report prompt contents. | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. |
-| `gen_ai.usage.completion_tokens` | int | Deprecated, use `gen_ai.usage.output_tokens` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.usage.output_tokens` attribute. |
-| `gen_ai.usage.prompt_tokens` | int | Deprecated, use `gen_ai.usage.input_tokens` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.usage.input_tokens` attribute. |
+| Attribute | Type | Description | Examples | Stability |
+| --------------------------------------------------------------------------------------------------------------------------------------- | ------ | --------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
+| `gen_ai.completion` | string | Deprecated, use Event API to report completions contents. | `[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. |
+| `gen_ai.openai.request.response_format` | string | Deprecated, use `gen_ai.request.response_format` instead. | `text`; `json_object`; `json_schema` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.request.response_format` attribute. |
+| `gen_ai.prompt` | string | Deprecated, use Event API to report prompt contents. | `[{'role': 'user', 'content': 'What is the capital of France?'}]` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Removed, no replacement at this time. |
+| `gen_ai.request.max_tokens` | int | Deprecated, use `gen_ai.request.max_tokens` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.request.max_completion_tokens` attribute. |
+| `gen_ai.response.id` | string | Deprecated, use `gen_ai.message.id` instead. | `chatcmpl-123` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.message.id` attribute. |
+| `gen_ai.usage.completion_tokens` | int | Deprecated, use `gen_ai.usage.output_tokens` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.usage.output_tokens` attribute. |
+| `gen_ai.usage.prompt_tokens` | int | Deprecated, use `gen_ai.usage.input_tokens` instead. | `42` | ![Deprecated](https://img.shields.io/badge/-deprecated-red)
Replaced by `gen_ai.usage.input_tokens` attribute. |
+
+`gen_ai.openai.request.response_format` 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 |
+| ------------- | --------------------------- | ---------------------------------------------------------------- |
+| `json_object` | JSON object response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `json_schema` | JSON schema response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `text` | Text response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
diff --git a/docs/gen-ai/azure-ai-inference.md b/docs/gen-ai/azure-ai-inference.md
index 7275e19c67..603e43e39f 100644
--- a/docs/gen-ai/azure-ai-inference.md
+++ b/docs/gen-ai/azure-ai-inference.md
@@ -23,23 +23,24 @@ The Semantic Conventions for [Azure AI Inference](https://learn.microsoft.com/az
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [3] | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [4] | `80`; `8080`; `443` | `Conditionally Required` If not default (443). | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`az.namespace`](/docs/attributes-registry/azure.md) | string | [Azure Resource Provider Namespace](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-services-resource-providers) as recognized by the client. [5] | `Microsoft.CognitiveServices` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.message.id`](/docs/attributes-registry/gen-ai.md) | string | Identifies message sent to or received from Generative AI model or agent. [6] | `msg_sLMd7grQfjFXgu5ZeHCXmBr7`; `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.frequency_penalty`](/docs/attributes-registry/gen-ai.md) | double | The frequency penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`gen_ai.request.max_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of tokens the model generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of prompt tokens the model can use. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of completion tokens the model generates in response. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.presence_penalty`](/docs/attributes-registry/gen-ai.md) | double | The presence penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.stop_sequences`](/docs/attributes-registry/gen-ai.md) | string[] | List of sequences that the model will use to stop generating further tokens. | `["forest", "lived"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the GenAI request. | `0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the GenAI request. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.response.finish_reasons`](/docs/attributes-registry/gen-ai.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]`; `["stop", "length"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`gen_ai.response.id`](/docs/attributes-registry/gen-ai.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/gen-ai.md) | string | The name of the model that generated the response. [6] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. [7] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.usage.input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of prompt tokens as reported in the usage prompt_tokens property of the response. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.usage.output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of completion tokens as reported in the usage completion_tokens property of the response. | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [9] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
**[1]:** If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value.
@@ -53,9 +54,14 @@ Instrumentations SHOULD document the list of errors they report.
**[5]:** When `az.namespace` attribute is populated, it MUST be set to `Microsoft.CognitiveServices` for all operations performed by Azure AI Inference clients.
-**[6]:** If available. The name of the GenAI model that provided the response. If the model is supplied by a vendor, then the value must be the exact name of the model actually used. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+**[6]:** For inference operations such as `chat` or `text_completion`, it SHOULD be the completion identifier returned by the GenAI system and may not be unique if multiple choices are returned.
+If message history is managed by the application, agent, or framework, it SHOULD match the identifier used by the message history management system.
-**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+**[7]:** If available. The name of the GenAI model that provided the response. If the model is supplied by a vendor, then the value must be the exact name of the model actually used. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[8]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[9]:** if available and if operation involves remote calls against GenAI service.
`error.type` 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.
@@ -68,8 +74,30 @@ Instrumentations SHOULD document the list of errors they report.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [12] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [13] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [14] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[10]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[11]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[12]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[13]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[14]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
diff --git a/docs/gen-ai/gen-ai-agent-spans.md b/docs/gen-ai/gen-ai-agent-spans.md
new file mode 100644
index 0000000000..4e69c5c0aa
--- /dev/null
+++ b/docs/gen-ai/gen-ai-agent-spans.md
@@ -0,0 +1,736 @@
+
+
+# Semantic Conventions for GenAI agent and framework spans
+
+**Status**: [Experimental][DocumentStatus]
+
+
+
+
+
+- [Spans](#spans)
+ - [Create agent span](#create-agent-span)
+ - [Create thread span](#create-thread-span)
+ - [Create message span](#create-message-span)
+ - [Start thread run span](#start-thread-run-span)
+ - [Process thread run span](#process-thread-run-span)
+ - [Tool execution span](#tool-execution-span)
+ - [Submit tool outputs span](#submit-tool-outputs-span)
+- [Examples](#examples)
+ - [Backend-side RAG](#backend-side-rag)
+ - [GenAI agent with tool calls](#genai-agent-with-tool-calls)
+ - [GenAI agent with tool calls without streaming](#genai-agent-with-tool-calls-without-streaming)
+
+
+
+Generative AI scenarios may involve multiple steps. For example RAG pattern implementation usually involves
+the following steps:
+
+- initial request to the GenAI model to rewrite user query
+- getting embeddings for the rewritten query
+- searching for similar documents in the vector store using embeddings
+- getting completion from the GenAI model based on the similar documents.
+
+These steps may be done by the application itself using GenAI models and vector databases.
+It's also common to leverage client framework such as [LangGraph](https://github.com/langchain-ai/langgraph)
+or service offerings such as [OpenAI Assistants](https://platform.openai.com/docs/assistants),
+[Azure AI Agents](TODO link), or [Amazon Bedrock Agents](https://aws.amazon.com/bedrock/agents/).
+
+This document defines semantic conventions for GenAI agent calls that are
+handled by the remote agent service.
+It MAY be applicable to agent operations that are performed by the GenAI
+framework locally.
+
+The semantic conventions for GenAI agents extend and override the semantic conventions
+for [Gen AI Spans](gen-ai-spans.md).
+
+## Spans
+
+### Create agent span
+
+Describes GenAI agent creation and is usually applicable when working with remote agent
+services.
+
+The `gen_ai.operation.name` MUST be `create_agent`.
+
+The **span name** SHOULD be `create_agent {gen_ai.agent.name}`.
+Semantic conventions for individual GenAI systems and frameworks MAY specify different span name format.
+
+
+
+
+
+
+
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.agent.description`](/docs/attributes-registry/gen-ai.md) | string | Free-form description of the GenAI agent provided by the application. | `Helps with math problems`; `Generates fiction stories` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Conditionally Required` if applicable. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.agent.name`](/docs/attributes-registry/gen-ai.md) | string | Human-readable name of the GenAI agent provided by the application. | `Math Tutor`; `Fiction Writer` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [3] | `gpt-4` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the GenAI request. | `0.0` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the GenAI request. | `1.0` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [4] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+**[2]:** The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
+the canonical name of exception that occurred, or another low-cardinality error identifier.
+Instrumentations SHOULD document the list of errors they report.
+
+**[3]:** The name of the GenAI model a request is being made to. If the model is supplied by a vendor, then the value must be the exact name of the model requested. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
+
+**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[6]:** if available and if operation involves remote calls against GenAI service.
+
+`error.type` 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 |
+|---|---|---|
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
+
+The following events SHOULD be reported as children of this span:
+
+- [`gen_ai.system.message`](./gen-ai-events.md#event-gen_aisystemmessage) - captures
+ instructions provided at agent creation time.
+
+### Create thread span
+
+Describes creation of the thread on the GenAI agent and is usually applicable
+when working with remote agent services.
+
+The `gen_ai.operation.name` MUST be `create_thread`.
+
+The **span name** SHOULD be `create_thread`.
+Semantic conventions for individual GenAI systems and frameworks MAY specify
+different span name format.
+
+
+
+
+
+
+
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [3] | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [4] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+**[2]:** The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
+the canonical name of exception that occurred, or another low-cardinality error identifier.
+Instrumentations SHOULD document the list of errors they report.
+
+**[3]:** The name of the GenAI model a request is being made to. If the model is supplied by a vendor, then the value must be the exact name of the model requested. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
+
+**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[6]:** if available and if operation involves remote calls against GenAI service.
+
+`error.type` 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 |
+|---|---|---|
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
+
+The following events SHOULD be reported as children of this span when corresponding
+details are available:
+
+- [`gen_ai.user.message`](./gen-ai-events.md#event-gen_aiusermessage) - captures
+ user messages provided at the thread creation time.
+- [`gen_ai.assistant.message`](./gen-ai-events.md#event-gen_aiassistantmessage) -
+ captures assistant messages provided at the thread creation time.
+
+Instrumentations SHOULD record one `gen_ai.{role}.message` event for each message
+provided at thread creation time.
+
+### Create message span
+
+Describes creation of the message on the GenAI agent and is usually applicable when
+working with remote agent or history management services.
+
+The `gen_ai.operation.name` MUST be `create_message`.
+
+The **span name** SHOULD be `create_message`.
+Semantic conventions for individual GenAI systems and frameworks MAY specify
+different span name format.
+
+
+
+
+
+
+
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.message.id`](/docs/attributes-registry/gen-ai.md) | string | Identifies message sent to or received from Generative AI model or agent. [3] | `msg_sLMd7grQfjFXgu5ZeHCXmBr7`; `chatcmpl-123` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [4] | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [5] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+**[2]:** The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
+the canonical name of exception that occurred, or another low-cardinality error identifier.
+Instrumentations SHOULD document the list of errors they report.
+
+**[3]:** For inference operations such as `chat` or `text_completion`, it SHOULD be the completion identifier returned by the GenAI system and may not be unique if multiple choices are returned.
+If message history is managed by the application, agent, or framework, it SHOULD match the identifier used by the message history management system.
+
+**[4]:** The name of the GenAI model a request is being made to. If the model is supplied by a vendor, then the value must be the exact name of the model requested. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
+
+**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[7]:** if available and if operation involves remote calls against GenAI service.
+
+`error.type` 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 |
+|---|---|---|
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
+
+The one of the following events SHOULD be reported as a child of this span:
+
+- [`gen_ai.user.message`](./gen-ai-events.md#event-gen_aiusermessage) - captures
+ user messages provided at the thread creation time.
+- [`gen_ai.assistant.message`](./gen-ai-events.md#event-gen_aiassistantmessage) -
+ captures assistant messages provided at the thread creation time.
+
+### Start thread run span
+
+Describes creation of the thread run on GenAI agent and is usually applicable
+when working with remote agents.
+
+The `gen_ai.operation.name` MUST be `start_thread_run`.
+
+The **span name** SHOULD be `start_thread_run`.
+
+Semantic conventions for individual GenAI systems and frameworks MAY specify
+different span name format.
+
+This span SHOULD be reported when application is starting a run without awaiting
+its completion. It SHOULD NOT be reported when instrumentation can capture the
+full run processing. Full processing is covered by the
+[Process thread run span](#process-thread-run-span).
+
+
+
+
+
+
+
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.request.max_input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of prompt tokens the model can use. | `100` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of completion tokens the model generates in response. | `100` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [3] | `gpt-4` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the GenAI request. | `0.0` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the GenAI request. | `1.0` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. | `gpt-4-0613` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.status`](/docs/attributes-registry/gen-ai.md) | string | The thread run status [4] | `queued`; `in_progress`; `completed` | `Conditionally Required` If run has started. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.usage.input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of input tokens for the whole run | `100` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.usage.output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of output tokens for the whole run | `180` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [5] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+**[2]:** The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
+the canonical name of exception that occurred, or another low-cardinality error identifier.
+Instrumentations SHOULD document the list of errors they report.
+
+**[3]:** The name of the GenAI model a request is being made to. If the model is supplied by a vendor, then the value must be the exact name of the model requested. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[4]:** SHOULD capture the last known status of the thread run.
+
+**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
+
+**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[7]:** if available and if operation involves remote calls against GenAI service.
+
+`error.type` 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 |
+|---|---|---|
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+`gen_ai.thread.run.status` 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 |
+|---|---|---|
+| `canceled` | The thread run has been canceled | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `completed` | The thread run has completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `expired` | The thread run has expired | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `failed` | The thread run has failed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `in_progress` | The thread run is in progress | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `incomplete` | The thread run has ended due to reaching maximum number of input or output tokens | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `queued` | The thread run is queued | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `requires_action` | The thread run requires action. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
+
+The the following events SHOULD be reported as a child of this span when corresponding
+details are available:
+
+- [`gen_ai.user.message`](./gen-ai-events.md#event-gen_aiusermessage) - captures
+ user messages provided to the processing call.
+
+### Process thread run span
+
+Describes creation and full processing of the thread run on GenAI agent.
+It's applicable for operations representing calls to remote GenAI agents or
+logical operations performed by the GenAI framework or application code.
+
+The `gen_ai.operation.name` MUST be `process_thread_run`.
+
+The **span name** SHOULD be `process_thread_run`.
+Semantic conventions for individual GenAI systems and frameworks MAY specify
+different span name format.
+
+The span SHOULD be reported for streaming runs or for operations
+that involve polling the run status and SHOULD cover full duration of the
+run including tool calls and time awaiting the final completion.
+
+Depending on the scenario and application code, this
+may not be possible. In this case the span SHOULD cover the part that
+instrumentation is able to capture and ensure that `gen_ai.thread.run.status`
+attribute value reflects the last known status (`in_process`, `requires_action`,
+etc).
+
+
+
+
+
+
+
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.request.max_input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of prompt tokens the model can use. | `100` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of completion tokens the model generates in response. | `100` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [3] | `gpt-4` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the GenAI request. | `0.0` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the GenAI request. | `1.0` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. | `gpt-4-0613` | `Conditionally Required` If provided by the application. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.status`](/docs/attributes-registry/gen-ai.md) | string | The thread run status [4] | `queued`; `in_progress`; `completed` | `Conditionally Required` If run has started. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.usage.input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of input tokens for the whole run | `100` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.usage.output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of output tokens for the whole run | `180` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [5] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [6] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [7] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+**[2]:** The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
+the canonical name of exception that occurred, or another low-cardinality error identifier.
+Instrumentations SHOULD document the list of errors they report.
+
+**[3]:** The name of the GenAI model a request is being made to. If the model is supplied by a vendor, then the value must be the exact name of the model requested. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[4]:** SHOULD capture the last known status of the thread run.
+
+**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
+
+**[6]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[7]:** if available and if operation involves remote calls against GenAI service.
+
+`error.type` 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 |
+|---|---|---|
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+`gen_ai.thread.run.status` 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 |
+|---|---|---|
+| `canceled` | The thread run has been canceled | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `completed` | The thread run has completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `expired` | The thread run has expired | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `failed` | The thread run has failed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `in_progress` | The thread run is in progress | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `incomplete` | The thread run has ended due to reaching maximum number of input or output tokens | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `queued` | The thread run is queued | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `requires_action` | The thread run requires action. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
+
+The the following events SHOULD be reported as a child of this span when corresponding
+details are available:
+
+- [`gen_ai.user.message`](./gen-ai-events.md#event-gen_aiusermessage) - captures
+ user messages provided to the processing call.
+- [`gen_ai.assistant.message`](./gen-ai-events.md#event-gen_aiassistantmessage) -
+ captures assistant messages generated during the run.
+- [`gen_ai.tool.message`](./gen-ai-events.md#event-gen_aitoolmessage) -
+ captures tool responses submitted to the model during the run.
+
+### Tool execution span
+
+Describes tool execution span.
+
+`gen_ai.operation.name` SHOULD be `execute_tool`.
+
+Span name SHOULD be `execute_tool {gen_ai.tool.name}`.
+
+GenAI instrumentations that are able to instrument tool execution call SHOULD do so.
+
+However, it's common for tools to be executed by the application code. It's recommended
+for the application developers to follow this semantic conventions for tool invoked
+by the application code.
+
+
+
+
+
+
+
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Recommended` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.tool.call.id`](/docs/attributes-registry/gen-ai.md) | string | The tool call identifier. | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.tool.name`](/docs/attributes-registry/gen-ai.md) | string | The tool call identifier. | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
+
+### Submit tool outputs span
+
+Describes submission of the tool outputs to the GenAI agent and is usually applicable
+when working with remote agents.
+
+`gen_ai.operation.name` SHOULD be `submit_tool_outputs`.
+
+Span name SHOULD be `submit_tool_outputs`.
+
+Semantic conventions for individual GenAI systems and frameworks MAY specify
+different span name format.
+
+This span SHOULD be reported when instrumentation can determine that
+application is submitting the tool call output to the model.
+
+When application is submitting the tool call output with the generic GenAI call
+such as `chat` or `text_completion`, the instrumentation SHOULD report generic
+GenAI span since it cannot reliably determine the intent behind the generic GenAI call.
+
+
+
+
+
+
+
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [2] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [3] | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [4] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [5] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [6] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+**[2]:** The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
+the canonical name of exception that occurred, or another low-cardinality error identifier.
+Instrumentations SHOULD document the list of errors they report.
+
+**[3]:** The name of the GenAI model a request is being made to. If the model is supplied by a vendor, then the value must be the exact name of the model requested. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[4]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
+
+**[5]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[6]:** if available and if operation involves remote calls against GenAI service.
+
+`error.type` 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 |
+|---|---|---|
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
+
+The the following events MAY be reported as a child of this span when corresponding
+details are available:
+
+- [`gen_ai.tool.message`](./gen-ai-events.md#event-gen_aitoolmessage) -
+ captures tool responses submitted to the model during this step.
+- [`gen_ai.assistant.message`](./gen-ai-events.md#event-gen_aiassistantmessage) -
+ captures assistant messages generated in response to tool submission.
+
+ Depending on the application code, the `submit_tool_outputs` span may cover the
+ time to submit tool outputs only or may include the process of receiving next
+ response based on the provided outputs. The `gen_ai.assistant.message` could only
+ be reported under `submit_tool_outputs` span when the corresponding operation
+ covers receiving the assistant message.
+
+When `submit_tool_outputs` span is reported along with
+[`process_thread_run` span](#process-thread-run-span), the `gen_ai.tool.message`
+and `gen_ai.assistant.message` events SHOULD, when possible, be reported as
+children of `process_thread_run` span.
+
+## Examples
+
+### Backend-side RAG
+
+This example demonstrates GenAI GitHub bot that, based on the documentation,
+can provide basic support tasks on the repository.
+
+1. Application creates the agent: it uploads documentation that bot will use
+ as the knowledge base and creates and configures the agent.
+
+ ![create_agent_rag.png](./images/create_agent_rag.png)
+
+ The remote agent definition is usually long lived and is reused across
+ multiple thread runs.
+
+ Corresponding `crete_agent` span is annotated with
+ `gen_ai.agent.id` that can be used for cross-correlation with thread runs on that
+ agent. The instructions provided at the agent creation time are recorded in
+ `gen_ai.system.message`.
+
+2. When a new issue created in the repository, the application creates a thread
+ which will contain conversation history about this issue between the
+ application and assistant.
+ Once thread is created, the application starts the thread run and awaits its
+ completion. It then uses generated response to post a comment on the GitHub issue.
+
+ ![create_and_run_thread.png](./images/create_and_run_thread.png)
+
+ Thread creation and processing spans are annotated with `gen_ai.thread.id`
+ attribute which can be used to filter and correlate runs and messages associated
+ with this thread.
+
+ One on more user message may be provided at different stages (on `create_thread`,
+ `process_thread_run` or via an additional `create_message` call). Corresponding
+ `gen_ai.user.message` event(s) are reported as children of the corresponding span.
+
+ If new or additional instructions are provided at the thread run time, they are
+ reported on `gen_ai.system.message` event parented to the `process_thread_run`
+ span.
+
+3. If the author of the issue posts another comment on the issue, the application
+ creates a new message with the user reply on the same thread it created in the Step 2.
+ Then it starts a new run and awaits its completion.
+
+ ![another_run_on_the_thread.png](./images/another_run_on_the_thread.png)
+
+### GenAI agent with tool calls
+
+This example shows trace with the GitHub support bot that supports tool calling and
+performs a tool call during the run. In this example, the application uses agent API
+that awaits run processing till completion and is able to record all the messages
+generated during the run.
+
+Agent creation is omitted for brevity.
+
+![run_with_tool_calls_and_streaming.png](./images/run_with_tool_calls_and_streaming.png)
+
+When a new issue is created in the repository, the application creates a new thread
+with the issue description as a user message. Then it starts and processes a thread
+run.
+
+The agent starts processing and then returns `action_required` status with tool call
+request that instrumentation records under `gen_ai.assistant.message` event.
+
+Application executes the tool call (reported as `execute_tool get_customer_info`)
+and submits tool outputs. The `gen_ai.tool.message` event is recorded for each
+executed tool as a child of `submit_tool_outputs` span.
+
+when the final response is received from the agent, it's recorded as `gen_ai.assistant.message`
+event parented to `process_thread_run` span.
+
+### GenAI agent with tool calls without streaming
+
+This example is similar to the [GenAI agent with tool calls](#genai-agent-with-tool-calls),
+but demonstrates the case when application starts a run and then polls its status.
+When it detects that run required action, it performs a tool call, submits the output
+and then polls run status again until it completes.
+
+Upon run completion, it lists messages on the thread to retrieve the GenAI completion
+generated by the agent.
+
+Agent creation is omitted for brevity.
+
+![run_with_tool_calls_without_streaming.png](./images/run_with_tool_calls_without_streaming.png)
+
+Since in this case application code does not await run completion as a single operation,
+the automatic instrumentation is not able to instrument the whole run duration.
+
+Instead, the instrumentation creates spans for each agent operation (`start_thread_run`,
+`retrieve_run`, `list_messages`, etc) and reports message events under the corresponding
+spans.
+
+[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
diff --git a/docs/gen-ai/gen-ai-events.md b/docs/gen-ai/gen-ai-events.md
index 44eeadc31d..71c6cc9632 100644
--- a/docs/gen-ai/gen-ai-events.md
+++ b/docs/gen-ai/gen-ai-events.md
@@ -10,15 +10,11 @@ linkTitle: Generative AI events
-- [Common attributes](#common-attributes)
-- [System event](#system-event)
-- [User event](#user-event)
-- [Assistant event](#assistant-event)
- - [`ToolCall` object](#toolcall-object)
- - [`Function` object](#function-object)
-- [Tool event](#tool-event)
-- [Choice event](#choice-event)
- - [`Message` object](#message-object)
+- [Event: `gen_ai.system.message`](#event-gen_aisystemmessage)
+- [Event: `gen_ai.user.message`](#event-gen_aiusermessage)
+- [Event: `gen_ai.assistant.message`](#event-gen_aiassistantmessage)
+- [Event: `gen_ai.tool.message`](#event-gen_aitoolmessage)
+- [Event: `gen_ai.choice`](#event-gen_aichoice)
- [Custom events](#custom-events)
- [Examples](#examples)
- [Chat completion](#chat-completion)
@@ -29,7 +25,7 @@ linkTitle: Generative AI events
GenAI instrumentations MAY capture user inputs sent to the model and responses received from it as [events](https://github.com/open-telemetry/opentelemetry-specification/tree/v1.37.0/specification/logs/event-api.md).
-> Note:
+> [!NOTE]
> Event API is experimental and not yet available in some languages. Check [spec-compliance matrix](https://github.com/open-telemetry/opentelemetry-specification/blob/main/spec-compliance-matrix.md#events) to see the implementation status in corresponding language.
Instrumentations MAY capture inputs and outputs if and only if application has enabled the collection of this data.
@@ -50,20 +46,27 @@ Telemetry consumers SHOULD expect to receive unknown body fields.
Instrumentations SHOULD NOT capture undocumented body fields and MUST follow the documented defaults for known fields.
Instrumentations MAY offer configuration options allowing to disable events or allowing to capture all fields.
-## Common attributes
+## Event: `gen_ai.system.message`
-The following attributes apply to all GenAI events.
-
-
+
+**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue)
+
+The event name MUST be `gen_ai.system.message`.
+
+This event describes the instructions passed to the GenAI system inside the prompt.
+
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
by `gen_ai.request.model` and `gen_ai.response.model` attributes.
@@ -85,97 +88,295 @@ If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**Body fields:**
+
+| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| `content` | undefined | The contents of the system message. | `You're a helpful bot` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `role` | string | The actual role of the message author as passed in the message. | `system`; `agent` | `Conditionally Required` if available and not equal to `system`.` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
-## System event
-
-This event describes the instructions passed to the GenAI model.
+## Event: `gen_ai.user.message`
-The event name MUST be `gen_ai.system.message`.
+
+
+
+
+
+
-| Body Field | Type | Description | Examples | Requirement Level |
-|---|---|---|---|---|
-| `role` | string | The actual role of the message author as passed in the message. | `"system"`, `"instructions"` | `Conditionally Required`: if available and not equal to `system` |
-| `content` | `AnyValue` | The contents of the system message. | `"You're a friendly bot that answers questions about OpenTelemetry."` | `Opt-In` |
+**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue)
-## User event
+The event name MUST be `gen_ai.user.message`.
This event describes the prompt message specified by the user.
-The event name MUST be `gen_ai.user.message`.
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**Body fields:**
+
+| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| `attachments`: | map | The list of message attachments to be used by tools. | | `Recommended` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `id` | string | The id of the attachment. | `file_mszuSIzqtI65i1wAUOE8w5H4` | `Recommended` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `tools` | string[] | The types of the tools the attachment is provided for | `["file_search"]` | `Recommended` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `content` | undefined | The contents of the user message. | `What's the weather in Paris?` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `role` | string | The actual role of the message author as passed in the message. | `user`; `customer` | `Conditionally Required` if available and not equal to `user`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
-| Body Field | Type | Description | Examples | Requirement Level |
-|---|---|---|---|---|
-| `role` | string | The actual role of the message author as passed in the message. | `"user"`, `"customer"` | `Conditionally Required`: if available and if not equal to `user` |
-| `content` | `AnyValue` | The contents of the user message. | `What telemetry is reported by OpenAI instrumentations?` | `Opt-In` |
+## Event: `gen_ai.assistant.message`
-## Assistant event
+
+
+
+
+
+
-This event describes the assistant message.
+**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue)
The event name MUST be `gen_ai.assistant.message`.
-| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
-|--------------|--------------------------------|----------------------------------------|-------------------------------------------------|-------------------|
-| `role` | string | The actual role of the message author as passed in the message. | `"assistant"`, `"bot"` | `Conditionally Required`: if available and if not equal to `assistant` |
-| `content` | `AnyValue` | The contents of the assistant message. | `Spans, events, metrics defined by the GenAI semantic conventions.` | `Opt-In` |
-| `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 |
+This event describes the assistant message passed to GenAI system or received from it.
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.message.id`](/docs/attributes-registry/gen-ai.md) | string | Identifies message sent to or received from Generative AI model or agent. [1] | `msg_sLMd7grQfjFXgu5ZeHCXmBr7`; `chatcmpl-123` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.message.status`](/docs/attributes-registry/gen-ai.md) | string | The status of the message at the time event is reported. | `in_progress`; `completed`; `incomplete` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[1]:** For inference operations such as `chat` or `text_completion`, it SHOULD be the completion identifier returned by the GenAI system and may not be unique if multiple choices are returned.
+If message history is managed by the application, agent, or framework, it SHOULD match the identifier used by the message history management system.
+
+**[2]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+`gen_ai.message.status` 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 |
+|---|---|---|
+| `completed` | The message has been completed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `in_progress` | The message is in progress | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `incomplete` | The message has ended due to reaching maximum number of input or output tokens | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+`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.
-### `ToolCall` object
+| Value | Description | Stability |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
-|------------|-----------------------------|------------------------------------|-------------------------------------------------|-------------------|
-| `id` | string | The id of the tool call | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Required` |
-| `type` | string | The type of the tool | `function` | `Required` |
-| `function` | [Function](#function-object)| The function that the model called | `{"name":"get_link_to_otel_semconv", "arguments":{"semconv":"gen_ai"}}` | `Required` |
+**Body fields:**
-### `Function` object
+| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| `content`: | map | The contents of the assistant message. | | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `text`: | map | The text content of the message. | | `Recommended` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `annotations` | undefined | Annotations returned by the assistant for the text content. | | `Recommended` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `value` | string | The actual text content of the message. | `The weather in Paris is rainy and overcast, with temperatures around 57°F` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `incomplete_details` | undefined | On an incomplete message, details about why the message is incomplete. | | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `role` | string | The actual role of the message author as passed in the message. | `assistant`; `bot` | `Conditionally Required` if available and not equal to `assistant`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `tool_calls`: | map | The tool calls generated by the model, such as function calls. | | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `function`: | map | The function call. | | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `arguments` | undefined | The arguments of the function as provided in the LLM response. [1] | `{\"location\": \"Paris\"}` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `name` | string | The name of the function. | `get_weather` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `id` | string | The id of the tool call. | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `type` | enum | The type of the tool. | `function` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[1]:** Models usually return arguments as a JSON string. In this case, it's RECOMMENDED to provide arguments as is without attempting to deserialize them.
+Semantic conventions for individual systems MAY specify a different type for arguments field.
+
+`type` 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.
-| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
-|-------------|------------|----------------------------------------|----------------------------|-------------------|
-| `name` | string | The name of the function to call | `get_link_to_otel_semconv` | `Required` |
-| `arguments` | `AnyValue` | The arguments to pass the the function | `{"semconv": "gen_ai"}` | `Opt-In` |
+| Value | Description | Stability |
+|---|---|---|
+| `function` | Function | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+
+
+
+
-## Tool event
+## Event: `gen_ai.tool.message`
+
+
+
+
+
+
+
-This event describes the output of the tool or function submitted back to the model.
+**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue)
The event name MUST be `gen_ai.tool.message`.
-| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
-|----------------|--------|-----------------------------------------------|---------------------------------|-------------------|
-| `role` | string | The actual role of the message author as passed in the message. | `"tool"`, `"function"` | `Conditionally Required`: if available and if not equal to `tool` |
-| `content` | AnyValue | The contents of the tool message. | `opentelemetry.io` | `Opt-In` |
-| `id` | string | Tool call that this message is responding to. | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Required` |
+This event describes the tool or function response message.
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Recommended` if applicable | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
+
+`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 |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**Body fields:**
-## Choice event
+| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| `content` | undefined | The contents of the tool message. | `rainy, 57°F` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `id` | string | Tool call id that this message is responding to. | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `role` | string | The actual role of the message author as passed in the message. | `tool`; `function` | `Conditionally Required` if available and not equal to `tool`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-This event describes model-generated individual chat response (choice).
-If GenAI model returns multiple choices, each choice SHOULD be recorded as an individual event.
+
+
+
+
-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 (if enabled). If `finish_reason` was not received, it MUST be set to `error`.
+## Event: `gen_ai.choice`
+
+
+
+
+
+
+
+
+**Status:** ![Experimental](https://img.shields.io/badge/-experimental-blue)
The event name MUST be `gen_ai.choice`.
-Choice event body has the following fields:
+This event describes the Gen AI response message.
+
+| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [1] | `openai` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[1]:** The `gen_ai.system` describes a family of GenAI models with specific model identified
+by `gen_ai.request.model` and `gen_ai.response.model` attributes.
+
+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.
+
+For custom model, a custom friendly name SHOULD be used.
+If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
-| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
-|-----------------|----------------------------|-------------------------------------------------|----------------------------------------|-------------------|
-| `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 | `{"content":"The OpenAI semantic conventions are available at opentelemetry.io"}` | `Recommended` |
+`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.
-### `Message` object
+| Value | Description | Stability |
+|---|---|---|
+| `anthropic` | Anthropic | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `az.ai.inference` | Azure AI Inference | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `cohere` | Cohere | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `openai` | OpenAI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `vertex_ai` | Vertex AI | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**Body fields:**
+
+| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
+|---|---|---|---|---|---|
+| `finish_reason` | enum | The reason the model stopped generating tokens. | `stop`; `tool_calls`; `content_filter` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `index` | int | The index of the choice in the list of choices. | `0`; `1` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `message`: | map | GenAI response message. | | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `attachments` | undefined | The list of message attachments. | | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `content` | undefined | The contents of the assistant message. | `The weather in Paris is rainy and overcast, with temperatures around 57°F` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `role` | string | The actual role of the message author as passed in the message. | `assistant`; `bot` | `Conditionally Required` if available and not equal to `assistant`. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `tool_calls`: | map | The tool calls generated by the model, such as function calls. | | `Conditionally Required` if available | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `function`: | map | The function that the model called. | | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `arguments` | undefined | The arguments of the function as provided in the LLM response. [1] | `{\"location\": \"Paris\"}` | `Opt-In` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `name` | string | The name of the function. | `get_weather` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `id` | string | The id of the tool call. | `call_mszuSIzqtI65i1wAUOE8w5H4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `type` | enum | The type of the tool. | `function` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+**[1]:** Models usually return arguments as a JSON string. In this case, it's RECOMMENDED to provide arguments as is without attempting to deserialize them.
+Semantic conventions for individual systems MAY specify a different type for arguments field.
+
+`finish_reason` 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 |
+|---|---|---|
+| `content_filter` | Content Filter | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `error` | Error | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `length` | Length | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `stop` | Stop | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `tool_calls` | Tool Calls | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
+`type` 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 |
+|---|---|---|
+| `function` | Function | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| Body Field | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) |
-|----------------|--------------------------------|-----------------------------------------------|---------------------------------|-------------------|
-| `role` | string | The actual role of the message author as passed in the message. | `"assistant"`, `"bot"` | `Conditionally Required`: if available and if not equal to `assistant` |
-| `content` | `AnyValue` | The contents of the assistant message. | `Spans, events, metrics defined by the GenAI semantic conventions.` | `Opt-In` |
-| `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 |
+
+
+
+
## Custom events
@@ -186,195 +387,238 @@ SHOULD follow `gen_ai.{gen_ai.system}.*` naming pattern for system-specific even
### Chat completion
-This example covers the following scenario:
-
-- user requests 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 `"Follow GenAI semantic conventions available at opentelemetry.io."` message
-
-Span:
+This is an example of telemetry generated for a chat completion call with system and user messages.
+
+```mermaid
+%%{init:
+{
+ "sequence": { "messageAlign": "left", "htmlLabels":true },
+ "themeVariables": { "noteBkgColor" : "green", "noteTextColor": "black", "activationBkgColor": "green", "htmlLabels":true }
+}
+}%%
+sequenceDiagram
+ participant A as Application
+ participant I as Instrumented Client
+ participant M as Model
+ A->>+I: #U+200D
+ I->>M: gen_ai.system.message: You are a helpful bot
gen_ai.user.message: Tell me a joke about OpenTelemetry
+ Note left of I: GenAI Client span
+ I-->M: gen_ai.choice: Why did the developer bring OpenTelemetry to the party? Because it always knows how to trace the fun!
+ I-->>-A: #U+200D
+```
+
+**GenAI Client span:**
| Attribute name | Value |
|---------------------------------|--------------------------------------------|
| Span name | `"chat gpt-4"` |
| `gen_ai.system` | `"openai"` |
| `gen_ai.request.model` | `"gpt-4"` |
-| `gen_ai.request.max_tokens` | `200` |
+| `gen_ai.request.max_output_tokens`| `200` |
| `gen_ai.request.top_p` | `1.0` |
-| `gen_ai.response.id` | `"chatcmpl-9J3uIL87gldCFtiIbyaOvTeYBRA3l"` |
+| `gen_ai.message.id` | `"chatcmpl-9J3uIL87gldCFtiIbyaOvTeYBRA3l"` |
| `gen_ai.response.model` | `"gpt-4-0613"` |
| `gen_ai.usage.output_tokens` | `47` |
| `gen_ai.usage.input_tokens` | `52` |
| `gen_ai.response.finish_reasons`| `["stop"]` |
-Events:
+**Events:**
-1. `gen_ai.system.message`.
+1. `gen_ai.system.message`
| Property | Value |
|---------------------|-------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body | `{"content": "You're a friendly bot that answers questions about OpenTelemetry."}` |
+ | Event body (with content enabled) | `{"content": "You're a helpful bot"}` |
2. `gen_ai.user.message`
| Property | Value |
|---------------------|-------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body | `{"content":"How to instrument GenAI library with OTel?"}` |
+ | Event body (with content enabled) | `{"content":"Tell me a joke about OpenTelemetry"}` |
3. `gen_ai.choice`
| Property | Value |
|---------------------|-------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body (with content enabled) | `{"index":0,"finish_reason":"stop","message":{"content":"Follow GenAI semantic conventions available at opentelemetry.io."}}` |
+ | Event body (with content enabled) | `{"index":0,"finish_reason":"stop","message":{"content":"Why did the developer bring OpenTelemetry to the party? Because it always knows how to trace the fun!"}}` |
| Event body (without content) | `{"index":0,"finish_reason":"stop","message":{}}` |
### Tools
-This example covers the following scenario:
-
-1. Application requests chat completion from OpenAI GPT-4 model and provides a function definition.
-
- - Application provides the following prompt:
- - User message: `How to instrument GenAI library with OTel?`
- - Application defines a tool (a function) names `get_link_to_otel_semconv` with single string argument named `semconv`
-
-2. The model responds with a tool call request which application executes
-3. The application requests chat completion again now with the tool execution result
+This is an example of telemetry generated for a chat completion call with user message and function definition
+that results in a model requesting application to call provided function. Application executes a function and
+requests another completion now with the tool response.
+
+```mermaid
+%%{init:
+{
+ "sequence": { "messageAlign": "left", "htmlLabels":true },
+ "themeVariables": { "noteBkgColor" : "green", "noteTextColor": "black", "activationBkgColor": "green", "htmlLabels":true }
+}
+}%%
+sequenceDiagram
+ participant A as Application
+ participant I as Instrumented Client
+ participant M as Model
+ A->>+I: #U+200D
+ I->>M: gen_ai.user.message: What's the weather in Paris?
+ Note left of I: GenAI Client span 1
+ I-->M: gen_ai.choice: Call to the get_weather tool with Paris as the location argument.
+ I-->>-A: #U+200D
+ A -->> A: parse tool parameters
execute tool
update chat history
+ A->>+I: #U+200D
+ I->>M: gen_ai.user.message: What's the weather in Paris?
gen_ai.assistant.message: get_weather tool call
gen_ai.tool.message: rainy, 57°F
+ Note left of I: GenAI Client span 2
+ I-->M: gen_ai.choice: The weather in Paris is rainy and overcast, with temperatures around 57°F
+ I-->>-A: #U+200D
+```
Here's the telemetry generated for each step in this scenario:
-1. Chat completion resulting in a tool call.
+**GenAI Client span 1:**
- | Attribute name | Value |
- |---------------------|-------------------------------------------------------|
- | Span name | `"chat 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.output_tokens`| `17` |
- | `gen_ai.usage.input_tokens`| `47` |
- | `gen_ai.response.finish_reasons`| `["tool_calls"]` |
+| Attribute name | Value |
+|---------------------|-------------------------------------------------------|
+| Span name | `"chat gpt-4"` |
+| `gen_ai.system` | `"openai"` |
+| `gen_ai.request.model`| `"gpt-4"` |
+| `gen_ai.request.max_output_tokens`| `200` |
+| `gen_ai.request.top_p`| `1.0` |
+| `gen_ai.message.id`| `"chatcmpl-9J3uIL87gldCFtiIbyaOvTeYBRA3l"` |
+| `gen_ai.response.model`| `"gpt-4-0613"` |
+| `gen_ai.usage.output_tokens`| `17` |
+| `gen_ai.usage.input_tokens`| `47` |
+| `gen_ai.response.finish_reasons`| `["tool_calls"]` |
+
+ **Events**:
- Events parented to this span:
+ All the following events are parented to the **GenAI chat span 1**.
- - `gen_ai.user.message` (not reported when capturing content is disabled)
+ 1. `gen_ai.user.message` (not reported when capturing content is disabled)
| Property | Value |
|---------------------|-------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body | `{"content":"How to instrument GenAI library with OTel?"}` |
+ | Event body | `{"content":"What's the weather in Paris?"}` |
- - `gen_ai.choice`
+ 2. `gen_ai.choice`
| Property | Value |
|---------------------|-------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body (with 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 body (without content) | `{"index":0,"finish_reason":"tool_calls","message":{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv"},"type":"function"}]}` |
+ | Event body (with content) | `{"index":0,"finish_reason":"tool_calls","message":{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_weather","arguments":"{\"location\":\"Paris\"}"},"type":"function"}]}` |
+ | Event body (without content) | `{"index":0,"finish_reason":"tool_calls","message":{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_weather"},"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
+**GenAI Client span 2:**
| Attribute name | Value |
|---------------------------------|-------------------------------------------------------|
| Span name | `"chat gpt-4"` |
| `gen_ai.system` | `"openai"` |
| `gen_ai.request.model` | `"gpt-4"` |
- | `gen_ai.request.max_tokens` | `200` |
+ | `gen_ai.request.max_output_tokens` | `200` |
| `gen_ai.request.top_p` | `1.0` |
- | `gen_ai.response.id` | `"chatcmpl-call_VSPygqKTWdrhaFErNvMV18Yl"` |
+ | `gen_ai.message.id` | `"chatcmpl-call_VSPygqKTWdrhaFErNvMV18Yl"` |
| `gen_ai.response.model` | `"gpt-4-0613"` |
| `gen_ai.usage.output_tokens` | `52` |
| `gen_ai.usage.input_tokens` | `47` |
| `gen_ai.response.finish_reasons`| `["stop"]` |
- Events parented to this span:
- (in this example, the event content matches the original messages, but applications may also drop messages or change their content)
+ **Events**:
- - `gen_ai.user.message` (not reported when capturing content is not enabled)
+ All the following events are parented to the **GenAI chat span 2**.
+
+ In this example, the event content matches the original messages, but applications may also drop messages or change their content.
+
+ 1. `gen_ai.user.message`
| Property | Value |
|----------------------------------|------------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body | `{"content":"How to instrument GenAI library with OTel?"}` |
+ | Event body | `{"content":"What's the weather in Paris?"}` |
- - `gen_ai.assistant.message`
+ 2. `gen_ai.assistant.message`
| Property | Value |
|----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body (content enabled) | `{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv","arguments":"{\"semconv\":\"GenAI\"}"},"type":"function"}]}` |
- | Event body (content not enabled) | `{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_link_to_otel_semconv"},"type":"function"}]}` |
+ | Event body (content enabled) | `{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_weather","arguments":"{\"location\":\"Paris\"}"},"type":"function"}]}` |
+ | Event body (content not enabled) | `{"tool_calls":[{"id":"call_VSPygqKTWdrhaFErNvMV18Yl","function":{"name":"get_weather"},"type":"function"}]}` |
- - `gen_ai.tool.message`
+ 3. `gen_ai.tool.message`
| Property | Value |
|----------------------------------|------------------------------------------------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body (content enabled) | `{"content":"opentelemetry.io/semconv/gen-ai","id":"call_VSPygqKTWdrhaFErNvMV18Yl"}` |
+ | Event body (content enabled) | `{"content":"rainy, 57°F","id":"call_VSPygqKTWdrhaFErNvMV18Yl"}` |
| Event body (content not enabled) | `{"id":"call_VSPygqKTWdrhaFErNvMV18Yl"}` |
- - `gen_ai.choice`
+ 4. `gen_ai.choice`
| Property | Value |
|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body (content enabled) | `{"index":0,"finish_reason":"stop","message":{"content":"Follow OTel semconv available at opentelemetry.io/semconv/gen-ai"}}` |
+ | Event body (content enabled) | `{"index":0,"finish_reason":"stop","message":{"content":"The weather in Paris is rainy and overcast, with temperatures around 57°F"}}` |
| Event body (content not enabled) | `{"index":0,"finish_reason":"stop","message":{}}` |
### 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:
+This example covers the scenario when user requests model to generate two completions for the same prompt :
+
+```mermaid
+%%{init:
+{
+ "sequence": { "messageAlign": "left", "htmlLabels":true },
+ "themeVariables": { "noteBkgColor" : "green", "noteTextColor": "black", "activationBkgColor": "green", "htmlLabels":true }
+}
+}%%
+sequenceDiagram
+ participant A as Application
+ participant I as Instrumented Client
+ participant M as Model
+ A->>+I: #U+200D
+ I->>M: gen_ai.system.message - "You are a helpful bot"
gen_ai.user.message - "Tell me a joke about OpenTelemetry"
+ Note left of I: GenAI Client span
+ I-->M: gen_ai.choice - Why did the developer bring OpenTelemetry to the party? Because it always knows how to trace the fun!
gen_ai.choice - Why did OpenTelemetry get promoted? It had great span of control!
+ I-->>-A: #U+200D
+```
+
+**GenAI Client Span**:
| Attribute name | Value |
|---------------------|--------------------------------------------|
| Span name | `"chat gpt-4"` |
| `gen_ai.system` | `"openai"` |
| `gen_ai.request.model`| `"gpt-4"` |
-| `gen_ai.request.max_tokens`| `200` |
+| `gen_ai.request.max_output_tokens`| `200` |
| `gen_ai.request.top_p`| `1.0` |
-| `gen_ai.response.id`| `"chatcmpl-9J3uIL87gldCFtiIbyaOvTeYBRA3l"` |
+| `gen_ai.message.id`| `"chatcmpl-9J3uIL87gldCFtiIbyaOvTeYBRA3l"` |
| `gen_ai.response.model`| `"gpt-4-0613"` |
| `gen_ai.usage.output_tokens`| `77` |
| `gen_ai.usage.input_tokens`| `52` |
-| `gen_ai.response.finish_reasons`| `["stop"]` |
+| `gen_ai.response.finish_reasons`| `["stop", "stop"]` |
+
+**Events**:
-Events:
+All events are parented to the GenAI chat span above.
1. `gen_ai.system.message`: the same as in the [Chat Completion](#chat-completion) example
-2. `gen_ai.user.message`: the same as in the previous example
+2. `gen_ai.user.message`: the same as in the [Chat Completion](#chat-completion) example
3. `gen_ai.choice`
| Property | Value |
|------------------------------|-------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body (content enabled) | `{"index":0,"finish_reason":"stop","message":{"content":"Follow GenAI semantic conventions available at opentelemetry.io."}}` |
+ | Event body (content enabled) | `{"index":0,"finish_reason":"stop","message":{"content":"Why did the developer bring OpenTelemetry to the party? Because it always knows how to trace the fun!"}}` |
4. `gen_ai.choice`
| Property | Value |
|------------------------------|-------------------------------------------------------|
| `gen_ai.system` | `"openai"` |
- | Event body (content enabled) | `{"index":1,"finish_reason":"stop","message":{"content":"Use OpenAI instrumentation library."}}` |
+ | Event body (content enabled) | `{"index":1,"finish_reason":"stop","message":{"content":"Why did OpenTelemetry get promoted? It had great span of control!"}}` |
[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
diff --git a/docs/gen-ai/gen-ai-metrics.md b/docs/gen-ai/gen-ai-metrics.md
index c8cba89124..23d962f98a 100644
--- a/docs/gen-ai/gen-ai-metrics.md
+++ b/docs/gen-ai/gen-ai-metrics.md
@@ -61,7 +61,7 @@ This metric SHOULD be specified with [ExplicitBucketBoundaries] of [1, 4, 16, 64
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.token.type`](/docs/attributes-registry/gen-ai.md) | string | The type of token being counted. | `input`; `output` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
@@ -90,8 +90,30 @@ If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[5]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[6]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[7]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[8]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[9]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
`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 |
@@ -133,7 +155,7 @@ This metric SHOULD be specified with [ExplicitBucketBoundaries] of [0.01, 0.02,
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
@@ -172,8 +194,30 @@ Instrumentations SHOULD document the list of errors they report.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[6]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[7]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[8]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[9]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[10]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
`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 |
@@ -215,7 +259,7 @@ This metric SHOULD be specified with [ExplicitBucketBoundaries] of
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
@@ -254,8 +298,30 @@ Instrumentations SHOULD document the list of errors they report.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [10] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[6]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[7]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[8]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[9]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[10]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
`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 |
@@ -297,7 +363,7 @@ This metric SHOULD be specified with [ExplicitBucketBoundaries] of
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [3] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
@@ -325,8 +391,30 @@ If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[5]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[6]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[7]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[8]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[9]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
`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 |
@@ -367,7 +455,7 @@ This metric SHOULD be specified with [ExplicitBucketBoundaries] of
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [3] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
@@ -395,8 +483,30 @@ If none of these options apply, the `gen_ai.system` SHOULD be set to `_OTHER`.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [9] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[5]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[6]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[7]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[8]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[9]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
`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 |
diff --git a/docs/gen-ai/gen-ai-spans.md b/docs/gen-ai/gen-ai-spans.md
index 56db7ab898..41d50dfeba 100644
--- a/docs/gen-ai/gen-ai-spans.md
+++ b/docs/gen-ai/gen-ai-spans.md
@@ -13,6 +13,7 @@ linkTitle: Generative AI traces
- [Name](#name)
- [GenAI attributes](#genai-attributes)
- [Capturing inputs and outputs](#capturing-inputs-and-outputs)
+- [Composite Generative AI scenarios](#composite-generative-ai-scenarios)
@@ -39,24 +40,30 @@ These attributes track input data and metadata for a request to an GenAI model.
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.system`](/docs/attributes-registry/gen-ai.md) | string | The Generative AI product as identified by the client or server instrumentation. [2] | `openai` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [4] | `gpt-4` | `Conditionally Required` If available. | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [5] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.agent.description`](/docs/attributes-registry/gen-ai.md) | string | Free-form description of the GenAI agent provided by the application. | `Helps with math problems`; `Generates fiction stories` | `Recommended` [6] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.agent.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the GenAI agent. | `asst_5j66UpCpwteGg4YSxUnt7lPY` | `Recommended` [7] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.agent.name`](/docs/attributes-registry/gen-ai.md) | string | Human-readable name of the GenAI agent provided by the application. | `Math Tutor`; `Fiction Writer` | `Recommended` [8] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.message.id`](/docs/attributes-registry/gen-ai.md) | string | Identifies message sent to or received from Generative AI model or agent. [9] | `msg_sLMd7grQfjFXgu5ZeHCXmBr7`; `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.frequency_penalty`](/docs/attributes-registry/gen-ai.md) | double | The frequency penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`gen_ai.request.max_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of tokens the model generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of prompt tokens the model can use. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of completion tokens the model generates in response. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.presence_penalty`](/docs/attributes-registry/gen-ai.md) | double | The presence penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.stop_sequences`](/docs/attributes-registry/gen-ai.md) | string[] | List of sequences that the model will use to stop generating further tokens. | `["forest", "lived"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the GenAI request. | `0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.top_k`](/docs/attributes-registry/gen-ai.md) | double | The top_k sampling setting for the GenAI request. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the GenAI request. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.response.finish_reasons`](/docs/attributes-registry/gen-ai.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]`; `["stop", "length"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`gen_ai.response.id`](/docs/attributes-registry/gen-ai.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/gen-ai.md) | string | The name of the model that generated the response. [6] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. [10] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread. | `thread_ggguJ0iZXRPjUnCy9vT9Fdvs` | `Recommended` [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.thread.run.id`](/docs/attributes-registry/gen-ai.md) | string | The unique identifier of the thread run. | `run_ep8IxBKdM06Mv338KNyo6EKP` | `Recommended` [12] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.usage.input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the GenAI input (prompt). | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.usage.output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the GenAI response (completion). | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [7] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [13] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [14] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
**[1]:** If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value.
@@ -78,9 +85,51 @@ Instrumentations SHOULD document the list of errors they report.
**[5]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
-**[6]:** If available. The name of the GenAI model that provided the response. If the model is supplied by a vendor, then the value must be the exact name of the model actually used. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+**[6]:** If available.
-**[7]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+Agent name is usually available only on the agent-related operations
+such as `create_agent`.
+
+**[7]:** If available.
+
+`gen_ai.agent.id` is usually available on the spans that describe operations
+performed on the agent such as `create_agent` or `process_thread_run`.
+
+Instrumentations of the low level GenAI inference operations such as
+`chat` or `text_completion` done by the lower-level clients usually
+don't have agent id available. If it's available, it SHOULD be set.
+
+**[8]:** If available.
+
+Agent name is usually available only on the agent-related operations
+such as `create_agent`.
+
+**[9]:** For inference operations such as `chat` or `text_completion`, it SHOULD be the completion identifier returned by the GenAI system and may not be unique if multiple choices are returned.
+If message history is managed by the application, agent, or framework, it SHOULD match the identifier used by the message history management system.
+
+**[10]:** If available. The name of the GenAI model that provided the response. If the model is supplied by a vendor, then the value must be the exact name of the model actually used. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+
+**[11]:** If available.
+
+`gen_ai.thread.id` is usually available on the spans that describe operations
+performed on the thread such as `create_thread` or `process_thread_run`.
+
+Instrumentations of the low level GenAI inference operations such as
+`chat` or `text_completion` done by the lower-level clients usually
+don't have thread id available. If it's available, it SHOULD be set.
+
+**[12]:** If available.
+
+`gen_ai.thread.run.id` is usually available on the spans that describe
+thread runs such as `process_thread_run` or `start_thread_run`.
+
+Instrumentations of the low level GenAI inference operations such as
+`chat` or `text_completion` done by the lower-level clients usually
+don't have thread run id available. If it's available, it SHOULD be set.
+
+**[13]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[14]:** if available and if operation involves remote calls against GenAI service.
`error.type` 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.
@@ -93,8 +142,30 @@ Instrumentations SHOULD document the list of errors they report.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [16] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [17] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [18] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [19] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[15]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[16]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[17]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[18]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[19]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
`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 |
@@ -114,4 +185,19 @@ Instrumentations SHOULD document the list of errors they report.
User inputs and model responses may be recorded as events parented to GenAI operation span. See [Semantic Conventions for GenAI events](./gen-ai-events.md) for the details.
+## Composite Generative AI scenarios
+
+Generative AI applications use patterns like
+[RAG](https://wikipedia.org/wiki/Retrieval-augmented_generation) that involve
+multiple operations such as GenAI or database calls. They also may need to store
+conversation history which also involves communication with multiple services.
+
+These patterns could be implemented in the application code, client framework
+such as [LangGraph](https://github.com/langchain-ai/langgraph) or on the managed
+service such as [OpenAI Assistants](https://platform.openai.com/docs/assistants),
+[Azure AI Agents](TODO link), or [Amazon Bedrock Agents](https://aws.amazon.com/bedrock/agents/).
+
+Semantic conventions for agents and local composite scenarios are covered in the [GenAI agent spans](./gen-ai-agent-spans.md)
+document.
+
[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
diff --git a/docs/gen-ai/images/another_run_on_the_thread.png b/docs/gen-ai/images/another_run_on_the_thread.png
new file mode 100644
index 0000000000..2e83ab6909
Binary files /dev/null and b/docs/gen-ai/images/another_run_on_the_thread.png differ
diff --git a/docs/gen-ai/images/create_agent_rag.png b/docs/gen-ai/images/create_agent_rag.png
new file mode 100644
index 0000000000..bc9c871f5c
Binary files /dev/null and b/docs/gen-ai/images/create_agent_rag.png differ
diff --git a/docs/gen-ai/images/create_and_run_thread.png b/docs/gen-ai/images/create_and_run_thread.png
new file mode 100644
index 0000000000..63efe58c0b
Binary files /dev/null and b/docs/gen-ai/images/create_and_run_thread.png differ
diff --git a/docs/gen-ai/images/run_with_tool_calls_and_streaming.png b/docs/gen-ai/images/run_with_tool_calls_and_streaming.png
new file mode 100644
index 0000000000..8ff2ce3d93
Binary files /dev/null and b/docs/gen-ai/images/run_with_tool_calls_and_streaming.png differ
diff --git a/docs/gen-ai/images/run_with_tool_calls_without_streaming.png b/docs/gen-ai/images/run_with_tool_calls_without_streaming.png
new file mode 100644
index 0000000000..5db8b41347
Binary files /dev/null and b/docs/gen-ai/images/run_with_tool_calls_without_streaming.png differ
diff --git a/docs/gen-ai/openai.md b/docs/gen-ai/openai.md
index 5acce4fb88..3ff729637f 100644
--- a/docs/gen-ai/openai.md
+++ b/docs/gen-ai/openai.md
@@ -36,26 +36,27 @@ attributes and ones specific the OpenAI.
| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
-| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.operation.name`](/docs/attributes-registry/gen-ai.md) | string | The name of the operation being performed. [1] | `chat`; `text_completion`; `create_agent` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the GenAI model a request is being made to. [2] | `gpt-4` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if the operation ended in an error | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
-| [`gen_ai.openai.request.response_format`](/docs/attributes-registry/gen-ai.md) | string | The response format that is requested. | `json` | `Conditionally Required` if the request includes a response_format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.openai.request.seed`](/docs/attributes-registry/gen-ai.md) | int | Requests with same seed value more likely to return same result. | `100` | `Conditionally Required` if the request includes a seed | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.openai.request.service_tier`](/docs/attributes-registry/gen-ai.md) | string | The service tier requested. May be a specific tier, detault, or auto. | `auto`; `default` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.openai.response.service_tier`](/docs/attributes-registry/gen-ai.md) | string | The service tier used for the response. | `scale`; `detault` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.response_format`](/docs/attributes-registry/gen-ai.md) | string | The response format that is requested. | `text`; `json_object`; `json_schema` | `Conditionally Required` if the request includes a response_format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`server.port`](/docs/attributes-registry/server.md) | int | GenAI server port. [6] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`gen_ai.message.id`](/docs/attributes-registry/gen-ai.md) | string | Identifies message sent to or received from Generative AI model or agent. [7] | `msg_sLMd7grQfjFXgu5ZeHCXmBr7`; `chatcmpl-123` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.frequency_penalty`](/docs/attributes-registry/gen-ai.md) | double | The frequency penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`gen_ai.request.max_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of tokens the model generates for a request. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of prompt tokens the model can use. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.request.max_output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The maximum number of completion tokens the model generates in response. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.presence_penalty`](/docs/attributes-registry/gen-ai.md) | double | The presence penalty setting for the GenAI request. | `0.1` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.stop_sequences`](/docs/attributes-registry/gen-ai.md) | string[] | List of sequences that the model will use to stop generating further tokens. | `["forest", "lived"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.temperature`](/docs/attributes-registry/gen-ai.md) | double | The temperature setting for the GenAI request. | `0.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.request.top_p`](/docs/attributes-registry/gen-ai.md) | double | The top_p sampling setting for the GenAI request. | `1.0` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.response.finish_reasons`](/docs/attributes-registry/gen-ai.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]`; `["stop", "length"]` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`gen_ai.response.id`](/docs/attributes-registry/gen-ai.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/gen-ai.md) | string | The name of the model that generated the response. [7] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| [`gen_ai.response.model`](/docs/attributes-registry/gen-ai.md) | string | The name of the model that generated the response. [8] | `gpt-4-0613` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.usage.input_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the prompt sent to OpenAI. | `100` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`gen_ai.usage.output_tokens`](/docs/attributes-registry/gen-ai.md) | int | The number of tokens used in the completions from OpenAI. | `180` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [8] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+| [`server.address`](/docs/attributes-registry/server.md) | string | GenAI server address. [9] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` [10] | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
**[1]:** If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic conventions for specific GenAI system and use system-specific name in the instrumentation. If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value.
@@ -71,23 +72,20 @@ Instrumentations SHOULD document the list of errors they report.
**[6]:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
-**[7]:** If available. The name of the GenAI model that provided the response. If the model is supplied by a vendor, then the value must be the exact name of the model actually used. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
+**[7]:** For inference operations such as `chat` or `text_completion`, it SHOULD be the completion identifier returned by the GenAI system and may not be unique if multiple choices are returned.
+If message history is managed by the application, agent, or framework, it SHOULD match the identifier used by the message history management system.
-**[8]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+**[8]:** If available. The name of the GenAI model that provided the response. If the model is supplied by a vendor, then the value must be the exact name of the model actually used. If the model is a fine-tuned custom model, the value should have a more specific name than the base model that's been fine-tuned.
-`error.type` 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.
+**[9]:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
-| Value | Description | Stability |
-|---|---|---|
-| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
+**[10]:** if available and if operation involves remote calls against GenAI service.
-`gen_ai.openai.request.response_format` 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.
+`error.type` 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 |
|---|---|---|
-| `json_object` | JSON object response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `json_schema` | JSON schema response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
-| `text` | Text response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
`gen_ai.openai.request.service_tier` 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.
@@ -101,8 +99,38 @@ Instrumentations SHOULD document the list of errors they report.
| Value | Description | Stability |
|---|---|---|
| `chat` | Chat completion operation such as [OpenAI Chat API](https://platform.openai.com/docs/api-reference/chat) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_agent` | Create GenAI agent | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_message` | Create a message in a thread [11] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `create_thread` | Create GenAI thread | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `execute_tool` | Execute a tool [12] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `process_thread_run` | Create and process a thread run on the agent [13] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `start_thread_run` | Create thread run [14] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `submit_tool_outputs` | Submit tool calls results to a run [15] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| `text_completion` | Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions) | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+**[11]:** This operation SHOULD be used when message creation involves remote call to store this message, but does not result in model generating response. It SHOULD NOT be reported along with `chat`, `text_completion` or other inference operations.
+
+**[12]:** This operation describes the tool execution which usually is a client operation performed by the application code.
+Instrumentations SHOULD record this operation when possible - for example, when they provide convenience methods for executing custom tools or provide built-in tools executed on the client side.
+
+**[13]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+The instrumented operation SHOULD cover full duration of the run including time awaiting the final completion. It SHOULD be reported for streaming runs and for operations that involve polling the run status.
+
+**[14]:** The run may consist of multiple steps such as calls to model or tool calls which may be executed on the client side by the application or GenAI client framework or remotely on the GenAI agent.
+Unlike `process_thread_run` this operation covers the creation of the thread run and does not include time awaiting the completion of the run.
+Instrumentations SHOULD report `process_thread_run` operation instead of `create_thread_run` whenever it is possible.
+
+**[15]:** This operation SHOULD be used when instrumentation can determine that application is submitting the tool call output to the model, for example, when this operation is reported in the context of agent thread run.
+When application is submitting the tool call output with the generic GenAI call such as `chat` or `text_completion`, the instrumentation SHOULD use the corresponding operation name since it cannot reliably determine the intent behind the generic GenAI call.
+
+`gen_ai.request.response_format` 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 |
+|---|---|---|
+| `json_object` | JSON object response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `json_schema` | JSON schema response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+| `text` | Text response format | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
+
diff --git a/model/gen-ai/deprecated/registry-deprecated.yaml b/model/gen-ai/deprecated/registry-deprecated.yaml
index 2115482f36..f61e886a12 100644
--- a/model/gen-ai/deprecated/registry-deprecated.yaml
+++ b/model/gen-ai/deprecated/registry-deprecated.yaml
@@ -28,3 +28,33 @@ groups:
deprecated: "Removed, no replacement at this time."
brief: "Deprecated, use Event API to report completions contents."
examples: ["[{'role': 'assistant', 'content': 'The capital of France is Paris.'}]"]
+ - id: gen_ai.request.max_tokens
+ stability: experimental
+ type: int
+ brief: "Deprecated, use `gen_ai.request.max_tokens` instead."
+ deprecated: "Replaced by `gen_ai.request.max_completion_tokens` attribute."
+ examples: [42]
+ - id: gen_ai.openai.request.response_format
+ stability: experimental
+ type:
+ members:
+ - id: text
+ value: "text"
+ brief: 'Text response format'
+ stability: experimental
+ - id: json_object
+ value: "json_object"
+ brief: 'JSON object response format'
+ stability: experimental
+ - id: json_schema
+ value: "json_schema"
+ brief: 'JSON schema response format'
+ stability: experimental
+ brief: "Deprecated, use `gen_ai.request.response_format` instead."
+ deprecated: "Replaced by `gen_ai.request.response_format` attribute."
+ - id: gen_ai.response.id
+ stability: experimental
+ type: string
+ brief: "Deprecated, use `gen_ai.message.id` instead."
+ deprecated: "Replaced by `gen_ai.message.id` attribute."
+ examples: ['chatcmpl-123']
diff --git a/model/gen-ai/events.yaml b/model/gen-ai/events.yaml
index 72a4e692f0..2c4244cb30 100644
--- a/model/gen-ai/events.yaml
+++ b/model/gen-ai/events.yaml
@@ -7,13 +7,49 @@ groups:
attributes:
- ref: gen_ai.system
+ - id: gen_ai.message.event.attributes
+ type: attribute_group
+ stability: experimental
+ brief: >
+ Describes Gen AI message event attributes.
+ extends: gen_ai.common.event.attributes
+ attributes:
+ - ref: gen_ai.thread.id
+ requirement_level:
+ recommended: if applicable
+ - ref: gen_ai.thread.run.id
+ requirement_level:
+ recommended: if applicable
+ - ref: gen_ai.agent.id
+ requirement_level:
+ recommended: if applicable
+
- id: gen_ai.system.message
name: gen_ai.system.message
type: event
stability: experimental
brief: >
This event describes the instructions passed to the GenAI system inside the prompt.
- extends: gen_ai.common.event.attributes
+ extends: gen_ai.message.event.attributes
+ body:
+ id: gen_ai.system.message
+ requirement_level: opt_in
+ type: map
+ fields:
+ - id: content
+ type: undefined # usually a string
+ stability: experimental
+ brief: The contents of the system message.
+ examples: ["You're a helpful bot"]
+ requirement_level: opt_in
+ - id: role
+ type: string
+ stability: experimental
+ brief: >
+ The actual role of the message author as passed in the message.
+ examples: ["system", "agent"]
+ requirement_level:
+ conditionally_required: if available and not equal to `system`.`
- id: gen_ai.user.message
name: gen_ai.user.message
@@ -21,7 +57,50 @@ groups:
stability: experimental
brief: >
This event describes the prompt message specified by the user.
- extends: gen_ai.common.event.attributes
+ extends: gen_ai.message.event.attributes
+ body:
+ id: gen_ai.user.message
+ requirement_level: opt_in
+ type: map
+ fields:
+ - id: content
+ type: undefined
+ stability: experimental
+ brief: >
+ The contents of the user message.
+ examples: ["What's the weather in Paris?"]
+ requirement_level: opt_in
+ - id: role
+ type: string
+ stability: experimental
+ brief: >
+ The actual role of the message author as passed in the message.
+ examples: ["user", "customer"]
+ requirement_level:
+ conditionally_required: if available and not equal to `user`.
+ - id: attachments
+ stability: experimental
+ brief: >
+ The list of message attachments to be used by tools.
+ requirement_level:
+ recommended: if available
+ type: map # TODO map[]
+ fields:
+ - id: id
+ type: string
+ stability: experimental
+ brief: The id of the attachment.
+ examples: ["file_mszuSIzqtI65i1wAUOE8w5H4"]
+ requirement_level:
+ recommended: if available
+ - id: tools
+ stability: experimental
+ brief: The types of the tools the attachment is provided for
+ requirement_level:
+ recommended: if available
+ type: string[]
+ examples:
+ - ["file_search"]
- id: gen_ai.assistant.message
name: gen_ai.assistant.message
@@ -29,7 +108,114 @@ groups:
stability: experimental
brief: >
This event describes the assistant message passed to GenAI system or received from it.
- extends: gen_ai.common.event.attributes
+ extends: gen_ai.message.event.attributes
+ attributes:
+ - ref: gen_ai.message.status
+ brief: >
+ The status of the message at the time event is reported.
+ requirement_level:
+ recommended: if applicable
+ - ref: gen_ai.message.id
+ requirement_level:
+ recommended: if applicable
+ body:
+ id: gen_ai.assistant.message
+ requirement_level: opt_in
+ type: map
+ fields:
+ - id: content
+ stability: experimental
+ brief: The contents of the assistant message.
+ requirement_level: opt_in
+ type: map
+ fields:
+ - id: text
+ stability: experimental
+ brief: The text content of the message.
+ requirement_level:
+ recommended: if available
+ type: map
+ fields:
+ - id: value
+ stability: experimental
+ brief: The actual text content of the message.
+ requirement_level: opt_in
+ type: string
+ examples: ["The weather in Paris is rainy and overcast, with temperatures around 57°F"]
+ - id: annotations
+ stability: experimental
+ brief: Annotations returned by the assistant for the text content.
+ requirement_level:
+ recommended: if available
+ type: undefined
+ - id: role
+ type: string
+ stability: experimental
+ brief: >
+ The actual role of the message author as passed in the message.
+ examples: ["assistant", "bot"]
+ requirement_level:
+ conditionally_required: if available and not equal to `assistant`.
+ - id: incomplete_details
+ type: undefined
+ stability: experimental
+ brief: >
+ On an incomplete message, details about why the message is incomplete.
+ requirement_level:
+ conditionally_required: if available
+ - id: tool_calls
+ type: map # TODO: it's an array
+ stability: experimental
+ brief: >
+ The tool calls generated by the model, such as function calls.
+ requirement_level:
+ conditionally_required: if available
+ fields:
+ - id: id
+ type: string
+ stability: experimental
+ brief: >
+ The id of the tool call.
+ examples: ["call_mszuSIzqtI65i1wAUOE8w5H4"]
+ requirement_level: required
+ - id: type
+ type: enum
+ members:
+ - id: function
+ value: 'function'
+ brief: Function
+ stability: experimental
+ brief: >
+ The type of the tool.
+ examples: ["function"]
+ requirement_level: required
+ - id: function
+ type: map
+ stability: experimental
+ brief: >
+ The function call.
+ requirement_level: required
+ fields:
+ - id: name
+ type: string
+ stability: experimental
+ brief: >
+ The name of the function.
+ examples: ["get_weather"]
+ requirement_level: required
+ - id: arguments
+ type: undefined
+ stability: experimental
+ brief: >
+ The arguments of the function as provided in the LLM response.
+ note: >
+ Models usually return arguments as a JSON string. In this case, it's
+ RECOMMENDED to provide arguments as is without attempting to deserialize them.
+
+ Semantic conventions for individual systems MAY specify a different type for
+ arguments field.
+ examples: ['{\"location\": \"Paris\"}']
+ requirement_level: opt_in
- id: gen_ai.tool.message
name: gen_ai.tool.message
@@ -37,7 +223,34 @@ groups:
stability: experimental
brief: >
This event describes the tool or function response message.
- extends: gen_ai.common.event.attributes
+ extends: gen_ai.message.event.attributes
+ body:
+ id: gen_ai.tool.message
+ requirement_level: opt_in
+ type: map
+ fields:
+ - id: content
+ type: undefined
+ stability: experimental
+ brief: >
+ The contents of the tool message.
+ examples: ["rainy, 57°F"]
+ requirement_level: opt_in
+ - id: role
+ type: string
+ stability: experimental
+ brief: >
+ The actual role of the message author as passed in the message.
+ examples: ["tool", "function"]
+ requirement_level:
+ conditionally_required: if available and not equal to `tool`.
+ - id: id
+ type: string
+ stability: experimental
+ brief: >
+ Tool call id that this message is responding to.
+ examples: ["call_mszuSIzqtI65i1wAUOE8w5H4"]
+ requirement_level: required
- id: gen_ai.choice
name: gen_ai.choice
@@ -46,3 +259,127 @@ groups:
brief: >
This event describes the Gen AI response message.
extends: gen_ai.common.event.attributes
+ body:
+ id: gen_ai.choice
+ requirement_level: opt_in
+ type: map
+ note: >
+ If GenAI model returns multiple choices, each choice SHOULD be recorded as an individual event.
+ 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 (if enabled).
+ If `finish_reason` was not received, it MUST be set to `error`.
+ fields:
+ - id: index
+ type: int
+ stability: experimental
+ brief: >
+ The index of the choice in the list of choices.
+ examples: [0, 1]
+ requirement_level: required
+ - id: finish_reason
+ type: enum
+ members:
+ - id: stop
+ value: 'stop'
+ brief: Stop
+ - id: tool_calls
+ value: 'tool_calls'
+ brief: Tool Calls
+ - id: content_filter
+ value: 'content_filter'
+ brief: Content Filter
+ - id: length
+ value: 'length'
+ brief: Length
+ - id: error
+ value: 'error'
+ brief: Error
+ stability: experimental
+ brief: >
+ The reason the model stopped generating tokens.
+ requirement_level: required
+ - id: message
+ type: map
+ stability: experimental
+ brief: >
+ GenAI response message.
+ requirement_level: recommended
+ fields:
+ - id: content
+ type: undefined
+ stability: experimental
+ brief: >
+ The contents of the assistant message.
+ examples: ["The weather in Paris is rainy and overcast, with temperatures around 57°F"]
+ requirement_level: opt_in
+ - id: role
+ type: string
+ stability: experimental
+ brief: >
+ The actual role of the message author as passed in the message.
+ examples: ["assistant", "bot"]
+ requirement_level:
+ conditionally_required: if available and not equal to `assistant`.
+ - id: attachments
+ type: undefined # TODO undefined[]
+ stability: experimental
+ brief: >
+ The list of message attachments.
+ requirement_level:
+ conditionally_required: if available
+ - id: tool_calls
+ type: map # TODO: it's an array
+ stability: experimental
+ brief: >
+ The tool calls generated by the model, such as function calls.
+ requirement_level:
+ conditionally_required: if available
+ fields:
+ - id: id
+ type: string
+ stability: experimental
+ brief: >
+ The id of the tool call.
+ examples: ["call_mszuSIzqtI65i1wAUOE8w5H4"]
+ requirement_level: required
+ - id: type
+ type: enum
+ members:
+ - id: function
+ value: 'function'
+ brief: Function
+ stability: experimental
+ brief: >
+ The type of the tool.
+ requirement_level: required
+ - id: function
+ type: map
+ stability: experimental
+ brief: >
+ The function that the model called.
+ requirement_level: required
+ fields:
+ - id: name
+ type: string
+ stability: experimental
+ brief: >
+ The name of the function.
+ examples: ["get_weather"]
+ requirement_level: required
+ - id: arguments
+ type: undefined
+ stability: experimental
+ brief: >
+ The arguments of the function as provided in the LLM response.
+ note: >
+ Models usually return arguments as a JSON string. In this case, it's
+ RECOMMENDED to provide arguments as is without attempting to deserialize them.
+
+ Semantic conventions for individual systems MAY specify a different type for
+ arguments field.
+ examples: ['{\"location\": \"Paris\"}']
+ requirement_level: opt_in
+
+ # TODO tools and tool resources events
diff --git a/model/gen-ai/registry.yaml b/model/gen-ai/registry.yaml
index a1e86b75fc..902d9eeab7 100644
--- a/model/gen-ai/registry.yaml
+++ b/model/gen-ai/registry.yaml
@@ -1,6 +1,7 @@
groups:
- id: registry.gen_ai
type: attribute_group
+ stability: experimental
display_name: GenAI Attributes
brief: >
This document defines the attributes used to describe telemetry in the context of Generative Artificial Intelligence (GenAI) Models requests and responses.
@@ -46,10 +47,15 @@ groups:
type: string
brief: The name of the GenAI model a request is being made to.
examples: 'gpt-4'
- - id: gen_ai.request.max_tokens
+ - id: gen_ai.request.max_output_tokens
stability: experimental
type: int
- brief: The maximum number of tokens the model generates for a request.
+ brief: The maximum number of completion tokens the model generates in response.
+ examples: [100]
+ - id: gen_ai.request.max_input_tokens
+ stability: experimental
+ type: int
+ brief: The maximum number of prompt tokens the model can use.
examples: [100]
- id: gen_ai.request.temperature
stability: experimental
@@ -82,11 +88,6 @@ groups:
type: double
brief: The presence penalty setting for the GenAI request.
examples: [0.1]
- - id: gen_ai.response.id
- stability: experimental
- type: string
- brief: The unique identifier for the completion.
- examples: ['chatcmpl-123']
- id: gen_ai.response.model
stability: experimental
type: string
@@ -135,23 +136,181 @@ groups:
value: "text_completion"
brief: 'Text completions operation such as [OpenAI Completions API (Legacy)](https://platform.openai.com/docs/api-reference/completions)'
stability: experimental
+ - id: create_agent
+ value: "create_agent"
+ brief: 'Create GenAI agent'
+ stability: experimental
+ - id: create_thread
+ value: "create_thread"
+ brief: 'Create GenAI thread'
+ stability: experimental
+ - id: start_thread_run
+ value: "start_thread_run"
+ brief: 'Create thread run'
+ note: >
+ The run may consist of multiple steps such as calls to model or
+ tool calls which may be executed on the client side by the
+ application or GenAI client framework or remotely on the GenAI agent.
+
+ Unlike `process_thread_run` this operation covers the creation of the thread run
+ and does not include time awaiting the completion of the run.
+
+ Instrumentations SHOULD report `process_thread_run` operation instead
+ of `create_thread_run` whenever it is possible.
+ stability: experimental
+ - id: process_thread_run
+ value: "process_thread_run"
+ brief: 'Create and process a thread run on the agent'
+ note: >
+ The run may consist of multiple steps such as calls to model or
+ tool calls which may be executed on the client side by the
+ application or GenAI client framework or remotely on the GenAI agent.
+
+ The instrumented operation SHOULD cover full duration of the run
+ including time awaiting the final completion. It SHOULD be reported
+ for streaming runs and for operations that involve polling the
+ run status.
+ stability: experimental
+ - id: submit_tool_outputs
+ value: "submit_tool_outputs"
+ brief: 'Submit tool calls results to a run'
+ note: >
+ This operation SHOULD be used when instrumentation can determine that
+ application is submitting the tool call output to the model, for example, when
+ this operation is reported in the context of agent thread run.
+
+ When application is submitting the tool call output with the generic GenAI call
+ such as `chat` or `text_completion`, the instrumentation SHOULD use the
+ corresponding operation name since it cannot reliably determine the
+ intent behind the generic GenAI call.
+ stability: experimental
+ - id: execute_tool
+ value: "execute_tool"
+ brief: 'Execute a tool'
+ stability: experimental
+ note: >
+ This operation describes the tool execution which usually is a client
+ operation performed by the application code.
+
+ Instrumentations SHOULD record this operation when possible - for example,
+ when they provide convenience methods for executing custom tools or
+ provide built-in tools executed on the client side.
+ - id: create_message
+ value: "create_message"
+ brief: 'Create a message in a thread'
+ stability: experimental
+ note: >
+ This operation SHOULD be used when message creation involves remote call
+ to store this message, but does not result in model generating response.
+ It SHOULD NOT be reported along with `chat`, `text_completion` or other
+ inference operations.
brief: The name of the operation being performed.
note: >
If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to document it in the semantic
conventions for specific GenAI system and use system-specific name in the instrumentation.
If a different name is not documented, instrumentation libraries SHOULD use applicable predefined value.
- - id: registry.gen_ai.openai
- type: attribute_group
- display_name: OpenAI Attributes
- brief: >
- Thie group defines attributes for OpenAI.
- attributes:
- - id: gen_ai.openai.request.seed
+ - id: gen_ai.agent.id # alternatives: assistant (openai)
stability: experimental
- type: int
- brief: Requests with same seed value more likely to return same result.
- examples: [100]
- - id: gen_ai.openai.request.response_format
+ type: string
+ brief: The unique identifier of the GenAI agent.
+ examples: ['asst_5j66UpCpwteGg4YSxUnt7lPY']
+ - id: gen_ai.agent.name
+ stability: experimental
+ type: string
+ brief: Human-readable name of the GenAI agent provided by the application.
+ examples: ["Math Tutor", "Fiction Writer"]
+ - id: gen_ai.agent.description
+ stability: experimental
+ type: string
+ brief: Free-form description of the GenAI agent provided by the application.
+ examples: ["Helps with math problems", "Generates fiction stories"]
+ - id: gen_ai.thread.id # alternatives: gen_ai.conversation.id, gen_ai.session.id (bedrock)
+ stability: experimental
+ type: string
+ brief: The unique identifier of the thread.
+ examples: ['thread_ggguJ0iZXRPjUnCy9vT9Fdvs']
+ - id: gen_ai.message.id
+ stability: experimental
+ type: string
+ brief: Identifies message sent to or received from Generative AI model or agent.
+ note: >
+ For inference operations such as `chat` or `text_completion`, it
+ SHOULD be the completion identifier returned by the GenAI system and
+ may not be unique if multiple choices are returned.
+
+ If message history is managed by the application, agent, or framework,
+ it SHOULD match the identifier used by the message history management system.
+ examples: ['msg_sLMd7grQfjFXgu5ZeHCXmBr7', 'chatcmpl-123']
+ - id: gen_ai.message.status
+ stability: experimental
+ type:
+ members:
+ - id: in_progress
+ value: "in_progress"
+ brief: 'The message is in progress'
+ stability: experimental
+ - id: completed
+ value: "completed"
+ brief: 'The message has been completed'
+ stability: experimental
+ - id: incomplete
+ value: "incomplete"
+ brief: 'The message has ended due to reaching maximum number of input or output tokens'
+ stability: experimental
+ brief: The status of the message.
+ - id: gen_ai.tool.call.id
+ stability: experimental
+ type: string
+ brief: The tool call identifier.
+ examples: ['call_mszuSIzqtI65i1wAUOE8w5H4']
+ - id: gen_ai.tool.name
+ stability: experimental
+ type: string
+ brief: The tool call identifier.
+ examples: ['call_mszuSIzqtI65i1wAUOE8w5H4']
+ - id: gen_ai.thread.run.id # alternatives: gen_ai.*.invocation.id (bedrock, langgraph), gen_ai.*.task.id (crewai)
+ stability: experimental
+ type: string
+ brief: The unique identifier of the thread run.
+ examples: ['run_ep8IxBKdM06Mv338KNyo6EKP']
+ - id: gen_ai.thread.run.status
+ stability: experimental
+ type:
+ members:
+ - id: queued
+ value: "queued"
+ brief: 'The thread run is queued'
+ stability: experimental
+ - id: in_progress
+ value: "in_progress"
+ brief: 'The thread run is in progress'
+ stability: experimental
+ - id: completed
+ value: "completed"
+ brief: 'The thread run has completed'
+ stability: experimental
+ - id: incomplete
+ value: "incomplete"
+ brief: 'The thread run has ended due to reaching maximum number of input or output tokens'
+ stability: experimental
+ - id: requires_action
+ value: "requires_action"
+ brief: 'The thread run requires action.'
+ stability: experimental
+ - id: failed
+ value: "failed"
+ brief: 'The thread run has failed'
+ stability: experimental
+ - id: canceled
+ value: "canceled"
+ brief: 'The thread run has been canceled'
+ stability: experimental
+ - id: expired
+ value: "expired"
+ brief: 'The thread run has expired'
+ stability: experimental
+ brief: The thread run status
+ - id: gen_ai.request.response_format
stability: experimental
type:
members:
@@ -168,7 +327,18 @@ groups:
brief: 'JSON schema response format'
stability: experimental
brief: The response format that is requested.
- examples: ['json']
+ - id: registry.gen_ai.openai
+ type: attribute_group
+ stability: experimental
+ display_name: OpenAI Attributes
+ brief: >
+ Thie group defines attributes for OpenAI.
+ attributes:
+ - id: gen_ai.openai.request.seed
+ stability: experimental
+ type: int
+ brief: Requests with same seed value more likely to return same result.
+ examples: [100]
- id: gen_ai.openai.request.service_tier
stability: experimental
type:
diff --git a/model/gen-ai/spans.yaml b/model/gen-ai/spans.yaml
index 79909f0f3c..f80711c98e 100644
--- a/model/gen-ai/spans.yaml
+++ b/model/gen-ai/spans.yaml
@@ -1,10 +1,14 @@
groups:
- - id: trace.gen_ai.client.common_attributes
+ - id: trace.gen_ai.client.minimal_attributes
type: attribute_group
stability: experimental
brief: >
- Describes GenAI operation span.
+ Describes GenAI span that represents agent creation.
attributes:
+ - ref: server.address
+ brief: GenAI server address.
+ requirement_level:
+ recommended: if available and if operation involves remote calls against GenAI service.
- ref: gen_ai.request.model
requirement_level:
conditionally_required: If available.
@@ -12,9 +16,27 @@ groups:
The name of the GenAI model a request is being made to. If the model is supplied by a vendor,
then the value must be the exact name of the model requested. If the model is a fine-tuned
custom model, the value should have a more specific name than the base model that's been fine-tuned.
- - ref: gen_ai.operation.name
- requirement_level: required
- - ref: gen_ai.request.max_tokens
+ - ref: server.port
+ brief: GenAI server port.
+ requirement_level:
+ conditionally_required: If `server.address` is set.
+ - ref: error.type
+ requirement_level:
+ conditionally_required: "if the operation ended in an error"
+ note: |
+ The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
+ the canonical name of exception that occurred, or another low-cardinality error identifier.
+ Instrumentations SHOULD document the list of errors they report.
+ - id: trace.gen_ai.client.common_attributes
+ type: attribute_group
+ stability: experimental
+ brief: >
+ Describes common GenAI attributes.
+ extends: trace.gen_ai.client.minimal_attributes
+ attributes:
+ - ref: gen_ai.request.max_input_tokens
+ requirement_level: recommended
+ - ref: gen_ai.request.max_output_tokens
requirement_level: recommended
- ref: gen_ai.request.temperature
requirement_level: recommended
@@ -26,7 +48,7 @@ groups:
requirement_level: recommended
- ref: gen_ai.request.presence_penalty
requirement_level: recommended
- - ref: gen_ai.response.id
+ - ref: gen_ai.message.id
requirement_level: recommended
- ref: gen_ai.response.model
requirement_level: recommended
@@ -40,35 +62,74 @@ groups:
requirement_level: recommended
- ref: gen_ai.usage.output_tokens
requirement_level: recommended
- - ref: server.address
- brief: GenAI server address.
- requirement_level: recommended
- - ref: server.port
- brief: GenAI server port.
+ - id: trace.gen_ai.client.common_and_agent_attributes
+ type: attribute_group
+ stability: experimental
+ brief: >
+ Describes GenAI operation span.
+ extends: trace.gen_ai.client.common_attributes
+ attributes:
+ - ref: gen_ai.agent.id
requirement_level:
- conditionally_required: If `server.address` is set.
- - ref: error.type
+ recommended: |
+ If available.
+
+ `gen_ai.agent.id` is usually available on the spans that describe operations
+ performed on the agent such as `create_agent` or `process_thread_run`.
+
+ Instrumentations of the low level GenAI inference operations such as
+ `chat` or `text_completion` done by the lower-level clients usually
+ don't have agent id available. If it's available, it SHOULD be set.
+ - ref: gen_ai.agent.name
requirement_level:
- conditionally_required: "if the operation ended in an error"
- note: |
- The `error.type` SHOULD match the error code returned by the Generative AI provider or the client library,
- the canonical name of exception that occurred, or another low-cardinality error identifier.
- Instrumentations SHOULD document the list of errors they report.
+ recommended: |
+ If available.
+
+ Agent name is usually available only on the agent-related operations
+ such as `create_agent`.
+ - ref: gen_ai.agent.description
+ requirement_level:
+ recommended: |
+ If available.
+
+ Agent name is usually available only on the agent-related operations
+ such as `create_agent`.
+ - ref: gen_ai.thread.id
+ requirement_level:
+ recommended: |
+ If available.
+
+ `gen_ai.thread.id` is usually available on the spans that describe operations
+ performed on the thread such as `create_thread` or `process_thread_run`.
+
+ Instrumentations of the low level GenAI inference operations such as
+ `chat` or `text_completion` done by the lower-level clients usually
+ don't have thread id available. If it's available, it SHOULD be set.
+ - ref: gen_ai.thread.run.id
+ requirement_level:
+ recommended: |
+ If available.
+
+ `gen_ai.thread.run.id` is usually available on the spans that describe
+ thread runs such as `process_thread_run` or `start_thread_run`.
+
+ Instrumentations of the low level GenAI inference operations such as
+ `chat` or `text_completion` done by the lower-level clients usually
+ don't have thread run id available. If it's available, it SHOULD be set.
- id: trace.gen_ai.client.span
type: span
stability: experimental
brief: >
Describes GenAI operation span.
- extends: trace.gen_ai.client.common_attributes
+ extends: trace.gen_ai.client.common_and_agent_attributes
attributes:
- ref: gen_ai.system
# TODO: Not adding to trace.gen_ai.client.common_attributes because of https://github.com/open-telemetry/build-tools/issues/192
requirement_level: required
- ref: gen_ai.request.top_k
requirement_level: recommended
- events:
- - gen_ai.content.prompt
- - gen_ai.content.completion
+ - ref: gen_ai.operation.name
+ requirement_level: required
- id: trace.gen_ai.openai.client
extends: trace.gen_ai.client.common_attributes
@@ -78,10 +139,12 @@ groups:
attributes:
- ref: gen_ai.request.model
requirement_level: required
+ - ref: gen_ai.operation.name
+ requirement_level: required
- ref: gen_ai.openai.request.seed
requirement_level:
conditionally_required: if the request includes a seed
- - ref: gen_ai.openai.request.response_format
+ - ref: gen_ai.request.response_format
requirement_level:
conditionally_required: if the request includes a response_format
- ref: gen_ai.openai.request.service_tier
@@ -102,6 +165,8 @@ groups:
brief: >
Describes Azure AI Inference span attributes.
attributes:
+ - ref: gen_ai.operation.name
+ requirement_level: required
- ref: az.namespace
note: >
When `az.namespace` attribute is populated, it MUST be set to `Microsoft.CognitiveServices` for all
@@ -116,3 +181,292 @@ groups:
- ref: server.port
requirement_level:
conditionally_required: If not default (443).
+
+ - id: trace.gen_ai.client.create_agent
+ type: span
+ stability: experimental
+ brief: >
+ Describes GenAI agent creation and is usually applicable when working
+ with remote agent services.
+ note: |
+ The `gen_ai.operation.name` MUST be `create_agent`.
+
+ The **span name** SHOULD be `create_agent {gen_ai.agent.name}`.
+ Semantic conventions for individual GenAI systems and frameworks MAY specify different span name format.
+ extends: trace.gen_ai.client.minimal_attributes
+ attributes:
+ - ref: gen_ai.system
+ requirement_level: required
+ - ref: gen_ai.agent.id
+ requirement_level:
+ conditionally_required: if applicable.
+ - ref: gen_ai.agent.name
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.agent.description
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.model
+ requirement_level:
+ conditionally_required: If provided by the application.
+ note: >
+ The name of the GenAI model a request is being made to. If the model is supplied by a vendor,
+ then the value must be the exact name of the model requested. If the model is a fine-tuned
+ custom model, the value should have a more specific name than the base model that's been fine-tuned.
+ - ref: gen_ai.request.temperature
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.top_p
+ requirement_level:
+ conditionally_required: If provided by the application.
+ #events:
+ # - ref: gen_ai.system.message
+ # - TODO tools & resources
+
+ - id: trace.gen_ai.client.create_thread
+ type: span
+ stability: experimental
+ brief: >
+ Describes creation of the thread on the GenAI agent and is usually applicable
+ when working with remote agent or history management services.
+ note: |
+ The `gen_ai.operation.name` MUST be `create_thread`.
+
+ The **span name** SHOULD be `create_thread`.
+ Semantic conventions for individual GenAI systems and frameworks MAY specify
+ different span name format.
+ extends: trace.gen_ai.client.minimal_attributes
+ attributes:
+ - ref: gen_ai.system
+ requirement_level: required
+ - ref: gen_ai.thread.id
+ requirement_level:
+ conditionally_required: if available
+ # events:
+ # - ref: gen_ai.user.message
+ # - ref: gen_ai.assistant.message
+ # - TODO tools & resources
+
+ - id: trace.gen_ai.client.execute_tool
+ type: span
+ stability: experimental
+ brief: Describes tool execution span.
+ note: |
+ `gen_ai.operation.name` SHOULD be `execute_tool`.
+
+ Span name SHOULD be `execute_tool {gen_ai.tool.name}`.
+
+ GenAI instrumentations that are able to instrument tool execution call SHOULD do so.
+
+ However, it's common for tools to be executed by the application code. It's recommended
+ for the application developers to follow this semantic conventions for tool invoked
+ by the application code.
+ attributes:
+ - ref: gen_ai.tool.call.id
+ requirement_level: recommended
+ - ref: gen_ai.tool.name
+ requirement_level: recommended
+ - ref: gen_ai.thread.run.id
+ requirement_level:
+ recommended: if available
+
+ - id: trace.gen_ai.client.create_message
+ type: span
+ stability: experimental
+ brief: Describes creation of the message on the GenAI agent is usually applicable
+ when working with remote agent or history management services.
+ note: |
+ The `gen_ai.operation.name` MUST be `create_message`.
+
+ The **span name** SHOULD be `create_message`.
+ Semantic conventions for individual GenAI systems and frameworks MAY specify
+ different span name format.
+ extends: trace.gen_ai.client.minimal_attributes
+ attributes:
+ - ref: gen_ai.system
+ requirement_level: required
+ - ref: gen_ai.thread.id
+ requirement_level:
+ conditionally_required: if available
+ - ref: gen_ai.message.id
+ requirement_level:
+ conditionally_required: if available
+ # events:
+ # - ref: gen_ai.user.message
+ # - ref: gen_ai.assistant.message
+
+ - id: trace.gen_ai.client.process_thread_run
+ type: span
+ stability: experimental
+ brief: >
+ Describes creation and full processing of the thread run on GenAI agent.
+ It's applicable for operations representing calls to remote GenAI agents or
+ logical operations performed by the GenAI framework or application code.
+ note:
+ The `gen_ai.operation.name` MUST be `process_thread_run`.
+
+ The **span name** SHOULD be `process_thread_run`.
+ Semantic conventions for individual GenAI systems and frameworks MAY specify
+ different span name format.
+
+ The span SHOULD be reported for streaming runs or for operations
+ that involve polling the run status and SHOULD cover full duration of the
+ run including tool calls and time awaiting the final completion.
+
+ Depending on the scenario and application code, this
+ may not be possible. In this case the span SHOULD cover the part that
+ instrumentation is able to capture and ensure that `gen_ai.thread.run.status`
+ attribute value reflects the last known status (`in_process`, `requires_action`,
+ etc).
+ extends: trace.gen_ai.client.minimal_attributes
+ attributes:
+ - ref: gen_ai.system
+ requirement_level: required
+ - ref: gen_ai.agent.id
+ requirement_level: required
+ - ref: gen_ai.thread.id
+ requirement_level: required
+ - ref: gen_ai.thread.run.id
+ requirement_level:
+ conditionally_required: if available
+ - ref: gen_ai.thread.run.status
+ requirement_level:
+ conditionally_required: if available
+ - ref: gen_ai.request.model
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.response.model
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.temperature
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.top_p
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.max_input_tokens
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.max_output_tokens
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.usage.input_tokens
+ brief: >
+ The number of input tokens for the whole run
+ requirement_level:
+ conditionally_required: If available.
+ - ref: gen_ai.usage.output_tokens
+ brief: >
+ The number of output tokens for the whole run
+ requirement_level:
+ conditionally_required: If available.
+ - ref: gen_ai.thread.run.status
+ note: >
+ SHOULD capture the last known status of the thread run.
+ requirement_level:
+ conditionally_required: If run has started.
+ # events:
+ # - ref: gen_ai.user.message
+ # - ref: gen_ai.assistant.message
+ # - ref: gen_ai.tool.message
+ # - TODO tools & resources
+
+ - id: trace.gen_ai.client.start_thread_run
+ type: span
+ stability: experimental
+ brief: >
+ Describes creation of the thread run on GenAI agent and is usually applicable
+ when working with remote agents.
+ note:
+ The `gen_ai.operation.name` MUST be `start_thread_run`.
+
+ The **span name** SHOULD be `start_thread_run`.
+
+ Semantic conventions for individual GenAI systems and frameworks MAY specify
+ different span name format.
+
+ This span SHOULD be reported when application is starting a run without awaiting
+ its completion. It SHOULD NOT be reported when instrumentation can capture the
+ full run processing. Full processing is covered by the
+ [Process thread run span](#process-thread-run-span).
+ extends: trace.gen_ai.client.minimal_attributes
+ attributes:
+ - ref: gen_ai.system
+ requirement_level: required
+ - ref: gen_ai.agent.id
+ requirement_level: required
+ - ref: gen_ai.thread.id
+ requirement_level: required
+ - ref: gen_ai.thread.run.id
+ requirement_level:
+ conditionally_required: if available
+ - ref: gen_ai.thread.run.status
+ requirement_level:
+ conditionally_required: if available
+ - ref: gen_ai.request.model
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.response.model
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.temperature
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.top_p
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.max_input_tokens
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.request.max_output_tokens
+ requirement_level:
+ conditionally_required: If provided by the application.
+ - ref: gen_ai.usage.input_tokens
+ brief: >
+ The number of input tokens for the whole run
+ requirement_level:
+ conditionally_required: If available.
+ - ref: gen_ai.usage.output_tokens
+ brief: >
+ The number of output tokens for the whole run
+ requirement_level:
+ conditionally_required: If available.
+ - ref: gen_ai.thread.run.status
+ note: >
+ SHOULD capture the last known status of the thread run.
+ requirement_level:
+ conditionally_required: If run has started.
+ # events:
+ # - ref: gen_ai.user.message
+ # - TODO tools & resources
+
+ - id: trace.gen_ai.client.submit_tool_outputs
+ type: span
+ stability: experimental
+ brief: >
+ Describes submission of the tool outputs to the GenAI agent and is usually applicable
+ when working with remote agents.
+ note:
+ The `gen_ai.operation.name` MUST be `submit_tool_outputs`.
+
+ The **span name** SHOULD be `submit_tool_outputs`.
+
+ Semantic conventions for individual GenAI systems and frameworks MAY specify
+ different span name format.
+
+ This span SHOULD be reported when instrumentation can determine that
+ application is submitting the tool call output to the model.
+
+ When application is submitting the tool call output with the generic GenAI call
+ such as `chat` or `text_completion`, the instrumentation SHOULD report generic
+ GenAI span since it cannot reliably determine the intent behind the generic GenAI call.
+ extends: trace.gen_ai.client.minimal_attributes
+ attributes:
+ - ref: gen_ai.system
+ requirement_level: required
+ - ref: gen_ai.thread.id
+ requirement_level: required
+ - ref: gen_ai.thread.run.id
+ requirement_level: required
+ # events:
+ # - ref: gen_ai.tool.message
diff --git a/schema-next.yaml b/schema-next.yaml
index 400ff09ac0..b260b641be 100644
--- a/schema-next.yaml
+++ b/schema-next.yaml
@@ -2,6 +2,15 @@ file_format: 1.1.0
schema_url: https://opentelemetry.io/schemas/next
versions:
next:
+ all:
+ changes:
+ # https://github.com/open-telemetry/semantic-conventions/pull/TODO
+ - rename_attributes:
+ attribute_map:
+ gen_ai.request.max_tokens: gen_ai.request.max_output_tokens
+ gen_ai.response.id: gen_ai.message.id
+ gen_ai.openai.request.response_format: gen_ai.request.response_format
+
1.28.0:
metrics:
changes: