Skip to main content
Vercel AI SDK v7 calls LLMs from TypeScript through helpers like generateText, streamText, and generateObject. Unlike v6 — which wrote OpenTelemetry spans to the global tracer directly — v7 moved telemetry to a pluggable “integrations” model: the SDK emits internal telemetry events, and a registered integration turns them into spans. Vercel ships @ai-sdk/otel as the OpenTelemetry integration. Arize AX then ingests those spans through the @arizeai/openinference-vercel span processor.
If you’re on AI SDK v6 or earlier, use the Vercel AI SDK (v6 and earlier) guide instead — v6 emits OpenTelemetry spans natively and does not need @ai-sdk/otel. The two SDK versions wire telemetry differently, so the setup is not interchangeable.

Prerequisites

  • Node.js 22+ (required by @arizeai/openinference-vercel@3 and @ai-sdk/otel)
  • An Arize AX account (sign up)
  • An OPENAI_API_KEY from the OpenAI Platform
  • Vercel AI SDK 7 (ai@^7)

Launch Arize AX

  1. Sign in to your Arize AX account.
  2. From Space Settings, copy your Space ID and API Key. You will set them as ARIZE_SPACE_ID and ARIZE_API_KEY below.

Install

Install the AI SDK v7, the @ai-sdk/otel telemetry integration, and the OpenInference processor. Pick the tab for your runtime — they differ only in the OpenTelemetry registration helper.
npm install ai@^7 @ai-sdk/openai@^4 @ai-sdk/otel \
  @arizeai/openinference-vercel@^3 \
  @opentelemetry/api \
  @opentelemetry/exporter-trace-otlp-proto \
  @opentelemetry/resources \
  @opentelemetry/sdk-trace-node
@ai-sdk/otel is the piece that makes v7 emit spans at all. Without a registered telemetry integration, experimental_telemetry: { isEnabled: true } enables the SDK’s telemetry events but nothing converts them to OpenTelemetry spans, so nothing reaches Arize.

Configure credentials

export ARIZE_SPACE_ID="<your-space-id>"
export ARIZE_API_KEY="<your-api-key>"
export ARIZE_PROJECT_NAME="vercel-ai-sdk-v7-tracing-example"
export OPENAI_API_KEY="<your-openai-api-key>"

Setup tracing

Register the OpenTelemetry provider and the @ai-sdk/otel integration in one startup file. registerTelemetry(new OpenTelemetry()) (from ai and @ai-sdk/otel) installs the integration globally, so individual generateText/streamText calls only need the experimental_telemetry: { isEnabled: true } opt-in. Pick the tab that matches your runtime. The processor’s spanFilter and reparentOrphanedSpans options control which spans reach Arize and how each trace is rooted — see Span filter.
// instrumentation.ts
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { resourceFromAttributes } from "@opentelemetry/resources";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import {
  isOpenInferenceSpan,
  OpenInferenceSimpleSpanProcessor,
} from "@arizeai/openinference-vercel";
import { registerTelemetry } from "ai";
import { OpenTelemetry } from "@ai-sdk/otel";

const projectName =
  process.env.ARIZE_PROJECT_NAME ?? "vercel-ai-sdk-v7-tracing-example";

export const provider = new NodeTracerProvider({
  resource: resourceFromAttributes({
    model_id: projectName,
    model_version: "1.0.0",
  }),
  spanProcessors: [
    new OpenInferenceSimpleSpanProcessor({
      exporter: new OTLPTraceExporter({
        url: "https://otlp.arize.com/v1/traces",
        headers: {
          "arize-space-id": process.env.ARIZE_SPACE_ID ?? "",
          "arize-api-key": process.env.ARIZE_API_KEY ?? "",
        },
      }),
      spanFilter: isOpenInferenceSpan,
      reparentOrphanedSpans: true,
    }),
  ],
});

provider.register();

// v7: bridge the AI SDK's telemetry events to OpenTelemetry spans. Register
// once, globally — `experimental_telemetry: { isEnabled: true }` on each call
// is then all that's needed.
registerTelemetry(new OpenTelemetry());

console.log("Arize AX tracing initialized for Vercel AI SDK v7.");

Run Vercel AI SDK

// example.ts

// Importing instrumentation first ensures the OTel provider and the
// @ai-sdk/otel integration are registered before the AI SDK is used.
import { provider } from "./instrumentation";

import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

// `experimental_telemetry: { isEnabled: true }` opts this call into the AI
// SDK's telemetry; the integration registered in instrumentation.ts turns
// those events into OpenTelemetry spans.
const { text } = await generateText({
  model: openai("gpt-5.5"),
  prompt: "Why is the ocean salty? Answer in two sentences.",
  experimental_telemetry: { isEnabled: true },
});

console.log(text);

// Flush any pending spans before the process exits.
await provider.forceFlush();
This is a standalone Node script. In Next.js, you don’t import provider or call forceFlush() — the root instrumentation.ts registers tracing automatically. Just add experimental_telemetry: { isEnabled: true } to the generateText/streamText calls inside your route handlers or server actions.

Expected output

Arize AX tracing initialized for Vercel AI SDK v7.
The ocean is salty because rivers continuously dissolve mineral salts from rocks and soil and carry them to the sea, where they accumulate over millions of years. Water leaves the ocean through evaporation but the salts remain, steadily concentrating until reaching today's roughly 3.5% salinity.

Verify in Arize AX

  1. Open your Arize AX space and select project vercel-ai-sdk-v7-tracing-example.
  2. Within ~30 seconds you should see a trace for the call. v7 names its spans with the GenAI convention rather than the v6 ai.generateText names — the OpenInference processor classifies them by span kind, which is what you read in the UI:
invoke_agent gpt-5.5   [agent]        the generateText call
  └─ step 1            [llm]          the step
       └─ chat gpt-5.5  [llm]         model request (prompt, response, tokens)
The top agent span carries the call; the chat LLM span holds the prompt, the model’s response, and token usage. Tool calls appear as additional tool spans under the step.
  1. If no traces appear, see Troubleshooting.

Span filter

Other instrumentations registered alongside the AI SDK (@opentelemetry/instrumentation-http, @vercel/otel, Next.js’s built-in tracing) emit POST / GET spans for every fetch, and the AI SDK’s spans nest under those HTTP roots. Two options on the processor control which spans reach Arize and how they’re rooted:
  • spanFilter: isOpenInferenceSpan keeps only the AI spans and drops the rest — the raw HTTP/fetch spans those other instrumentations emit.
  • reparentOrphanedSpans: true re-roots any AI span left orphaned when the filter drops its parent, so the top-level call span becomes a clean trace root instead of pointing at a parent that was never exported.
new OpenInferenceSimpleSpanProcessor({
  exporter,
  spanFilter: isOpenInferenceSpan,
  reparentOrphanedSpans: true, // default: false
});

Troubleshooting

  • No traces in Arize AX. v7 emits no spans unless a telemetry integration is registered — confirm @ai-sdk/otel is installed and registerTelemetry(new OpenTelemetry()) runs in your instrumentation.ts. Each call also needs experimental_telemetry: { isEnabled: true }. Confirm ARIZE_SPACE_ID and ARIZE_API_KEY are set in the same shell, and enable debug logs with export OTEL_LOG_LEVEL=debug.
  • 401 from OpenAI. Verify OPENAI_API_KEY is set and has access to gpt-5.5. Swap openai("gpt-5.5") for a model your key can call.
  • Process exits before spans flush. Always await provider.forceFlush() (or provider.shutdown()) before the process exits, otherwise trailing spans are dropped.
  • Next.js / Vercel runtime. Use @vercel/otel’s registerOTel(...) instead of NodeTracerProvider, and pin versions: @vercel/otel@1.x requires @opentelemetry/* 1.x; @vercel/otel@2.x requires 2.x. Mismatches surface as silent missing traces.
  • AI SDK spans orphaned on the Traces tab. Set reparentOrphanedSpans: true on the processor as shown in Span filter, and confirm @arizeai/openinference-vercel is 3.0.0 or later — stable v7 telemetry support (and the v7-aware reparenting) landed in the v3 major.
  • You want the v6 span names. @ai-sdk/otel also exports a LegacyOpenTelemetry integration that emits the older ai.generateText / ai.generateText.doGenerate span names; register it in place of OpenTelemetry if you have dashboards or evaluators keyed on those names.

Resources

Vercel AI SDK Documentation

@ai-sdk/otel

OpenInference Vercel Span Processor