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.
@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

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.

Run Vercel AI SDK

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

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

Check from the skill, CLI, or SDK

Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.
Install the Arize Skills plugin and let your coding agent check for you:
Then prompt your agent:
Use the arize-trace skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.

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.

Trace decisions

Vercel AI SDK decision models answer typed questions about a shared state instead of generating text. Calls through experimental_decide appear as a CHAIN span for the operation with a child DECISION span for the model call. This support requires ai 7.0.128 or later, @ai-sdk/otel 1.0.128 or later, and @arizeai/openinference-vercel 3.3.0 or later. The setup above enables decision tracing. experimental_decision: true records the decision state, questions, and answers. enrichSpan: enrichSpanWithOpenInference identifies the model-call span so the processor exports the outer operation as CHAIN and the model call as DECISION. The helper is exported by the ESM-only @arizeai/openinference-vercel package, which is already installed above. With the integration configured, call experimental_decide as usual:

Expected output

The CHAIN span carries the state and questions as input and the answers as output. The child DECISION span carries decision.system, decision.provider, decision.request.model_name, decision.model_name, and decision.token_count.input / decision.token_count.output. When the AI SDK reports a response model, the processor records it as decision.response.model_name. In this example, Arize AX recorded gpt-6-luna, matching the requested model. Output token counts are often 0 because the answers are typed values rather than generated tokens. Decision model and usage attributes use decision.* rather than llm.*, so these calls are not included in LLM token and cost reporting. Without experimental_decision: true, the spans include model and token counts but omit the decision input and output. Without enrichSpan, both SDK spans can be exported as DECISION spans.

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 text-generation 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-6.1-sol. Swap openai("gpt-6.1-sol") 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 TracerProvider, 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