diff --git a/.chloggen/main.yaml b/.chloggen/main.yaml
new file mode 100644
index 0000000000..2a0385c1b5
--- /dev/null
+++ b/.chloggen/main.yaml
@@ -0,0 +1,22 @@
+# Use this changelog template to create an entry for release notes.
+#
+# If your change doesn't affect end users you should instead start
+# your pull request title with [chore] or use the "Skip Changelog" label.
+
+# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
+change_type: enhancement
+
+# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db)
+component: gen-ai
+
+# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
+note: "`invoke_agent` spans now include span kind (CLIENT/INTERNAL) guidance and clarify when `server.*` attributes should be set."
+
+# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
+# The values here must be integers.
+issues: [2837]
+
+# (Optional) One or more lines of additional information to render under the primary note.
+# These lines will be padded with 2 spaces and then inserted directly into the document.
+# Use pipe (|) for multiline entries.
+subtext:
diff --git a/docs/gen-ai/gen-ai-agent-spans.md b/docs/gen-ai/gen-ai-agent-spans.md
index 2eaeaa51a3..ee1e31bd85 100644
--- a/docs/gen-ai/gen-ai-agent-spans.md
+++ b/docs/gen-ai/gen-ai-agent-spans.md
@@ -178,14 +178,22 @@ Instrumentations SHOULD document the list of errors they report.
**Status:** 
-Describes GenAI agent invocation and is usually applicable when working with remote agent services.
+Describes GenAI agent invocation.
The `gen_ai.operation.name` SHOULD be `invoke_agent`.
The **span name** SHOULD be `invoke_agent {gen_ai.agent.name}` if `gen_ai.agent.name` is readily available.
When `gen_ai.agent.name` is not available, it SHOULD be `invoke_agent`.
Semantic conventions for individual GenAI systems and frameworks MAY specify different span name format.
-**Span kind** SHOULD be `CLIENT`.
+**Span kind** SHOULD be `CLIENT` and MAY be set to `INTERNAL` on spans representing
+invocation of agents running in the same process.
+It's RECOMMENDED to use `CLIENT` kind when the agent being instrumented usually runs
+in a different process than its caller or when the agent invocation happens over
+instrumented protocol such as HTTP.
+
+Examples of span kinds for different agent scenarios:
+- `CLIENT`: Remote agent services (e.g., OpenAI Assistants API, AWS Bedrock Agents)
+- `INTERNAL`: In-process agents (e.g., LangChain agents, CrewAI agents)
**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document.
@@ -203,7 +211,7 @@ Semantic conventions for individual GenAI systems and frameworks MAY specify dif
| [`gen_ai.request.choice.count`](/docs/registry/attributes/gen-ai.md) | int | The target number of candidate completions to return. | `3` | `Conditionally Required` if available, in the request, and !=1 |  |
| [`gen_ai.request.model`](/docs/registry/attributes/gen-ai.md) | string | The name of the GenAI model a request is being made to. [8] | `gpt-4` | `Conditionally Required` If available. |  |
| [`gen_ai.request.seed`](/docs/registry/attributes/gen-ai.md) | int | Requests with same seed value more likely to return same result. | `100` | `Conditionally Required` if applicable and if the request includes a seed |  |
-| [`server.port`](/docs/registry/attributes/server.md) | int | GenAI server port. [9] | `80`; `8080`; `443` | `Conditionally Required` If `server.address` is set. |  |
+| [`server.port`](/docs/registry/attributes/server.md) | int | GenAI server port. [9] | `80`; `8080`; `443` | `Conditionally Required` [10] |  |
| [`gen_ai.request.frequency_penalty`](/docs/registry/attributes/gen-ai.md) | double | The frequency penalty setting for the GenAI request. | `0.1` | `Recommended` |  |
| [`gen_ai.request.max_tokens`](/docs/registry/attributes/gen-ai.md) | int | The maximum number of tokens the model generates for a request. | `100` | `Recommended` |  |
| [`gen_ai.request.presence_penalty`](/docs/registry/attributes/gen-ai.md) | double | The presence penalty setting for the GenAI request. | `0.1` | `Recommended` |  |
@@ -212,14 +220,14 @@ Semantic conventions for individual GenAI systems and frameworks MAY specify dif
| [`gen_ai.request.top_p`](/docs/registry/attributes/gen-ai.md) | double | The top_p sampling setting for the GenAI request. | `1.0` | `Recommended` |  |
| [`gen_ai.response.finish_reasons`](/docs/registry/attributes/gen-ai.md) | string[] | Array of reasons the model stopped generating tokens, corresponding to each generation received. | `["stop"]`; `["stop", "length"]` | `Recommended` |  |
| [`gen_ai.response.id`](/docs/registry/attributes/gen-ai.md) | string | The unique identifier for the completion. | `chatcmpl-123` | `Recommended` |  |
-| [`gen_ai.response.model`](/docs/registry/attributes/gen-ai.md) | string | The name of the model that generated the response. [10] | `gpt-4-0613` | `Recommended` |  |
+| [`gen_ai.response.model`](/docs/registry/attributes/gen-ai.md) | string | The name of the model that generated the response. [11] | `gpt-4-0613` | `Recommended` |  |
| [`gen_ai.usage.input_tokens`](/docs/registry/attributes/gen-ai.md) | int | The number of tokens used in the GenAI input (prompt). | `100` | `Recommended` |  |
| [`gen_ai.usage.output_tokens`](/docs/registry/attributes/gen-ai.md) | int | The number of tokens used in the GenAI response (completion). | `180` | `Recommended` |  |
-| [`server.address`](/docs/registry/attributes/server.md) | string | GenAI server address. [11] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` |  |
-| [`gen_ai.input.messages`](/docs/registry/attributes/gen-ai.md) | any | The chat history provided to the model as an input. [12] | [
{
"role": "user",
"parts": [
{
"type": "text",
"content": "Weather in Paris?"
}
]
},
{
"role": "assistant",
"parts": [
{
"type": "tool_call",
"id": "call_VSPygqKTWdrhaFErNvMV18Yl",
"name": "get_weather",
"arguments": {
"location": "Paris"
}
}
]
},
{
"role": "tool",
"parts": [
{
"type": "tool_call_response",
"id": " call_VSPygqKTWdrhaFErNvMV18Yl",
"result": "rainy, 57°F"
}
]
}
] | `Opt-In` |  |
-| [`gen_ai.output.messages`](/docs/registry/attributes/gen-ai.md) | any | Messages returned by the model where each message represents a specific model response (choice, candidate). [13] | [
{
"role": "assistant",
"parts": [
{
"type": "text",
"content": "The weather in Paris is currently rainy with a temperature of 57°F."
}
],
"finish_reason": "stop"
}
] | `Opt-In` |  |
-| [`gen_ai.system_instructions`](/docs/registry/attributes/gen-ai.md) | any | The system message or instructions provided to the GenAI model separately from the chat history. [14] | [
{
"type": "text",
"content": "You are an Agent that greet users, always use greetings tool to respond"
}
]; [
{
"type": "text",
"content": "You are a language translator."
},
{
"type": "text",
"content": "Your mission is to translate text in English to French."
}
] | `Opt-In` |  |
-| [`gen_ai.tool.definitions`](/docs/registry/attributes/gen-ai.md) | any | The list of source system tool definitions available to the GenAI agent or model. [15] | [
{
"type": "function",
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": [
"celsius",
"fahrenheit"
]
}
},
"required": [
"location",
"unit"
]
}
}
] | `Opt-In` |  |
+| [`server.address`](/docs/registry/attributes/server.md) | string | GenAI server address. [12] | `example.com`; `10.1.2.80`; `/tmp/my.sock` | `Recommended` when span kind is `CLIENT`. |  |
+| [`gen_ai.input.messages`](/docs/registry/attributes/gen-ai.md) | any | The chat history provided to the model as an input. [13] | [
{
"role": "user",
"parts": [
{
"type": "text",
"content": "Weather in Paris?"
}
]
},
{
"role": "assistant",
"parts": [
{
"type": "tool_call",
"id": "call_VSPygqKTWdrhaFErNvMV18Yl",
"name": "get_weather",
"arguments": {
"location": "Paris"
}
}
]
},
{
"role": "tool",
"parts": [
{
"type": "tool_call_response",
"id": " call_VSPygqKTWdrhaFErNvMV18Yl",
"result": "rainy, 57°F"
}
]
}
] | `Opt-In` |  |
+| [`gen_ai.output.messages`](/docs/registry/attributes/gen-ai.md) | any | Messages returned by the model where each message represents a specific model response (choice, candidate). [14] | [
{
"role": "assistant",
"parts": [
{
"type": "text",
"content": "The weather in Paris is currently rainy with a temperature of 57°F."
}
],
"finish_reason": "stop"
}
] | `Opt-In` |  |
+| [`gen_ai.system_instructions`](/docs/registry/attributes/gen-ai.md) | any | The system message or instructions provided to the GenAI model separately from the chat history. [15] | [
{
"type": "text",
"content": "You are an Agent that greet users, always use greetings tool to respond"
}
]; [
{
"type": "text",
"content": "You are a language translator."
},
{
"type": "text",
"content": "Your mission is to translate text in English to French."
}
] | `Opt-In` |  |
+| [`gen_ai.tool.definitions`](/docs/registry/attributes/gen-ai.md) | any | The list of source system tool definitions available to the GenAI agent or model. [16] | [
{
"type": "function",
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": [
"celsius",
"fahrenheit"
]
}
},
"required": [
"location",
"unit"
]
}
}
] | `Opt-In` |  |
**[1] `gen_ai.operation.name`:** 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.
@@ -272,11 +280,13 @@ Additional output format details may be recorded in the future in the `gen_ai.ou
**[9] `server.port`:** 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.
-**[10] `gen_ai.response.model`:** 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.
+**[10] `server.port`:** when span kind is `CLIENT` and `server.address` is set.
+
+**[11] `gen_ai.response.model`:** 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] `server.address`:** 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.
+**[12] `server.address`:** 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.
-**[12] `gen_ai.input.messages`:** Instrumentations MUST follow [Input messages JSON schema](/docs/gen-ai/gen-ai-input-messages.json).
+**[13] `gen_ai.input.messages`:** Instrumentations MUST follow [Input messages JSON schema](/docs/gen-ai/gen-ai-input-messages.json).
When the attribute is recorded on events, it MUST be recorded in structured
form. When recorded on spans, it MAY be recorded as a JSON string if structured
format is not supported and SHOULD be recorded in structured form otherwise.
@@ -291,7 +301,7 @@ input messages.
See [Recording content on attributes](/docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes)
section for more details.
-**[13] `gen_ai.output.messages`:** Instrumentations MUST follow [Output messages JSON schema](/docs/gen-ai/gen-ai-output-messages.json)
+**[14] `gen_ai.output.messages`:** Instrumentations MUST follow [Output messages JSON schema](/docs/gen-ai/gen-ai-output-messages.json)
Each message represents a single output choice/candidate generated by
the model. Each message corresponds to exactly one generation
@@ -311,7 +321,7 @@ output messages.
See [Recording content on attributes](/docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes)
section for more details.
-**[14] `gen_ai.system_instructions`:** This attribute SHOULD be used when the corresponding provider or API
+**[15] `gen_ai.system_instructions`:** This attribute SHOULD be used when the corresponding provider or API
allows to provide system instructions or messages separately from the
chat history.
@@ -332,7 +342,7 @@ system instructions.
See [Recording content on attributes](/docs/gen-ai/gen-ai-spans.md#recording-content-on-attributes)
section for more details.
-**[15] `gen_ai.tool.definitions`:** The value of this attribute matches source system tool definition format.
+**[16] `gen_ai.tool.definitions`:** The value of this attribute matches source system tool definition format.
It's expected to be an array of objects where each object represents a tool definition. In case a serialized string is available
to the instrumentation, the instrumentation SHOULD do the best effort to
@@ -387,9 +397,9 @@ populating this attribute.
| `azure.ai.openai` | [Azure OpenAI](https://azure.microsoft.com/products/ai-services/openai-service/) |  |
| `cohere` | [Cohere](https://cohere.com/) |  |
| `deepseek` | [DeepSeek](https://www.deepseek.com/) |  |
-| `gcp.gemini` | [Gemini](https://cloud.google.com/products/gemini) [16] |  |
-| `gcp.gen_ai` | Any Google generative AI endpoint [17] |  |
-| `gcp.vertex_ai` | [Vertex AI](https://cloud.google.com/vertex-ai) [18] |  |
+| `gcp.gemini` | [Gemini](https://cloud.google.com/products/gemini) [17] |  |
+| `gcp.gen_ai` | Any Google generative AI endpoint [18] |  |
+| `gcp.vertex_ai` | [Vertex AI](https://cloud.google.com/vertex-ai) [19] |  |
| `groq` | [Groq](https://groq.com/) |  |
| `ibm.watsonx.ai` | [IBM Watsonx AI](https://www.ibm.com/products/watsonx-ai) |  |
| `mistral_ai` | [Mistral AI](https://mistral.ai/) |  |
@@ -397,11 +407,11 @@ populating this attribute.
| `perplexity` | [Perplexity](https://www.perplexity.ai/) |  |
| `x_ai` | [xAI](https://x.ai/) |  |
-**[16]:** Used when accessing the 'generativelanguage.googleapis.com' endpoint. Also known as the AI Studio API.
+**[17]:** Used when accessing the 'generativelanguage.googleapis.com' endpoint. Also known as the AI Studio API.
-**[17]:** May be used when specific backend is unknown.
+**[18]:** May be used when specific backend is unknown.
-**[18]:** Used when accessing the 'aiplatform.googleapis.com' endpoint.
+**[19]:** Used when accessing the 'aiplatform.googleapis.com' endpoint.
diff --git a/model/gen-ai/spans.yaml b/model/gen-ai/spans.yaml
index fd6c9632d0..275c39cacc 100644
--- a/model/gen-ai/spans.yaml
+++ b/model/gen-ai/spans.yaml
@@ -252,13 +252,22 @@ groups:
stability: development
span_kind: client
brief: >
- Describes GenAI agent invocation and is usually applicable when working
- with remote agent services.
+ Describes GenAI agent invocation.
note: |
The `gen_ai.operation.name` SHOULD be `invoke_agent`.
The **span name** SHOULD be `invoke_agent {gen_ai.agent.name}` if `gen_ai.agent.name` is readily available.
When `gen_ai.agent.name` is not available, it SHOULD be `invoke_agent`.
Semantic conventions for individual GenAI systems and frameworks MAY specify different span name format.
+
+ **Span kind** SHOULD be `CLIENT` and MAY be set to `INTERNAL` on spans representing
+ invocation of agents running in the same process.
+ It's RECOMMENDED to use `CLIENT` kind when the agent being instrumented usually runs
+ in a different process than its caller or when the agent invocation happens over
+ instrumented protocol such as HTTP.
+
+ Examples of span kinds for different agent scenarios:
+ - `CLIENT`: Remote agent services (e.g., OpenAI Assistants API, AWS Bedrock Agents)
+ - `INTERNAL`: In-process agents (e.g., LangChain agents, CrewAI agents)
extends: attributes.gen_ai.inference.client
attributes:
- ref: gen_ai.provider.name
@@ -275,6 +284,12 @@ groups:
- ref: gen_ai.data_source.id
requirement_level:
conditionally_required: if applicable.
+ - ref: server.address
+ requirement_level:
+ recommended: when span kind is `CLIENT`.
+ - ref: server.port
+ requirement_level:
+ conditionally_required: when span kind is `CLIENT` and `server.address` is set.
- ref: gen_ai.system_instructions
requirement_level: opt_in
- ref: gen_ai.input.messages