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

# 使用 Vercel AI SDK 进行追踪（旧版）

<Warning>
  本页记录了追踪 AI SDK 运行的旧方法。如需更简单且通用的方法（无需设置 OTEL），请参阅[新指南](/langsmith/trace-with-vercel-ai-sdk)。
</Warning>

您可以使用 LangSmith 通过 OpenTelemetry (OTEL) 追踪来自 Vercel AI SDK 的运行。本指南将通过一个示例进行说明。

<Note>
  JavaScript 中许多流行的 [OpenTelemetry 实现](https://www.npmjs.com/package/@opentelemetry/sdk-node) 目前仍处于实验阶段，
  在生产环境中可能表现不稳定，尤其是在将 LangSmith 与其他提供商一起进行检测时。如果您使用的是 AI SDK 5，
  我们强烈建议使用[我们推荐的追踪 AI SDK 运行的方法](/langsmith/trace-with-vercel-ai-sdk)。
</Note>

## 0. 安装

安装 Vercel AI SDK 和所需的 OTEL 包。下面的代码片段使用了他们的 OpenAI 集成，但您也可以使用他们的任何其他选项。

<CodeGroup>
  ```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  npm install ai @ai-sdk/openai zod
  ```

  ```bash yarn theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  yarn add ai @ai-sdk/openai zod
  ```

  ```bash pnpm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  pnpm add ai @ai-sdk/openai zod
  ```
</CodeGroup>

<CodeGroup>
  ```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  npm install @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-proto @opentelemetry/context-async-hooks
  ```

  ```bash yarn theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  yarn add @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-proto @opentelemetry/context-async-hooks
  ```

  ```bash pnpm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  pnpm add @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-proto @opentelemetry/context-async-hooks
  ```
</CodeGroup>

## 1. 配置您的环境

```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=<your-api-key>
export LANGSMITH_OTEL_ENABLED=true

# 此示例使用 OpenAI，但您可以使用任何选择的 LLM 提供商
export OPENAI_API_KEY=<your-openai-api-key>
```

## 2. 记录追踪

### Node.js

要开始追踪，您需要在代码开头导入并调用 `initializeOTEL` 方法：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { initializeOTEL } from "langsmith/experimental/otel/setup";

const { DEFAULT_LANGSMITH_SPAN_PROCESSOR } = initializeOTEL();
```

之后，在您想要追踪的 AI SDK 调用中添加 `experimental_telemetry` 参数。

<Info>
  请不要忘记在应用程序关闭前调用 `await DEFAULT_LANGSMITH_SPAN_PROCESSOR.shutdown();`，以便将任何剩余的追踪刷新到 LangSmith。
</Info>

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

let result;
try {
  result = await generateText({
    model: openai("gpt-5.4-nano"),
    prompt: "Write a vegetarian lasagna recipe for 4 people.",
    experimental_telemetry: {
      isEnabled: true,
    },
  });
} finally {
  await DEFAULT_LANGSMITH_SPAN_PROCESSOR.shutdown();
}
```

您应该在 LangSmith 仪表板中看到一个[像这样的追踪](https://smith.langchain.com/public/21d33490-d522-4928-a944-a09e988d539c/r)。

您也可以追踪带有工具调用的运行：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

await generateText({
  model: openai("gpt-5.4-nano"),
  messages: [
    {
      role: "user",
      content: "What are my orders and where are they? My user ID is 123",
    },
  ],
  tools: {
    listOrders: tool({
      description: "list all orders",
      parameters: z.object({ userId: z.string() }),
      execute: async ({ userId }) =>
        `User ${userId} has the following orders: 1`,
    }),
    viewTrackingInformation: tool({
      description: "view tracking information for a specific order",
      parameters: z.object({ orderId: z.string() }),
      execute: async ({ orderId }) =>
        `Here is the tracking information for ${orderId}`,
    }),
  },
  experimental_telemetry: {
    isEnabled: true,
  },
  maxSteps: 10,
});
```

这将产生一个[像这样的追踪](https://smith.langchain.com/public/e6122734-2762-4ae0-986b-0cbe4d68692f/r)。

### 使用 `traceable`

您可以在 AI SDK 工具调用周围或内部包装 `traceable` 调用。如果您这样做，我们建议您初始化一个 LangSmith `client` 实例，并将其传递给每个 `traceable`，然后调用 `client.awaitPendingTraceBatches();` 以确保所有追踪被刷新。如果您这样做，就不需要手动调用 `DEFAULT_LANGSMITH_SPAN_PROCESSOR` 上的 `shutdown()` 或 `forceFlush()`。以下是一个示例：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { initializeOTEL } from "langsmith/experimental/otel/setup";

initializeOTEL();

import { Client } from "langsmith";
import { traceable } from "langsmith/traceable";
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

const client = new Client();

const wrappedText = traceable(
  async (content: string) => {
    const { text } = await generateText({
      model: openai("gpt-5.4-nano"),
      messages: [{ role: "user", content }],
      tools: {
        listOrders: tool({
          description: "list all orders",
          parameters: z.object({ userId: z.string() }),
          execute: async ({ userId }) => {
            const getOrderNumber = traceable(
              async () => {
                return "1234";
              },
              { name: "getOrderNumber" }
            );
            const orderNumber = await getOrderNumber();
            return `User ${userId} has the following order: ${orderNumber}`;
          },
        }),
      },
      experimental_telemetry: {
        isEnabled: true,
      },
      maxSteps: 10,
    });
    return { text };
  },
  { name: "parentTraceable", client }
);

let result;
try {
  result = await wrappedText("What are my orders?");
} finally {
  await client.awaitPendingTraceBatches();
}
```

生成的追踪将[看起来像这样](https://smith.langchain.com/public/296a0134-f3d4-4e54-afc7-b18f2c190911/r)。

### Next.js

首先，安装 [`@vercel/otel`](https://www.npmjs.com/package/@vercel/otel) 包：

<CodeGroup>
  ```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  npm install @vercel/otel
  ```

  ```bash yarn theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  yarn add @vercel/otel
  ```

  ```bash pnpm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
  pnpm add @vercel/otel
  ```
</CodeGroup>

然后，在您的根目录中设置一个 [`instrumentation.ts`](https://nextjs.org/docs/app/guides/instrumentation) 文件。
调用 `initializeOTEL` 并将生成的 `DEFAULT_LANGSMITH_SPAN_PROCESSOR` 传递到 `registerOTEL(...)` 调用的 `spanProcessors` 字段中。
它应该看起来像这样：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { registerOTel } from "@vercel/otel";
import { initializeOTEL } from "langsmith/experimental/otel/setup";

const { DEFAULT_LANGSMITH_SPAN_PROCESSOR } = initializeOTEL({});

export function register() {
  registerOTel({
    serviceName: "your-project-name",
    spanProcessors: [DEFAULT_LANGSMITH_SPAN_PROCESSOR],
  });
}
```

最后，在您的 API 路由中，也调用 `initializeOTEL` 并在您的 AI SDK 调用中添加 `experimental_telemetry` 字段：

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

import { initializeOTEL } from "langsmith/experimental/otel/setup";

initializeOTEL();

export async function GET() {
  const { text } = await generateText({
    model: openai("gpt-5.4-nano"),
    messages: [{ role: "user", content: "Why is the sky blue?" }],
    experimental_telemetry: {
      isEnabled: true,
    },
  });

  return new Response(text);
}
```

您也可以将代码的某些部分包装在 `traceables` 中以获得更细粒度的追踪。

### Sentry

如果您使用的是 Sentry，您可以将 LangSmith 追踪导出器附加到 Sentry 的默认 OpenTelemetry 检测中，如下例所示。

<Warning>
  在撰写本文时，Sentry 仅支持 OTEL v1 包。LangSmith 支持 v1 和 v2，但您**必须**确保安装 OTEL v1 包才能使检测正常工作。

  <CodeGroup>
    ```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    npm install @opentelemetry/sdk-trace-base@1.30.1 @opentelemetry/exporter-trace-otlp-proto@0.57.2 @opentelemetry/context-async-hooks@1.30.1
    ```

    ```bash yarn theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    yarn add @opentelemetry/sdk-trace-base@1.30.1 @opentelemetry/exporter-trace-otlp-proto@0.57.2 @opentelemetry/context-async-hooks@1.30.1
    ```

    ```bash pnpm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    pnpm add @opentelemetry/sdk-trace-base@1.30.1 @opentelemetry/exporter-trace-otlp-proto@0.57.2 @opentelemetry/context-async-hooks@1.30.1
    ```
  </CodeGroup>
</Warning>

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { initializeOTEL } from "langsmith/experimental/otel/setup";
import { LangSmithOTLPTraceExporter } from "langsmith/experimental/otel/exporter";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { traceable } from "langsmith/traceable";
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";
import * as Sentry from "@sentry/node";
import { Client } from "langsmith";

const exporter = new LangSmithOTLPTraceExporter();
const spanProcessor = new BatchSpanProcessor(exporter);

const sentry = Sentry.init({
  dsn: "...",
  tracesSampleRate: 1.0,
  openTelemetrySpanProcessors: [spanProcessor],
});

initializeOTEL({
  globalTracerProvider: sentry?.traceProvider,
});

const wrappedText = traceable(
  async (content: string) => {
    const { text } = await generateText({
      model: openai("gpt-5.4-nano"),
      messages: [{ role: "user", content }],
      experimental_telemetry: {
        isEnabled: true,
      },
      maxSteps: 10,
    });
    return { text };
  },
  { name: "parentTraceable" }
);

let result;
try {
  result = await wrappedText("What color is the sky?");
} finally {
  await sentry?.traceProvider?.shutdown();
}
```

## 添加其他元数据

您可以向追踪添加其他元数据，以帮助在 LangSmith UI 中组织和筛选它们：

```typescript {highlight={9}} theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

await generateText({
  model: openai("gpt-5.4-nano"),
  prompt: "Write a vegetarian lasagna recipe for 4 people.",
  experimental_telemetry: {
    isEnabled: true,
    metadata: { userId: "123", language: "english" },
  },
});
```

元数据将在您的 LangSmith 仪表板中可见，并可用于筛选和搜索特定追踪。
请注意，AI SDK 也会在内部子 span 上传播元数据。

## 自定义运行名称

您可以通过在 `experimental_telemetry` 中传递名为 `ls_run_name` 的元数据键来自定义运行名称。

```typescript theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

await generateText({
  model: openai("gpt-5.4-mini"),
  prompt: "Write a vegetarian lasagna recipe for 4 people.",
  experimental_telemetry: {
    isEnabled: true,
    // highlight-start
    metadata: {
      ls_run_name: "my-custom-run-name",
    },
    // highlight-end
  },
});
```

***

<div className="source-links">
  <Callout icon="terminal-2">
    [将这些文档](/use-these-docs)通过 MCP 连接到 Claude、VSCode 等，以获取实时答案。
  </Callout>

  <Callout icon="edit">
    [在 GitHub 上编辑此页面](https://github.com/langchain-ai/docs/edit/main/src/langsmith/legacy-trace-with-vercel-ai-sdk.mdx) 或 [提交问题](https://github.com/langchain-ai/docs/issues/new/choose)。
  </Callout>
</div>
