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/otel
import { 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:

instrumentation.ts
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:

(event: GenerateTextStartEvent) => void | PromiseLike<void>

onStepStart:

(event: GenerateTextStepStartEvent) => void | PromiseLike<void>

onLanguageModelCallStart:

(event: LanguageModelCallStartEvent) => void | PromiseLike<void>

onLanguageModelCallEnd:

(event: LanguageModelCallEndEvent) => void | PromiseLike<void>

onToolExecutionStart:

(event: ToolExecutionStartEvent) => void | PromiseLike<void>

onToolExecutionEnd:

(event: ToolExecutionEndEvent) => void | PromiseLike<void>

onStepEnd:

(event: GenerateTextStepEndEvent) => void | PromiseLike<void>

onEmbedEnd:

(event: EmbeddingModelCallEndEvent) => void | PromiseLike<void>

onRerankEnd:

(event: RerankingModelCallEndEvent) => void | PromiseLike<void>

onEnd:

(event: GenerateTextEndEvent) => void | PromiseLike<void>

onAbort:

(event: GenerateTextAbortEvent) => void | PromiseLike<void>

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 ID
    • gen_ai.agent.name: the functionId from telemetry settings
    • gen_ai.system_instructions: system instructions formatted as a JSON array of parts (when recordInputs is enabled)
    • gen_ai.input.messages: the input messages in GenAI SemConv message format (when recordInputs is enabled)
    • gen_ai.request.temperature: the temperature setting
    • gen_ai.request.max_tokens: the maximum output tokens
    • gen_ai.request.top_p: the topP setting
    • gen_ai.request.top_k: the topK setting
    • gen_ai.request.frequency_penalty: the frequency penalty
    • gen_ai.request.presence_penalty: the presence penalty
    • gen_ai.request.stop_sequences: the stop sequences
    • gen_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 used
    • gen_ai.usage.output_tokens: the number of output tokens used
    • gen_ai.usage.cache_read.input_tokens: cached input tokens read
    • gen_ai.usage.cache_creation.input_tokens: cached input tokens created
    • gen_ai.output.messages: the output in GenAI SemConv message format (when recordOutputs is 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 provider
    • gen_ai.request.model: the requested model ID
    • gen_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 parameters
    • gen_ai.input.messages: the prompt messages in GenAI SemConv message format (when recordInputs is enabled)
    • gen_ai.tool.definitions: the tool definitions as stringified JSON (when recordInputs is enabled)

    Attributes set on finish:

    • gen_ai.response.finish_reasons: array of finish reasons
    • gen_ai.response.id: the response ID from the provider
    • gen_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 step
    • gen_ai.usage.output_tokens: output tokens used in this step
    • gen_ai.usage.cache_read.input_tokens: cached input tokens read
    • gen_ai.usage.cache_creation.input_tokens: cached input tokens created
    • gen_ai.client.operation.duration: provider call duration, in seconds
    • gen_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 (when recordOutputs is 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 provider
    • gen_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, embedMany only): one span per provider batch call, nested under the root span.

    Initial attributes:

    • gen_ai.operation.name: "embeddings"
    • gen_ai.provider.name: the provider
    • gen_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 provider
    • gen_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 provider
    • gen_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 tool
  • gen_ai.tool.call.id: the tool call ID
  • gen_ai.tool.type: "function"
  • gen_ai.tool.call.arguments: the input arguments (stringified JSON, when recordInputs is enabled)
  • gen_ai.execute_tool.duration: the tool execution duration, in seconds
  • gen_ai.tool.call.result: the output result (stringified JSON, when recordOutputs is 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, or reranking).
  • operationId: the AI SDK operation ID for the current call, such as ai.generateText or ai.streamText.
  • callId: the unique ID for the current AI SDK call.
  • runtimeContext: the telemetry-filtered runtime context for text generation spans, including updates from prepareStep.

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 more ai.generateText.doGenerate spans. It contains the basic LLM span information and the following attributes:

    • operation.name: ai.generateText and the functionId that was set through telemetry.functionId
    • ai.operationId: "ai.generateText"
    • ai.prompt: the prompt that was used when calling generateText
    • ai.response.text: the text that was generated
    • ai.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.settings.maxOutputTokens: the maximum number of output tokens that were set
  • ai.generateText.doGenerate (span): a provider doGenerate call. It can contain ai.toolCall spans. It contains the call LLM span information and the following attributes:

    • operation.name: ai.generateText.doGenerate and the functionId that was set through telemetry.functionId
    • ai.operationId: "ai.generateText.doGenerate"
    • ai.prompt.messages: the messages that were passed into the provider
    • ai.prompt.tools: array of stringified tool definitions. The serialized tools can be of type function or provider. Function tools include FunctionTool and DynamicTool definitions and have a name, description (optional), and inputSchema (JSON schema). Provider tools include ProviderDefinedTool and ProviderExecutedTool definitions and have a name, id, and args (Record).
    • ai.prompt.toolChoice: the stringified tool choice setting (JSON). It has a type property (auto, none, required, tool), and if the type is tool, a toolName property with the specific tool.
    • ai.response.text: the text that was generated
    • ai.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 a ai.streamText.doStream span. It contains the basic LLM span information and the following attributes:

    • operation.name: ai.streamText and the functionId that was set through telemetry.functionId
    • ai.operationId: "ai.streamText"
    • ai.prompt: the prompt that was used when calling streamText
    • ai.response.text: the text that was generated
    • ai.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.settings.maxOutputTokens: the maximum number of output tokens that were set
  • ai.streamText.doStream (span): a provider doStream call. This span contains an ai.stream.firstChunk event and ai.toolCall spans. It contains the call LLM span information and the following attributes:

    • operation.name: ai.streamText.doStream and the functionId that was set through telemetry.functionId
    • ai.operationId: "ai.streamText.doStream"
    • ai.prompt.messages: the messages that were passed into the provider
    • ai.prompt.tools: array of stringified tool definitions. The serialized tools can be of type function or provider. Function tools include FunctionTool and DynamicTool definitions and have a name, description (optional), and inputSchema (JSON schema). Provider tools include ProviderDefinedTool and ProviderExecutedTool definitions and have a name, id, and args (Record).
    • ai.prompt.toolChoice: the stringified tool choice setting (JSON). It has a type property (auto, none, required, tool), and if the type is tool, a toolName property with the specific tool.
    • ai.response.text: the text that was generated
    • ai.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 milliseconds
    • ai.response.msToFinish: the time it took to receive the finish part of the LLM stream in milliseconds
    • ai.response.avgCompletionTokensPerSecond: the average number of completion tokens per second
    • ai.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.doGenerate
  • streamObject: 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 1 ai.embed.doEmbed spans. It contains the basic embedding span information and the following attributes:

    • operation.name: ai.embed and the functionId that was set through telemetry.functionId
    • ai.operationId: "ai.embed"
    • ai.value: the value that was passed into the embed function
    • ai.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.doEmbed and the functionId that was set through telemetry.functionId
    • ai.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 more ai.embedMany.doEmbed spans. It contains the basic embedding span information and the following attributes:

    • operation.name: ai.embedMany and the functionId that was set through telemetry.functionId
    • ai.operationId: "ai.embedMany"
    • ai.values: the values that were passed into the embedMany function
    • ai.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.doEmbed and the functionId that was set through telemetry.functionId
    • ai.operationId: "ai.embedMany.doEmbed"
    • ai.values: the values that were sent to the provider
    • ai.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 through telemetry.functionId
  • ai.model.id: the id of the model
  • ai.model.provider: the provider of the model
  • ai.request.headers.*: the request headers that were passed in through headers
  • ai.response.providerMetadata: provider specific metadata returned with the generation response
  • ai.settings.maxRetries: the maximum number of retries that were set
  • ai.telemetry.functionId: the functionId that was set through telemetry.functionId
  • ai.settings.runtimeContext.*: the runtime context that was passed in through the runtimeContext option, filtered to top-level properties marked with telemetry.includeRuntimeContext when configured
  • ai.usage.completionTokens: the number of completion tokens that were used
  • ai.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 used
    • gen_ai.request.model: the model that was requested
    • gen_ai.request.temperature: the temperature that was set
    • gen_ai.request.max_tokens: the maximum number of tokens that were set
    • gen_ai.request.frequency_penalty: the frequency penalty that was set
    • gen_ai.request.presence_penalty: the presence penalty that was set
    • gen_ai.request.top_k: the topK parameter value that was set
    • gen_ai.request.top_p: the topP parameter value that was set
    • gen_ai.request.stop_sequences: the stop sequences
    • gen_ai.response.finish_reasons: the finish reasons that were returned by the provider
    • gen_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 used
    • gen_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 model
  • ai.model.provider: the provider of the model
  • ai.request.headers.*: the request headers that were passed in through headers
  • ai.settings.maxRetries: the maximum number of retries that were set
  • ai.telemetry.functionId: the functionId that was set through telemetry.functionId
  • ai.settings.runtimeContext.*: the runtime context that was passed in through the runtimeContext option
  • ai.usage.tokens: the number of tokens that were used
  • resource.name: the functionId that was set through telemetry.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 tool
  • ai.toolCall.id: the id of the tool call
  • ai.toolCall.args: the input parameters of the tool call
  • ai.toolCall.result: the output result of the tool call. Only available if the tool call is successful and the result is serializable.