> ## Documentation Index
> Fetch the complete documentation index at: https://arizeai-433a7140.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Vercel AI SDK Tracing (JS)

> Trace Vercel AI SDK calls with @arizeai/phoenix-otel and send spans to Phoenix for LLM and agent observability.

Phoenix traces [Vercel AI SDK](https://github.com/vercel/ai) (>= 7) applications through the AI SDK's OpenTelemetry integration (`@ai-sdk/otel`). The simplest setup is [`@arizeai/phoenix-otel`](https://www.npmjs.com/package/@arizeai/phoenix-otel), which handles the OpenTelemetry provider, OpenInference span processing, and export to Phoenix in a single `register()` call.

## Version compatibility

| Vercel AI SDK | @arizeai/phoenix-otel | @arizeai/openinference-vercel |
| ------------- | --------------------- | ----------------------------- |
| v7+           | 2.x                   | 3.x                           |
| v6 and older  | 1.x                   | 2.x                           |

AI SDK v7 telemetry requires Node.js 22 or newer.

## Installation

```bash theme={null}
npm i --save ai @ai-sdk/otel @arizeai/phoenix-otel
```

<Warning>
  Ensure your installed version of `@opentelemetry/api` matches the version installed by `@ai-sdk/otel` otherwise the AI SDK will not emit traces to the TracerProvider that you configure. If you install `ai` before the other packages, then dependency resolution in your package manager should install the correct version.
</Warning>

## Setup

Since AI SDK v7, telemetry is emitted once you register a telemetry integration with `registerTelemetry(new OpenTelemetry(...))`. Pair that with `register()` from `@arizeai/phoenix-otel`, which processes the resulting spans and exports them to Phoenix:

```typescript theme={null}
// instrumentation.ts
import { OpenTelemetry } from "@ai-sdk/otel";
import { register } from "@arizeai/phoenix-otel";
import { registerTelemetry } from "ai";

// Handles all the OpenTelemetry setup and exports spans to Phoenix.
// Reads PHOENIX_COLLECTOR_ENDPOINT and PHOENIX_API_KEY from the environment.
export const provider = register({
  projectName: "my-ai-sdk-app",
});

// Point the AI SDK's telemetry at OpenTelemetry. headers: false keeps
// outgoing LLM request headers (which can contain credentials) off of spans.
registerTelemetry(new OpenTelemetry({ headers: false }));
```

Import this file before the rest of your program executes, e.g. `node --import ./instrumentation.ts index.ts`, or `import "./instrumentation.js"` at the top of your application's entrypoint.

Once the telemetry integration is registered, AI SDK calls are traced by default; no per-call configuration is required. Use the `telemetry` option for per-call metadata such as `functionId`, or to opt out with `isEnabled: false`.

```typescript theme={null}
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

const result = await generateText({
  model: openai("gpt-4o"),
  prompt: "Write a short story about a cat.",
  // Optional per-call metadata:
  telemetry: { functionId: "story-agent" },
});
```

This applies to agents as well: a `ToolLoopAgent` run is traced end to end, with the agent, each LLM step, and every tool call captured as spans in a single trace. See the [AI SDK agent example](https://github.com/Arize-ai/phoenix/tree/main/js/examples/apps/ai-sdk-agent) for a complete runnable project.

<Note>
  `register()` uses a batch span processor by default, so spans still queued when a short-lived script exits may not be exported. Call `await provider.shutdown()` before exit to flush them, or pass `batch: false` to `register()` for immediate export.
</Note>

## Next.js

In a Next.js project, register the telemetry integration and `@vercel/otel` from the `register()` function in `instrumentation.ts`, using the OpenInference span processor from [`@arizeai/openinference-vercel`](https://github.com/Arize-ai/openinference/tree/main/js/packages/openinference-vercel), the same processor `@arizeai/phoenix-otel` uses under the hood:

```bash theme={null}
npm i --save @arizeai/openinference-vercel @arizeai/openinference-semantic-conventions @vercel/otel @opentelemetry/api @opentelemetry/exporter-trace-otlp-proto
```

```javascript expandable theme={null}
// instrumentation.ts
// Vercel / Next.js environment instrumentation
import { registerOTel, OTLPHttpProtoTraceExporter } from "@vercel/otel";
import { registerTelemetry } from "ai";
import { OpenTelemetry } from "@ai-sdk/otel";
import {
  isOpenInferenceSpan,
  OpenInferenceSimpleSpanProcessor,
} from "@arizeai/openinference-vercel";
import { SEMRESATTRS_PROJECT_NAME } from "@arizeai/openinference-semantic-conventions";

// e.g. http://localhost:6006
// e.g. https://app.phoenix.arize.com/s/<your-space>
const COLLECTOR_ENDPOINT = process.env.PHOENIX_COLLECTOR_ENDPOINT;
// The project name that may appear in your collector's interface
const SERVICE_NAME = "phoenix-vercel-ai-sdk-app";

/**
 * Register function used by Next.js to instantiate instrumentation
 * correctly in all environments that Next.js can be deployed to
 */
export function register() {
  // Register the AI SDK telemetry integration. Header capture is disabled
  // because request headers can contain credentials.
  registerTelemetry(new OpenTelemetry({ headers: false }));

  registerOTel({
    serviceName: SERVICE_NAME,
    attributes: {
      [SEMRESATTRS_PROJECT_NAME]: SERVICE_NAME,
    },
    spanProcessors: [
      new OpenInferenceSimpleSpanProcessor({
        exporter: new OTLPHttpProtoTraceExporter({
          url: `${COLLECTOR_ENDPOINT}/v1/traces`,
          // (optional) if connecting to a collector with Authentication enabled
          headers: { Authorization: `Bearer ${process.env.PHOENIX_API_KEY}` },
        }),
        spanFilter: isOpenInferenceSpan,
      }),
    ],
  });
}
```

See Vercel's [instrumentation guide](https://nextjs.org/docs/app/guides/open-telemetry#using-vercelotel) for more details on configuring your instrumentation file and `@vercel/otel` within a Next.js project.

<Info>
  When instrumenting a Next.js application, traced spans will not be "root spans" when the OpenInference span filter is configured. This is because Next.js parents spans underneath http requests, which do not meet the requirements to be an OpenInference span.
</Info>

<Frame>
  <iframe src="https://cdn.iframe.ly/ry2U623" width={1000} height={400} allowFullScreen scrolling="no" allow="accelerometer *; clipboard-write *; encrypted-media *; gyroscope *; picture-in-picture *; web-share *;" />
</Frame>

## Examples

* [AI SDK Agent](https://github.com/Arize-ai/phoenix/tree/main/js/examples/apps/ai-sdk-agent): an AI SDK v7 `ToolLoopAgent` traced with `@arizeai/phoenix-otel`
* [Next.js OpenAI Telemetry Example](https://github.com/Arize-ai/openinference/tree/main/js/examples/next-openai-telemetry-app) in the [OpenInference repo](https://github.com/Arize-ai/openinference/tree/main/js)

For details on Vercel AI SDK telemetry see the [Vercel AI SDK Telemetry documentation](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry).
