# Observability for Vercel AI SDK with Opik

> Start here to integrate Opik into your Vercel AI SDK-based genai application for end-to-end LLM observability, unit testing, and optimization.

## Setup

The AI SDK supports tracing via OpenTelemetry. With the `OpikExporter` you can collect these traces in Opik.
While telemetry is experimental ([docs](https://sdk.vercel.ai/docs/ai-sdk-core/telemetry#enabling-telemetry)), you can enable it by setting `experimental_telemetry` on each request that you want to trace.

```ts
const result = await generateText({
  model: openai("gpt-4o"),
  prompt: "Tell a joke",
  experimental_telemetry: { isEnabled: true },
});
```

To collect the traces in Opik, you need to add the `OpikExporter` to your application, first you have to set your environment variables

```bash filename=".env"
OPIK_API_KEY="<opik-api-key>"
OPIK_URL_OVERRIDE=https://www.comet.com/opik/api # in case you are using the Cloud version
OPIK_PROJECT_NAME="<custom-project-name>"
OPIK_WORKSPACE="<your-workspace>"
OPENAI_API_KEY="<openai-api-key>" # in case you are using an OpenAI model
```

```ts
import { OpikExporter } from "opik-vercel";

new OpikExporter();
```

Now you need to register this exporter via the OpenTelemetry SDK.

### Next.js

Next.js has support for OpenTelemetry instrumentation on the framework level. Learn more about it in the [Next.js OpenTelemetry guide](https://nextjs.org/docs/app/building-your-application/optimizing/open-telemetry).

Install dependencies:

```bash
npm install opik-vercel @vercel/otel @opentelemetry/api-logs @opentelemetry/instrumentation @opentelemetry/sdk-logs
```

Add `OpikExporter` to your instrumentation file:

```ts filename="instrumentation.ts"
import { registerOTel } from "@vercel/otel";
import { OpikExporter } from "opik-vercel";

export function register() {
  registerOTel({
    serviceName: "opik-vercel-ai-nextjs-example",
    traceExporter: new OpikExporter(),
  });
}
```

### Node.js

Install dependencies:

```bash
npm install opik-vercel ai @ai-sdk/openai @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
```

```ts
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OpikExporter } from "opik-vercel";

const sdk = new NodeSDK({
  traceExporter: new OpikExporter(),
  instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start();

async function main() {
  const result = await generateText({
    model: openai("gpt-4o"),
    maxTokens: 50,
    prompt: "What is love?",
    experimental_telemetry: OpikExporter.getSettings({
      name: "opik-nodejs-example",
    }),
  });

  console.log(result.text);

  await sdk.shutdown(); // Flushes the trace to Opik
}

main().catch(console.error);
```

Done! All traces that contain AI SDK spans are automatically captured in Opik.

## Configuration

### Custom Tags and Metadata

You can add custom tags and metadata to all traces generated by the OpikExporter:

```ts
const exporter = new OpikExporter({
  // Optional: add custom tags to all traces
  tags: ["production", "gpt-4o"],
  // Optional: add custom metadata to all traces
  metadata: {
    environment: "production",
    version: "1.0.0",
    team: "ai-team",
  },
  // Optional: associate traces with a conversation thread
  threadId: "conversation-123",
});
```

Tags are useful for filtering and grouping traces, while metadata adds additional context that can be valuable for debugging and analysis. The `threadId` parameter is useful for tracking multi-turn conversations or grouping related AI interactions.

### Pass Custom Trace name

```ts
const result = await generateText({
  model: openai("gpt-4o"),
  prompt: "Tell a joke",
  experimental_telemetry: OpikExporter.getSettings({
    name: "custom-trace-name",
  }),
});
```

### Thread ID Support

You can associate traces with conversation threads by setting the `threadId` parameter. This is useful for tracking multi-turn conversations or grouping related AI interactions.

Set `threadId` per request via telemetry metadata (this overrides any exporter-level `threadId`):

```ts
const result = await generateText({
  model: openai("gpt-4o"),
  prompt: "Continue the conversation",
  experimental_telemetry: OpikExporter.getSettings({
    name: "chat-message",
    metadata: {
      threadId: "conversation-456",
    },
  }),
});
```

## Debugging

Use the logger level to see the more verbose logs of the exporter.

```bash filename=".env"
OPIK_LOG_LEVEL=DEBUG
```