Observability for Vercel AI SDK with Opik

Setup

The AI SDK supports tracing via OpenTelemetry. With the OpikExporter you can collect these traces in Opik. While telemetry is experimental (docs), you can enable it by setting experimental_telemetry on each request that you want to trace.

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

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

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
1import { OpikExporter } from "opik-vercel";
2
3new 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.

Install dependencies:

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

Add OpikExporter to your instrumentation file:

filename="instrumentation.ts"
1import { registerOTel } from "@vercel/otel";
2import { OpikExporter } from "opik-vercel";
3
4export function register() {
5 registerOTel({
6 serviceName: "opik-vercel-ai-nextjs-example",
7 traceExporter: new OpikExporter(),
8 });
9}

Node.js

Install dependencies:

$npm install opik-vercel ai @ai-sdk/openai @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node
1import { openai } from "@ai-sdk/openai";
2import { generateText } from "ai";
3import { NodeSDK } from "@opentelemetry/sdk-node";
4import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
5import { OpikExporter } from "opik-vercel";
6
7const sdk = new NodeSDK({
8 traceExporter: new OpikExporter(),
9 instrumentations: [getNodeAutoInstrumentations()],
10});
11
12sdk.start();
13
14async function main() {
15 const result = await generateText({
16 model: openai("gpt-4o"),
17 maxTokens: 50,
18 prompt: "What is love?",
19 experimental_telemetry: OpikExporter.getSettings({
20 name: "opik-nodejs-example",
21 }),
22 });
23
24 console.log(result.text);
25
26 await sdk.shutdown(); // Flushes the trace to Opik
27}
28
29main().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:

1const exporter = new OpikExporter({
2 // Optional: add custom tags to all traces
3 tags: ["production", "gpt-4o"],
4 // Optional: add custom metadata to all traces
5 metadata: {
6 environment: "production",
7 version: "1.0.0",
8 team: "ai-team",
9 },
10 // Optional: associate traces with a conversation thread
11 threadId: "conversation-123",
12});

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

1const result = await generateText({
2 model: openai("gpt-4o"),
3 prompt: "Tell a joke",
4 experimental_telemetry: OpikExporter.getSettings({
5 name: "custom-trace-name",
6 }),
7});

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

1const result = await generateText({
2 model: openai("gpt-4o"),
3 prompt: "Continue the conversation",
4 experimental_telemetry: OpikExporter.getSettings({
5 name: "chat-message",
6 metadata: {
7 threadId: "conversation-456",
8 },
9 }),
10});

Debugging

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

filename=".env"
$OPIK_LOG_LEVEL=DEBUG