Telemetry
The AI SDK uses OpenTelemetry to collect telemetry data. OpenTelemetry is an open-source observability framework designed to provide standardized instrumentation for collecting telemetry data.
Check out the AI SDK Observability Integrations to see providers that offer monitoring and tracing for AI SDK applications.
Enabling telemetry
Step 1: Register the OpenTelemetry integration
OpenTelemetry span collection requires the @ai-sdk/otel package. Install it and register the integration once at application startup:
pnpm install @ai-sdk/otelimport { registerTelemetry } from 'ai';import { OpenTelemetry } from '@ai-sdk/otel';
registerTelemetry(new OpenTelemetry());Next.js
For Next.js applications, create an instrumentation.ts file in your project root and register the AI SDK telemetry integration alongside your OpenTelemetry provider setup:
import { registerOTel } from '@vercel/otel';import { registerTelemetry } from 'ai';import { OpenTelemetry } from '@ai-sdk/otel';
export function register() { registerOTel({ serviceName: 'my-ai-app', });
registerTelemetry(new OpenTelemetry());}See the Next.js OpenTelemetry guide for more details on setting up OpenTelemetry in Next.js.
For Node.js applications (without Next.js), register the integration at the top level of your entry file.
Step 2: Enabling Telemetry
Once a telemetry integration is registered, all AI SDK calls emit telemetry events by default.
You can still pass telemetry to attach metadata (like functionId) or to opt out of a specific call:
const result = await generateText({ model: "xai/grok-4.5", prompt: 'Write a short story about a cat.', telemetry: { functionId: `story-agent`, },});By default, both inputs and outputs are recorded. You can disable them by setting the recordInputs and recordOutputs options to false.
Disabling the recording of inputs and outputs can be useful for privacy, data transfer, and performance reasons. You might for example want to disable recording inputs if they contain sensitive information.
Opting out
Telemetry is opt-out. To disable telemetry for a specific call, set isEnabled: false:
const result = await generateText({ model: "xai/grok-4.5", prompt: 'Write a short story about a cat.', telemetry: { isEnabled: false },});To disable telemetry globally, do not register any telemetry integrations via the registerTelemetry() function.
Telemetry Metadata
You can provide a functionId to identify the function that the telemetry data is for,
and runtimeContext to include additional information in the telemetry data.
For the broader context model, see
Runtime and Tool Context.
const result = await generateText({ model: "xai/grok-4.5", prompt: 'Write a short story about a cat.', runtimeContext: { userId: 'user_123', requestId: 'req_abc', }, telemetry: { functionId: 'my-awesome-function', },});Runtime context telemetry inclusion
runtimeContext can contain values that are useful inside your application but should not be sent to telemetry providers, such as user identifiers, tenant IDs, or credentials. Use telemetry.includeRuntimeContext to mark the top-level runtimeContext properties that should be included in telemetry:
const result = await generateText({ model: "xai/grok-4.5", prompt: 'Write a short story about a cat.', runtimeContext: { userId: 'user_123', requestId: 'req_abc', }, telemetry: { includeRuntimeContext: { requestId: true, }, },});In this example, telemetry integrations receive runtimeContext as { requestId: 'req_abc' }. Properties set to false or omitted are excluded. If telemetry.includeRuntimeContext is omitted, no runtime context properties are included. telemetry.includeRuntimeContext is supported by generateText, streamText, and ToolLoopAgent.
telemetry.includeRuntimeContext only filters telemetry integrations,
including OpenTelemetry integrations. Lifecycle callbacks and returned results
still receive the full runtimeContext.
Tool context
Tool-specific context can also contain values that are useful during execution but should not be sent to telemetry providers, such as API keys or access tokens.
Use telemetry.includeToolsContext to include selected top-level properties from a tool's context in telemetry:
const weatherTool = tool({ inputSchema: z.object({ location: z.string(), }), contextSchema: z.object({ weatherApiKey: z.string(), defaultUnit: z.enum(['celsius', 'fahrenheit']), }), execute: async ({ location }, { context }) => fetchWeather(location, context.weatherApiKey, context.defaultUnit),});
const result = await generateText({ model: "xai/grok-4.5", tools: { weather: weatherTool }, toolsContext: { weather: { weatherApiKey: 'weather-123', defaultUnit: 'fahrenheit', }, }, prompt: 'What is the weather in San Francisco?', telemetry: { includeToolsContext: { weather: { defaultUnit: true, }, }, },});In this example, telemetry integrations receive toolsContext.weather and tool execution telemetry event toolContext as { defaultUnit: 'fahrenheit' }.
Properties set to false or omitted are excluded. If telemetry.includeToolsContext is omitted, no tool context properties are included. telemetry.includeToolsContext is supported by generateText, streamText, and ToolLoopAgent.
telemetry.includeToolsContext only filters telemetry integrations, including
OpenTelemetry integrations. Tool execution, lifecycle callbacks, and returned
results still receive the full tool context. See Runtime and Tool
Context for the difference
between tool execution context and telemetry event context.
Custom Tracer
If you want your traces to use a TracerProvider other than the one provided by the @opentelemetry/api singleton, pass a custom Tracer to the OpenTelemetry constructor:
import { registerTelemetry } from 'ai';import { OpenTelemetry } from '@ai-sdk/otel';
const tracerProvider = new NodeTracerProvider();registerTelemetry( new OpenTelemetry({ tracer: tracerProvider.getTracer('gen_ai'), }),);Telemetry Integrations
Telemetry integrations let you hook into the generation lifecycle to build custom observability — logging, analytics, DevTools, or any other monitoring system. Instead of wiring up individual callbacks on every call, you implement a Telemetry once and register it globally or pass it via telemetry.integrations.
The OpenTelemetry and LegacyOpenTelemetry from @ai-sdk/otel are the built-in integrations for collecting OpenTelemetry spans (see Enabling telemetry above).
Registering integrations globally
Use registerTelemetry to register an integration once for all AI SDK calls:
import { registerTelemetry } from 'ai';import { OpenTelemetry } from '@ai-sdk/otel';
registerTelemetry(new OpenTelemetry());You can also register multiple integrations in a single call by passing them as additional arguments. They all receive the same lifecycle events:
import { registerTelemetryIntegration } from 'ai';import { OpenTelemetry } from '@ai-sdk/otel';import { DevToolsTelemetry } from '@ai-sdk/devtools';
registerTelemetryIntegration(new OpenTelemetry(), DevToolsTelemetry());Per-call integrations
You can also pass one or more integrations to individual generateText or streamText calls. When per-call integrations are provided, they replace the globally registered integrations for that call:
import { streamText } from 'ai';import { DevToolsTelemetry } from '@ai-sdk/devtools';
const result = streamText({ model: openai('gpt-4o'), prompt: 'Hello!', telemetry: { integrations: [DevToolsTelemetry()], },});You can combine multiple integrations — they all receive the same lifecycle events:
telemetry: { integrations: [DevToolsTelemetry(), customLogger()],},Errors inside integrations are caught and do not break the generation flow.
Tracing channel
In Node.js, AI SDK telemetry lifecycle and execution events are also traced on
the ai:telemetry tracing channel.
This lets observability providers subscribe to AI SDK telemetry events without
requiring users to register a separate telemetry integration, and bind async
context across provider calls and tool executions.
import { tracingChannel } from 'node:diagnostics_channel';import { AI_SDK_TELEMETRY_TRACING_CHANNEL, type TelemetryTracingChannelMessage,} from 'ai';
tracingChannel(AI_SDK_TELEMETRY_TRACING_CHANNEL).subscribe({ start(message) { const telemetryMessage = message as TelemetryTracingChannelMessage;
if (telemetryMessage.type === 'onStart') { // Inspect telemetryMessage.event and forward it to your provider. } },});Tracing-channel events follow the same per-call telemetry settings as other
telemetry integrations. Setting telemetry: { isEnabled: false } disables both
registered integrations and tracing-channel events for that call.
Building a custom integration
Implement the Telemetry interface from the ai package. All methods are optional — implement only the lifecycle events you care about:
import type { Telemetry } from 'ai';
class MyIntegration implements Telemetry { async onStart(event) { console.log('Generation started:', event.modelId); }
async onStepEnd(event) { console.log( `Step ${event.stepNumber} done:`, event.usage.totalTokens, 'tokens', ); }
async onToolExecutionEnd(event) { if (event.toolOutput.type === 'tool-result') { console.log( `Tool "${event.toolCall.toolName}" took ${event.toolExecutionMs}ms`, ); } else { console.error( `Tool "${event.toolCall.toolName}" failed:`, event.toolOutput.error, ); } }
async onEnd(event) { console.log('Done. Total tokens:', event.usage.totalTokens); }
async onAbort(event) { console.log('Stream aborted after', event.steps.length, 'finished steps'); }}
export function myIntegration(): Telemetry { return new MyIntegration();}Available lifecycle methods
onStart:
onStepStart:
onLanguageModelCallStart:
onLanguageModelCallEnd:
onToolExecutionStart:
onToolExecutionEnd:
onStepEnd:
onEmbedEnd:
onRerankEnd:
onEnd:
onAbort:
The event types for each method are the same as the corresponding lifecycle callbacks. See the lifecycle callbacks documentation for the full property reference of each event.
Collected Data
The @ai-sdk/otel package provides two integrations that emit different span formats.
The OpenTelemetry follows the OpenTelemetry GenAI Semantic Conventions and is the recommended integration.
The LegacyOpenTelemetry integration emits legacy AI SDK-specific spans.
GenAI Semantic Conventions
The OpenTelemetry emits spans that follow the OpenTelemetry Semantic Conventions for GenAI.
By default, attributes use the gen_ai.* prefix. Provider names are mapped to well-known values (e.g. openai, anthropic, gcp.vertex_ai).
generateText / streamText
For generateText and streamText, the integration records 3 types of spans:
-
invoke_agent {modelId}(root span,INTERNAL): covers the full operation including all steps and tool calls.Initial attributes:
gen_ai.operation.name:"invoke_agent"gen_ai.provider.name: the provider (e.g."openai","anthropic")gen_ai.request.model: the requested model IDgen_ai.agent.name: thefunctionIdfrom telemetry settingsgen_ai.system_instructions: system instructions formatted as a JSON array of parts (whenrecordInputsis enabled)gen_ai.input.messages: the input messages in GenAI SemConv message format (whenrecordInputsis enabled)gen_ai.request.temperature: the temperature settinggen_ai.request.max_tokens: the maximum output tokensgen_ai.request.top_p: the topP settinggen_ai.request.top_k: the topK settinggen_ai.request.frequency_penalty: the frequency penaltygen_ai.request.presence_penalty: the presence penaltygen_ai.request.stop_sequences: the stop sequencesgen_ai.request.seed: the seed value
Attributes set on finish:
gen_ai.response.finish_reasons: array of finish reasons (e.g.["stop"],["tool_call"])gen_ai.usage.input_tokens: the number of input tokens usedgen_ai.usage.output_tokens: the number of output tokens usedgen_ai.usage.cache_read.input_tokens: cached input tokens readgen_ai.usage.cache_creation.input_tokens: cached input tokens createdgen_ai.output.messages: the output in GenAI SemConv message format (whenrecordOutputsis enabled)
-
chat {modelId}(step span,CLIENT): one span per LLM provider call, nested under the root span.Initial attributes:
gen_ai.operation.name:"chat"gen_ai.provider.name: the providergen_ai.request.model: the requested model IDgen_ai.request.temperature,gen_ai.request.max_tokens,gen_ai.request.top_p,gen_ai.request.top_k,gen_ai.request.frequency_penalty,gen_ai.request.presence_penalty,gen_ai.request.stop_sequences: request parametersgen_ai.input.messages: the prompt messages in GenAI SemConv message format (whenrecordInputsis enabled)gen_ai.tool.definitions: the tool definitions as stringified JSON (whenrecordInputsis enabled)
Attributes set on finish:
gen_ai.response.finish_reasons: array of finish reasonsgen_ai.response.id: the response ID from the providergen_ai.response.model: the model that generated the response (may differ from the requested model)gen_ai.usage.input_tokens: input tokens used in this stepgen_ai.usage.output_tokens: output tokens used in this stepgen_ai.usage.cache_read.input_tokens: cached input tokens readgen_ai.usage.cache_creation.input_tokens: cached input tokens createdgen_ai.client.operation.duration: provider call duration, in secondsgen_ai.client.operation.time_to_first_chunk: time to the first streamed output chunk, in seconds (streaming calls only)gen_ai.client.operation.time_per_output_chunk: average time between streamed output chunks, in seconds (streaming calls with multiple output chunks only)gen_ai.output.messages: the output in GenAI SemConv message format (whenrecordOutputsis enabled)
-
execute_tool {toolName}(tool span,INTERNAL): one span per tool execution, nested under the step span. See GenAI tool call spans for details.
Deprecated object APIs (generateObject / streamObject)
generateObject and streamObject are deprecated. Use generateText and
streamText with the output property instead.
The deprecated object APIs emit the same span hierarchy as generateText/streamText with these additional attributes on the root span:
gen_ai.output.type:"json"
The step spans also include gen_ai.output.type: "json", and gen_ai.output.messages contains the generated object as a text part.
embed / embedMany
For embed and embedMany, the integration records spans with CLIENT kind:
-
embeddings {modelId}(root span): covers the full embedding operation.Initial attributes:
gen_ai.operation.name:"embeddings"gen_ai.provider.name: the providergen_ai.request.model: the requested model ID
Attributes set on finish:
gen_ai.usage.input_tokens: the number of tokens used
-
embeddings {modelId}(inner span,embedManyonly): one span per provider batch call, nested under the root span.Initial attributes:
gen_ai.operation.name:"embeddings"gen_ai.provider.name: the providergen_ai.request.model: the model ID
Attributes set on finish:
gen_ai.usage.input_tokens: the number of tokens used
rerank
For rerank, the integration records spans with CLIENT kind:
-
rerank {modelId}(root span): covers the full rerank operation.Initial attributes:
gen_ai.operation.name:"rerank"gen_ai.provider.name: the providergen_ai.request.model: the requested model ID
-
rerank {modelId}(inner span): one span per provider rerank call, nested under the root span.Initial attributes:
gen_ai.operation.name:"rerank"gen_ai.provider.name: the providergen_ai.request.model: the model ID
GenAI span details
GenAI message format
The gen_ai.input.messages and gen_ai.output.messages attributes follow the OpenTelemetry GenAI Semantic Conventions message format.
Messages are JSON arrays of objects with a role and a parts array. Each part has a type and type-specific fields:
text:{ type: "text", content: "..." }reasoning:{ type: "reasoning", content: "..." }tool_call:{ type: "tool_call", id: "...", name: "...", arguments: ... }tool_call_response:{ type: "tool_call_response", id: "...", response: ... }blob:{ type: "blob", modality: "image"|"video"|"audio", mime_type: "...", content: "..." }(base64-encoded)uri:{ type: "uri", modality: "image"|"video"|"audio", mime_type: "...", uri: "..." }(for URL-based files)
Output messages also include a finish_reason field (e.g. "stop", "tool_call", "length", "content_filter").
System instructions are recorded separately in gen_ai.system_instructions as a JSON array of { type: "text", content: "..." } parts.
GenAI tool call spans
Tool call spans (execute_tool {toolName}) are nested under the step span and contain:
gen_ai.operation.name:"execute_tool"gen_ai.tool.name: the name of the toolgen_ai.tool.call.id: the tool call IDgen_ai.tool.type:"function"gen_ai.tool.call.arguments: the input arguments (stringified JSON, whenrecordInputsis enabled)gen_ai.execute_tool.duration: the tool execution duration, in secondsgen_ai.tool.call.result: the output result (stringified JSON, whenrecordOutputsis enabled). Only set when the tool call succeeds.
Custom OpenTelemetry span attributes
Use enrichSpan to add custom attributes to spans created by the
OpenTelemetry integration. This is useful when an observability backend needs
vendor-specific attributes that are not AI SDK-owned semantics.
import { registerTelemetry } from 'ai';import { OpenTelemetry } from '@ai-sdk/otel';
registerTelemetry( new OpenTelemetry({ enrichSpan: ({ spanType, operationId, callId, runtimeContext }) => { return { ...getCustomAttributes(runtimeContext, spanType), 'my_app.operation_id': operationId, 'my_app.call_id': callId, }; }, }),);The callback runs when each span is created and receives:
spanType: the type of span being created (operation,step,languageModel,tool,embedding, orreranking).operationId: the AI SDK operation ID for the current call, such asai.generateTextorai.streamText.callId: the unique ID for the current AI SDK call.runtimeContext: the telemetry-filtered runtime context for text generation spans, including updates fromprepareStep.
Custom attributes are merged with AI SDK attributes on the span. AI SDK-owned attributes take precedence when a custom attribute uses the same key.
sensitiveRuntimeContext is applied before telemetry integrations receive
runtimeContext, so custom span enrichment does not receive top-level runtime
context properties marked as sensitive.
Supplemental AI SDK attributes on OpenTelemetry spans
The GenAI semantic conventions cover the core model, prompt, response, tool call, and usage data. You can opt into additional AI SDK-specific attributes for data that is not represented by GenAI semantics:
import { registerTelemetry } from 'ai';import { OpenTelemetry } from '@ai-sdk/otel';
registerTelemetry( new OpenTelemetry({ usage: true, providerMetadata: true, runtimeContext: true, }),);This does not create additional AI SDK-specific spans such as ai.generateText, ai.generateText.doGenerate, or ai.toolCall. Instead, it adds only the selected supplemental attributes to the spans emitted by OpenTelemetry, such as invoke_agent {modelId}, step {n}, chat {modelId}, and execute_tool {toolName}.
All supplemental attributes are disabled by default. Enable only the data you want to collect:
registerTelemetry( new OpenTelemetry({ usage: true, providerMetadata: true, embedding: true, reranking: true, runtimeContext: true, headers: true, toolChoice: true, schema: true, }),);The available options are:
usage: detailed usage attributes that are not covered by GenAI usage attributes, such as uncached input tokens and output text/reasoning token details.providerMetadata:ai.response.providerMetadata.embedding: embedding inputs and outputs.reranking: rerank input documents and ranking output.runtimeContext:ai.settings.context.*.headers:ai.request.headers.*.toolChoice:ai.prompt.toolChoice.schema: object generation schema and output mode attributes.
The recordInputs and recordOutputs telemetry options are still respected for supplemental input and output attributes.
Legacy AI SDK Spans (LegacyOpenTelemetry)
The LegacyOpenTelemetry integration emits spans using AI SDK-specific ai.* prefixed attributes.
This is the legacy format. Consider migrating to the OpenTelemetry for better compatibility with observability platforms.
generateText function
generateText records 3 types of spans:
-
ai.generateText(span): the full length of the generateText call. It contains 1 or moreai.generateText.doGeneratespans. It contains the basic LLM span information and the following attributes:operation.name:ai.generateTextand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.generateText"ai.prompt: the prompt that was used when callinggenerateTextai.response.text: the text that was generatedai.response.toolCalls: the tool calls that were made as part of the generation (stringified JSON)ai.response.finishReason: the reason why the generation finishedai.settings.maxOutputTokens: the maximum number of output tokens that were set
-
ai.generateText.doGenerate(span): a provider doGenerate call. It can containai.toolCallspans. It contains the call LLM span information and the following attributes:operation.name:ai.generateText.doGenerateand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.generateText.doGenerate"ai.prompt.messages: the messages that were passed into the providerai.prompt.tools: array of stringified tool definitions. The serialized tools can be of typefunctionorprovider. Function tools includeFunctionToolandDynamicTooldefinitions and have aname,description(optional), andinputSchema(JSON schema). Provider tools includeProviderDefinedToolandProviderExecutedTooldefinitions and have aname,id, andargs(Record).ai.prompt.toolChoice: the stringified tool choice setting (JSON). It has atypeproperty (auto,none,required,tool), and if the type istool, atoolNameproperty with the specific tool.ai.response.text: the text that was generatedai.response.toolCalls: the tool calls that were made as part of the generation (stringified JSON)ai.response.finishReason: the reason why the generation finished
-
ai.toolCall(span): a tool call that is made as part of the generateText call. See Legacy tool call spans for more details.
streamText function
streamText records 3 types of spans and 2 types of events:
-
ai.streamText(span): the full length of the streamText call. It contains aai.streamText.doStreamspan. It contains the basic LLM span information and the following attributes:operation.name:ai.streamTextand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.streamText"ai.prompt: the prompt that was used when callingstreamTextai.response.text: the text that was generatedai.response.toolCalls: the tool calls that were made as part of the generation (stringified JSON)ai.response.finishReason: the reason why the generation finishedai.settings.maxOutputTokens: the maximum number of output tokens that were set
-
ai.streamText.doStream(span): a provider doStream call. This span contains anai.stream.firstChunkevent andai.toolCallspans. It contains the call LLM span information and the following attributes:operation.name:ai.streamText.doStreamand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.streamText.doStream"ai.prompt.messages: the messages that were passed into the providerai.prompt.tools: array of stringified tool definitions. The serialized tools can be of typefunctionorprovider. Function tools includeFunctionToolandDynamicTooldefinitions and have aname,description(optional), andinputSchema(JSON schema). Provider tools includeProviderDefinedToolandProviderExecutedTooldefinitions and have aname,id, andargs(Record).ai.prompt.toolChoice: the stringified tool choice setting (JSON). It has atypeproperty (auto,none,required,tool), and if the type istool, atoolNameproperty with the specific tool.ai.response.text: the text that was generatedai.response.toolCalls: the tool calls that were made as part of the generation (stringified JSON)ai.response.msToFirstChunk: the time it took to receive the first chunk in millisecondsai.response.msToFinish: the time it took to receive the finish part of the LLM stream in millisecondsai.response.avgCompletionTokensPerSecond: the average number of completion tokens per secondai.response.finishReason: the reason why the generation finished
-
ai.toolCall(span): a tool call that is made as part of the streamText call. See Legacy tool call spans for more details. -
ai.stream.firstChunk(event): an event that is emitted when the first chunk of the stream is received.ai.response.msToFirstChunk: the time it took to receive the first chunk
-
ai.stream.finish(event): an event that is emitted when the finish part of the LLM stream is received.
Deprecated object APIs
generateObject and streamObject are deprecated. Use generateText and
streamText with the output property instead.
If you still run deprecated object APIs, you will see legacy span names:
generateObject:ai.generateObject,ai.generateObject.doGeneratestreamObject:ai.streamObject,ai.streamObject.doStream,ai.stream.firstChunk
Legacy object spans include the same core metadata as other LLM spans, plus
object-specific attributes such as ai.schema.*, ai.response.object, and
ai.settings.output.
embed function
embed records 2 types of spans:
-
ai.embed(span): the full length of the embed call. It contains 1ai.embed.doEmbedspans. It contains the basic embedding span information and the following attributes:operation.name:ai.embedand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.embed"ai.value: the value that was passed into theembedfunctionai.embedding: a JSON-stringified embedding
-
ai.embed.doEmbed(span): a provider doEmbed call. It contains the basic embedding span information and the following attributes:operation.name:ai.embed.doEmbedand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.embed.doEmbed"ai.values: the values that were passed into the provider (array)ai.embeddings: an array of JSON-stringified embeddings
embedMany function
embedMany records 2 types of spans:
-
ai.embedMany(span): the full length of the embedMany call. It contains 1 or moreai.embedMany.doEmbedspans. It contains the basic embedding span information and the following attributes:operation.name:ai.embedManyand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.embedMany"ai.values: the values that were passed into theembedManyfunctionai.embeddings: an array of JSON-stringified embedding
-
ai.embedMany.doEmbed(span): a provider doEmbed call. It contains the basic embedding span information and the following attributes:operation.name:ai.embedMany.doEmbedand the functionId that was set throughtelemetry.functionIdai.operationId:"ai.embedMany.doEmbed"ai.values: the values that were sent to the providerai.embeddings: an array of JSON-stringified embeddings for each value
Legacy span details
Basic LLM span information
Many spans that use LLMs (ai.generateText, ai.generateText.doGenerate, ai.streamText, ai.streamText.doStream) contain the following attributes:
resource.name: the functionId that was set throughtelemetry.functionIdai.model.id: the id of the modelai.model.provider: the provider of the modelai.request.headers.*: the request headers that were passed in throughheadersai.response.providerMetadata: provider specific metadata returned with the generation responseai.settings.maxRetries: the maximum number of retries that were setai.telemetry.functionId: the functionId that was set throughtelemetry.functionIdai.settings.runtimeContext.*: the runtime context that was passed in through theruntimeContextoption, filtered to top-level properties marked withtelemetry.includeRuntimeContextwhen configuredai.usage.completionTokens: the number of completion tokens that were usedai.usage.promptTokens: the number of prompt tokens that were used
Call LLM span information
Spans that correspond to individual LLM calls (ai.generateText.doGenerate, ai.streamText.doStream) contain
basic LLM span information and the following attributes:
ai.response.model: the model that was used to generate the response. This can be different from the model that was requested if the provider supports aliases.ai.response.id: the id of the response. Uses the ID from the provider when available.ai.response.timestamp: the timestamp of the response. Uses the timestamp from the provider when available.- Semantic Conventions for GenAI operations
gen_ai.system: the provider that was usedgen_ai.request.model: the model that was requestedgen_ai.request.temperature: the temperature that was setgen_ai.request.max_tokens: the maximum number of tokens that were setgen_ai.request.frequency_penalty: the frequency penalty that was setgen_ai.request.presence_penalty: the presence penalty that was setgen_ai.request.top_k: the topK parameter value that was setgen_ai.request.top_p: the topP parameter value that was setgen_ai.request.stop_sequences: the stop sequencesgen_ai.response.finish_reasons: the finish reasons that were returned by the providergen_ai.response.model: the model that was used to generate the response. This can be different from the model that was requested if the provider supports aliases.gen_ai.response.id: the id of the response. Uses the ID from the provider when available.gen_ai.usage.input_tokens: the number of prompt tokens that were usedgen_ai.usage.output_tokens: the number of completion tokens that were used
Basic embedding span information
Many spans that use embedding models (ai.embed, ai.embed.doEmbed, ai.embedMany, ai.embedMany.doEmbed) contain the following attributes:
ai.model.id: the id of the modelai.model.provider: the provider of the modelai.request.headers.*: the request headers that were passed in throughheadersai.settings.maxRetries: the maximum number of retries that were setai.telemetry.functionId: the functionId that was set throughtelemetry.functionIdai.settings.runtimeContext.*: the runtime context that was passed in through theruntimeContextoptionai.usage.tokens: the number of tokens that were usedresource.name: the functionId that was set throughtelemetry.functionId
Legacy tool call spans
Tool call spans (ai.toolCall) contain the following attributes:
operation.name:"ai.toolCall"ai.operationId:"ai.toolCall"ai.toolCall.name: the name of the toolai.toolCall.id: the id of the tool callai.toolCall.args: the input parameters of the tool callai.toolCall.result: the output result of the tool call. Only available if the tool call is successful and the result is serializable.