AI Agents Module

The AI Agents module is agnostic to the library used. The SDK will instrument existing AI agents in certain frameworks or libraries (at the time of writing those are openai-agents in Python and Vercel AI in Javascript). You may need to manually annotate spans for other libraries.

For your AI agents data to show up in the Sentry AI Agents dashboard, at least one of the AI spans needs to be created and have well-defined names and data attributes. If the required data (marked with MUST or required) is missing, the data will not show up in the Agents dashbboard.

We try to follow v1.36.0 of the OpenTelemetry Semantic Conventions for Generative AI as close as possible. Being 100% compatible is not yet possible, because OpenTelemetry has "Span Events" which Sentry does not support. The input from/output to an AI model is stored in span events in OpenTelemetry. Since this is not possible in Sentry, we add this data onto span attributes as a list.

Describes AI agent invocation. Agent invocations represent operations that can include multiple model calls, or some auxiliary work that goes beyond transforming the model input and output.

  • Span op SHOULD be "gen_ai.invoke_agent".
  • Span name SHOULD be "invoke_agent {gen_ai.agent.name}". (e.g. "invoke_agent Weather Agent") [6]
  • Attribute gen_ai.operation.name MUST be "invoke_agent".
  • Attribute gen_ai.agent.name SHOULD be set to the agents name. (e.g. "Weather Agent")
  • If relevant, the gen_ai.pipeline.name attribute SHOULD be set to the name of the AI workflow, pipeline or chain within which the agent operates. (e.g. "weather-pipeline")

Additional attributes on the span:

AttributeTypeRequirement LevelDescriptionExample
gen_ai.input.messagesstringoptionalList of dictionaries describing the messages (prompts) given to the agent. [0], [1], [4], [5], [7]'[{"role": "user", "parts": [{"type": "text", "content": "..."}]}]'
gen_ai.system_instructionsstringoptionalThe system instructions passed to the model."You are a helpful assistant."

AttributeTypeRequirement LevelDescriptionExample
gen_ai.output.messagesstringoptionalStringified array of message objects representing the model's output. [0], [1]'[{"role": "assistant", "parts": [{"type": "text", "content": "..."}]}]'
  • [0]: Span attributes only allow primitive data types (like int, float, boolean, string). This means you need to use a stringified version of a list of dictionaries. Do NOT set the object/array [{"foo": "bar"}] but rather the string '[{"foo": "bar"}]' (must be parsable JSON).
  • [1]: Messages use the format {role, parts} where parts is an array of typed objects: [{"role": "user", "parts": [{"type": "text", "content": "..."}]}]. The role must be "user", "assistant", "tool", or "system". For backwards compatibility, the legacy format {role, content} (e.g. [{"role": "user", "content": "..."}]) is also accepted.

This span represents a request to an AI model or service that generates a response or requests a tool call based on the input prompt.

  • Span op SHOULD be "gen_ai.{gen_ai.operation.name}". (e.g. "gen_ai.chat")
  • Span name SHOULD be {gen_ai.operation.name} {gen_ai.request.model}". (e.g. "chat o3-mini")
  • Attribute gen_ai.operation.name MUST be "chat", "embeddings", "generate_content" or "text_completion".
  • Attribute gen_ai.provider.name MUST be the Generative AI product as identified by the client or server instrumentation. (e.g. "openai")
  • Attribute gen_ai.request.model MUST be the requested model. (e.g. "gpt-4o")
  • Attribute gen_ai.response.model MUST be the concrete response model. (e.g. "gpt-4o-2024-08-06")
  • If the request originates from an agent, the gen_ai.agent.name attribute SHOULD be set to the name of the agent. (e.g. "Weather Agent")
  • If relevant, the gen_ai.pipeline.name attribute SHOULD be set to the name of the AI workflow, pipeline or chain within which the agent operates. (e.g. "weather-pipeline")

Additional attributes on the span:

AttributeTypeRequirement LevelDescriptionExample
gen_ai.input.messagesstringoptionalList of dictionaries describing the messages (prompts) sent to the LLM. [0], [1], [4], [5], [7]'[{"role": "user", "parts": [{"type": "text", "content": "..."}]}]'
gen_ai.tool.definitionsstringoptionalList of dictionaries describing the available tools. [0]'[{"name": "random_number", "description": "..."}, ...]'
gen_ai.system_instructionsstringoptionalThe system instructions passed to the model."You are a helpful assistant."
gen_ai.request.max_tokensintoptionalModel configuration parameter.500
gen_ai.request.seedstringoptionalSeed for reproducible outputs."12345"
gen_ai.request.frequency_penaltyfloatoptionalModel configuration parameter.0.5
gen_ai.request.presence_penaltyfloatoptionalModel configuration parameter.0.5
gen_ai.request.temperaturefloatoptionalModel configuration parameter.0.1
gen_ai.request.top_pfloatoptionalModel configuration parameter.0.7
gen_ai.request.top_kintoptionalLimits model to K most likely next tokens.40
gen_ai.request.reasoning.levelstringoptionalThe reasoning or thinking effort level requested for a GenAI model. Supported values vary by provider."medium"
gen_ai.request.messagesstringoptionalDeprecated. Use gen_ai.input.messages instead. List of dictionaries describing the messages (prompts) sent to the LLM. [0]'[{"role": "system", "content": "..."}, ...]'
gen_ai.request.available_toolsstringoptionalDeprecated. Use gen_ai.tool.definitions instead. List of dictionaries describing the available tools. [0]'[{"name": "random_number", "description": "..."}, ...]'

AttributeTypeRequirement LevelDescriptionExample
gen_ai.output.messagesstringoptionalStringified array of message objects representing the model's output. [0], [1]'[{"role": "assistant", "parts": [{"type": "text", "content": "..."}]}]'
gen_ai.response.finish_reasonsstringoptionalThe reason why the model stopped generating."stop"
gen_ai.response.idstringoptionalUnique identifier for the completion."chatcmpl-abc123"
gen_ai.response.streamingbooleanoptionalWhether response was streamed asynchronously.true
gen_ai.response.time_to_first_chunkdoubleoptionalSeconds until first response chunk in streaming.0.5
gen_ai.response.textstringoptionalDeprecated. Use gen_ai.output.messages instead. The text representation of the model's response. [0]"The weather in Paris is rainy"
gen_ai.response.tool_callsstringoptionalDeprecated. Use gen_ai.output.messages instead. The tool calls in the model's response. [0]'[{"name": "random_number", "type": "function_call", "arguments": "..."}]'
gen_ai.response.time_to_first_tokendoubleoptionalDeprecated. Use gen_ai.response.time_to_first_chunk instead. Seconds until first response chunk in streaming.0.5

AttributeTypeRequirement LevelDescriptionExample
gen_ai.usage.input_tokensintoptionalThe number of tokens used in the AI input (prompt), including cached tokens. [2]60
gen_ai.usage.cache_read.input_tokensintoptionalThe number of cached tokens used in the AI input (prompt).50
gen_ai.usage.cache_creation.input_tokensintoptionalTokens written to cache when processing input.20
gen_ai.usage.output_tokensintoptionalThe number of tokens used in the AI output, including reasoning tokens. [3]130
gen_ai.usage.reasoning.output_tokensintoptionalThe number of tokens used for reasoning.30
gen_ai.usage.total_tokensintoptionalThe sum of gen_ai.usage.input_tokens and gen_ai.usage.output_tokens.190
gen_ai.usage.input_tokens.cachedintoptionalDeprecated. Use gen_ai.usage.cache_read.input_tokens instead. The number of cached tokens used in the AI input (prompt).50
gen_ai.usage.input_tokens.cache_writeintoptionalDeprecated. Use gen_ai.usage.cache_creation.input_tokens instead. Tokens written to cache when processing input.20
gen_ai.usage.output_tokens.reasoningintoptionalDeprecated. Use gen_ai.usage.reasoning.output_tokens instead. The number of tokens used for reasoning.30
  • [0]: Span attributes only allow primitive data types (like int, float, boolean, string). This means you need to use a stringified version of a list of dictionaries. Do NOT set the object/array [{"foo": "bar"}] but rather the string '[{"foo": "bar"}]' (must be parsable JSON).
  • [1]: Messages use the format {role, parts} where parts is an array of typed objects: [{"role": "user", "parts": [{"type": "text", "content": "..."}]}]. The role must be "user", "assistant", "tool", or "system". For backwards compatibility, the legacy format {role, content} (e.g. [{"role": "user", "content": "..."}]) is also accepted.
  • [2]: Cached tokens are a subset of input tokens; gen_ai.usage.input_tokens includes gen_ai.usage.cache_read.input_tokens.
  • [3]: Reasoning tokens are a subset of output tokens; gen_ai.usage.output_tokens includes gen_ai.usage.reasoning.output_tokens.

Describes a tool execution.

  • Span op SHOULD be "gen_ai.execute_tool".
  • Span name SHOULD be "execute_tool {gen_ai.tool.name}". (e.g. "execute_tool query_database")
  • Attribute gen_ai.operation.name MUST be "execute_tool".
  • Attribute gen_ai.tool.name SHOULD be set to the name of the tool. (e.g. "query_database")
  • Attribute gen_ai.agent.name SHOULD be set to the name of the agent that invoked the tool. (e.g. "Weather Agent")
  • If relevant, the gen_ai.pipeline.name attribute SHOULD be set to the name of the AI workflow, pipeline or chain within which the agent operates. (e.g. "weather-pipeline")

Additional attributes on the span:

AttributeTypeRequirement LevelDescriptionExample
gen_ai.tool.namestringoptionalName of the tool executed."random_number"
gen_ai.tool.descriptionstringoptionalDescription of the tool executed."Tool returning a random number"
gen_ai.tool.typestringoptionalThe type of the tools."function"; "extension"; "datastore"
gen_ai.tool.call.argumentsstringoptionalArguments of the tool call (stringified).'{"max":10}'
gen_ai.tool.call.resultstringoptionalResult of the tool call (stringified)."7"
gen_ai.tool.messagestringoptionalResponse from a tool/function call passed to model."The random number is 7"
gen_ai.tool.inputstringoptionalDeprecated. Use gen_ai.tool.call.arguments instead. Input that was given to the executed tool as string.'{"max":10}'
gen_ai.tool.outputstringoptionalDeprecated. Use gen_ai.tool.call.result instead. The output from the tool."7"

[2]:

Cached tokens are a subset of input tokens; gen_ai.usage.input_tokens includes gen_ai.usage.input_tokens.cached.

[3]:

Reasoning tokens are a subset of output tokens; gen_ai.usage.output_tokens includes gen_ai.usage.output_tokens.reasoning.

[4]

The input list should include the most recent messages up to and including the most recent previous model response. The previous model response is identified with an "assistant" or "model" role in common frameworks. If there is no previous model response in the input list, then all input items which are not system instructions should be included. System instructions must be added in gen_ai.system_instructions, and are not included in the gen_ai.input.messages list.

[5]

Binary blobs in the input list should be replaced with the string "[Blob substitute]" in positions where binary data is expected in a given schema. Only binary blobs in positions where binary data is explicitly expected must be redacted. For example, in OpenAI Completions schema, only binary blobs in content blocks with type image_url, input_audio or file should be redacted.

[6]

In some agent libraries, the agent name is optional, and some do not provide the user an option to name their agents. In these cases, the span name SHOULD be "invoke_agent {call_id}", where call_id is some user-provided identifier for the agent invocation. For example, functionId in Vercel AI.

[7]

Image URLs in the data URL format in the input list should be replaced with the string "[Blob substitute]" in positions where binary data is expected. For example, data URLs like data:image/png;base64 will be redacted, but HTTP URLs like example.com/data?<a-base64-string> will not be.

See here for the regex used.

Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").