---
title: "Span Attributes"
---

## Instrumentation Timing

To align with the Google ADK instrumentation conventions, the instrumentation timing in VeADK is consistent with Google ADK. Instrumentation mainly happens at the following points:

- [When invoking the agent](https://github.com/google/adk-python/blob/v1.17.0/src/google/adk/runners.py): Instrumented in the Runner's `_run_with_trace` function, with the span named `invocation`
- [When running the agent](https://github.com/google/adk-python/blob/v1.17.0/src/google/adk/agents/base_agent.py): Instrumented in the agent's `run_async` function, with the span named `invoke_agent {agent.name}`
- [When calling the model](https://github.com/google/adk-python/blob/v1.17.0/src/google/adk/flows/llm_flows/base_llm_flow.py): Instrumented in BaseLlmFlow's `_call_llm_with_tracing` function, with the span named `call_llm`
- [When calling a tool](https://github.com/google/adk-python/blob/v1.17.0/src/google/adk/flows/llm_flows/functions.py): Instrumented in BaseLlmFlow's `_execute_single_function_call_async` function, with the span named `execute_tool {tool.name}`

At each point, a span with the corresponding name is created to record the details of that point. When a stage ends, the corresponding instrumentation function is called to record the information of that stage into the span:

- Google ADK [instrumentation file](https://github.com/google/adk-python/blob/v1.17.0/src/google/adk/telemetry/tracing.py)
- VeADK [instrumentation file](https://github.com/volcengine/veadk-python/blob/main/veadk/tracing/telemetry/telemetry.py)

## Span Attribute Definitions

VeADK's span attribute naming and value conventions follow the [OpenTelemetry](https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/) community as well as the requirements of Volcengine products such as CozeLoop and APMPlus. Span attributes in VeADK fall into three categories:

- Common: present in all types of spans
- LLM: present in the `call_llm` span
- Tool: present in the `tool_call` span

<Callout type="info" title="Notes on Span Attributes">
  Because the OpenTelemetry community's field conventions for generative AI are still evolving, the meaning of some fields may change.
</Callout>

<Callout type="info" title="Input and Output Content Collection">
  `observability.opentelemetry.trace_content` or the `OBSERVABILITY_OPENTELEMETRY_TRACE_CONTENT` environment variable controls Agent, LLM, and tool input/output content collection. When set to `false`, fields marked as controlled by content collection in the tables below are not written to spans; non-content data such as trace structure, model parameters, token usage, and tool names is still retained.
</Callout>

### Common

| No. | Attribute Name | Meaning | Notes |
| - | - | - | - |
| 1  | `gen_ai.system` | The name of the generative-AI system provider, used to identify the model provider | Default value is `<unknown_model_provider>` |
| 2  | `gen_ai.system.version` | The VeADK framework version, used for version tracking and compatibility analysis | Always returns `veadk.version.VERSION` |
| 3  | `gen_ai.agent.name` | The agent name, used to distinguish different instances | Default value is `<unknown_agent_name>` |
| 4  | `openinference.instrumentation.veadk` | VeADK's OpenInference standardized instrumentation version identifier | Always returns `veadk.version.VERSION` |
| 5  | `gen_ai.app.name` | The `app_name` in the agent system | Default value is `<unknown_app_name>` |
| 6  | `gen_ai.user.id` | The `user_id` in the agent system | Default value is `<unknown_user_id>` |
| 7  | `gen_ai.session.id` | The `session_id` in the agent system | Default value is `<unknown_session_id>` |
| 8  | `agent_name` | The agent name | Same as `gen_ai.agent.name`; used for the CozeLoop platform |
| 9  | `agent.name` | The agent name | Same as `gen_ai.agent.name`; used for the TLS platform |
| 10 | `app_name` | The `app_name` in the agent system | Same as `gen_ai.app.name`; used for the CozeLoop platform |
| 11 | `app.name` | The `app_name` in the agent system | Same as `gen_ai.app.name`; used for the TLS platform |
| 12 | `user.id` | The `user_id` in the agent system | Same as `gen_ai.user.id`; used for the CozeLoop and TLS platforms |
| 13 | `session.id` | The `session_id` in the agent system | Same as `gen_ai.session.id`; used for the CozeLoop and TLS platforms |
| 14 | `cozeloop.report.source` | Trace data source identifier | Always returns `veadk`, indicating it comes from the VeADK framework; used for the CozeLoop platform |
| 15 | `cozeloop.call_type` | The CozeLoop call type | Default value is `None` |

### LLM

| No. | Attribute Name | Meaning | Notes |
| - | - | - | - |
| 1  | `gen_ai.request.model` | The model name, used to identify the specific model being called | Obtained from `params.llm_request.model`; default value is `<unknown_model_name>` |
| 2  | `gen_ai.request.type` | The LLM request type, identifying the interaction mode | Always returns `chat`, indicating conversational interaction |
| 3  | `gen_ai.request.max_tokens` | The configured maximum number of tokens to generate in the response | Obtained from `params.llm_request.config.max_output_tokens` |
| 4  | `gen_ai.request.temperature` | The sampling temperature parameter, controlling randomness of generation | Obtained from `params.llm_request.config.temperature` |
| 5  | `gen_ai.request.top_p` | The top-p parameter for cloud inference | Obtained from `params.llm_request.config.top_p` |
| 6  | `gen_ai.request.functions` | Metadata of the functions/tools defined in the request | Extracts the name, description, and parameter definitions of each tool; used for the CozeLoop platform |
| 7  | `gen_ai.response.model` | The model name actually used in the response | Consistent with the request model indicates a normal return |
| 8  | `gen_ai.response.stop_reason` | The reason the response generation stopped | Currently returns the placeholder `<no_stop_reason_provided>`, to be implemented later |
| 9  | `gen_ai.response.finish_reason` | The reason the response finished | Currently returns the placeholder `"<no_finish_reason_provided>"`, used to distinguish natural completion / truncation, etc. |
| 10 | `gen_ai.is_streaming` | Whether the response is streaming | Returns `None` |
| 11 | `gen_ai.operation.name` | The operation name | Always returns `chat`, used to uniformly identify the operation type |
| 12 | `gen_ai.span.kind` | The span kind | Always returns `llm`, conforming to OpenTelemetry semantic conventions |
| 13 | `gen_ai.prompt` | Structured information of the request input content | Records role, content, function calls, images, and other inputs in message order; controlled by content collection |
| 14 | `gen_ai.completion` | Structured information of the model response content | Records the text, function calls, and other output generated by the model; controlled by content collection |
| 15 | `gen_ai.usage.input_tokens` | The number of input tokens | Extracted from `params.llm_response.usage_metadata.prompt_token_count` |
| 16 | `gen_ai.usage.output_tokens` | The number of output tokens | Extracted from `params.llm_response.usage_metadata.candidates_token_count` |
| 17 | `gen_ai.usage.total_tokens` | The total number of tokens | Extracted from `params.llm_response.usage_metadata.total_token_count` |
| 18 | `gen_ai.usage.cache_creation_input_tokens` | The number of tokens used to create the cache | Extracted from `params.llm_response.usage_metadata.cached_content_token_count` |
| 19 | `gen_ai.usage.cache_read_input_tokens` | The number of tokens used to read the cache | Extracted from `params.llm_response.usage_metadata.cached_content_token_count` |
| 20 | `gen_ai.messages` | The complete conversation message events | Includes the structured event sequence of system instructions, user messages, tool responses, and assistant replies; controlled by content collection |
| 21 | `gen_ai.choice` | The model choice event | Represents the candidate response generated by the model (including function calls or text content); controlled by content collection |
| 22 | `input.value` | The complete LLM request body | *(for debugging)* The serialized output request object |
| 23 | `output.value` | The complete LLM response body | *(for debugging)* The serialized output response object |

### Tool

| No. | Attribute Name | Meaning | Notes |
| - | - | - | - |
| 1  | `gen_ai.operation.name` | The operation name | Always returns `execute_tool`, uniformly identifying tool-call operations |
| 2  | `gen_ai.tool.name` | The tool name | Obtained from `params.tool.name`; if absent, it is `<unknown_tool_name>`; used for the TLS platform |
| 3  | `gen_ai.tool.input` | The tool input content | JSON serialization includes `name`, `description`, `parameters`, used to record tool-call arguments; used for the TLS platform; controlled by content collection |
| 4  | `gen_ai.tool.output` | The tool output content | JSON serialization includes `id`, `name`, `response`, recording tool execution results; used for the TLS platform; controlled by content collection |
| 5  | `cozeloop.input` | The tool input | Same as `gen_ai.tool.input`; used for the CozeLoop platform; controlled by content collection |
| 6  | `cozeloop.output` | The tool output | Same as `gen_ai.tool.output`; used for the CozeLoop platform; controlled by content collection |
| 7  | `gen_ai.span.kind` | The span kind | Always returns `tool`, following OpenTelemetry semantic conventions; used for the APMPlus platform |
| 8  | `gen_ai.input` | The tool input | Same as `gen_ai.tool.input`; used for the APMPlus platform; controlled by content collection |
| 9  | `gen_ai.output` | The tool output | Same as `gen_ai.tool.output`; used for the APMPlus platform; controlled by content collection |
