Skip to main content
本文档介绍了一种较旧的 AI SDK 运行追踪方法。如需一种更简单、更通用且无需 OTEL 设置的方法,请参阅新指南
你可以使用 LangSmith 通过 OpenTelemetry (OTEL) 追踪来自 Vercel AI SDK 的运行。本指南将逐步介绍一个示例。
目前,JavaScript 中许多流行的 OpenTelemetry 实现 仍处于实验阶段,在生产环境中可能表现不稳定,尤其是在将 LangSmith 与其他提供程序一起进行检测时。如果你使用的是 AI SDK 5,我们强烈建议使用我们推荐的追踪 AI SDK 运行的方法

0. 安装

安装 Vercel AI SDK 和所需的 OTEL 包。下面的代码片段使用了它们的 OpenAI 集成,但你也可以使用任何其他选项。
npm install ai @ai-sdk/openai zod
npm install @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-proto @opentelemetry/context-async-hooks

1. 配置环境

export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=<你的 API 密钥>
export LANGSMITH_OTEL_ENABLED=true

# 此示例使用 OpenAI,但你可以选择任何 LLM 提供程序
export OPENAI_API_KEY=<你的 OpenAI API 密钥>

2. 记录追踪

Node.js

要开始追踪,你需要在代码开头导入并调用 initializeOTEL 方法:
import { initializeOTEL } from "langsmith/experimental/otel/setup";

const { DEFAULT_LANGSMITH_SPAN_PROCESSOR } = initializeOTEL();
之后,在你想要追踪的 AI SDK 调用中添加 experimental_telemetry 参数。
请勿忘记在应用程序关闭前调用 await DEFAULT_LANGSMITH_SPAN_PROCESSOR.shutdown();,以便将剩余的追踪数据刷新到 LangSmith。
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

let result;
try {
  result = await generateText({
    model: openai("gpt-4.1-nano"),
    prompt: "为 4 个人写一份素食千层面食谱。",
    experimental_telemetry: {
      isEnabled: true,
    },
  });
} finally {
  await DEFAULT_LANGSMITH_SPAN_PROCESSOR.shutdown();
}
你应该能在 LangSmith 仪表板中看到类似此示例的追踪记录。 你也可以追踪包含工具调用的运行:
import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

await generateText({
  model: openai("gpt-4.1-nano"),
  messages: [
    {
      role: "user",
      content: "我的订单有哪些,它们在哪里?我的用户 ID 是 123",
    },
  ],
  tools: {
    listOrders: tool({
      description: "列出所有订单",
      parameters: z.object({ userId: z.string() }),
      execute: async ({ userId }) =>
        `用户 ${userId} 有以下订单:1`,
    }),
    viewTrackingInformation: tool({
      description: "查看特定订单的物流信息",
      parameters: z.object({ orderId: z.string() }),
      execute: async ({ orderId }) =>
        `这是订单 ${orderId} 的物流信息`,
    }),
  },
  experimental_telemetry: {
    isEnabled: true,
  },
  maxSteps: 10,
});
这将生成类似此示例的追踪记录。

使用 traceable

你可以在 AI SDK 工具调用的周围或内部包装 traceable 调用。如果这样做,我们建议你初始化一个 LangSmith client 实例,并将其传递给每个 traceable,然后调用 client.awaitPendingTraceBatches(); 以确保所有追踪数据都被刷新。如果采用此方法,你无需手动调用 DEFAULT_LANGSMITH_SPAN_PROCESSORshutdown()forceFlush()。示例如下:
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-4.1-nano"),
      messages: [{ role: "user", content }],
      tools: {
        listOrders: tool({
          description: "列出所有订单",
          parameters: z.object({ userId: z.string() }),
          execute: async ({ userId }) => {
            const getOrderNumber = traceable(
              async () => {
                return "1234";
              },
              { name: "getOrderNumber" }
            );
            const orderNumber = await getOrderNumber();
            return `用户 ${userId} 有以下订单:${orderNumber}`;
          },
        }),
      },
      experimental_telemetry: {
        isEnabled: true,
      },
      maxSteps: 10,
    });
    return { text };
  },
  { name: "parentTraceable", client }
);

let result;
try {
  result = await wrappedText("我的订单有哪些?");
} finally {
  await client.awaitPendingTraceBatches();
}
生成的追踪记录将类似于此

Next.js

首先,安装 @vercel/otel 包:
npm install @vercel/otel
然后,在你的根目录中设置一个 instrumentation.ts 文件。 调用 initializeOTEL,并将生成的 DEFAULT_LANGSMITH_SPAN_PROCESSOR 传递到 registerOTEL(...) 调用的 spanProcessors 字段中。 代码应类似如下:
import { registerOTel } from "@vercel/otel";
import { initializeOTEL } from "langsmith/experimental/otel/setup";

const { DEFAULT_LANGSMITH_SPAN_PROCESSOR } = initializeOTEL({});

export function register() {
  registerOTel({
    serviceName: "你的项目名称",
    spanProcessors: [DEFAULT_LANGSMITH_SPAN_PROCESSOR],
  });
}
最后,在你的 API 路由中,同样调用 initializeOTEL,并在 AI SDK 调用中添加 experimental_telemetry 字段:
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-4.1-nano"),
    messages: [{ role: "user", content: "天空为什么是蓝色的?" }],
    experimental_telemetry: {
      isEnabled: true,
    },
  });

  return new Response(text);
}
你也可以将部分代码包装在 traceable 中,以实现更细粒度的追踪。

Sentry

如果你使用 Sentry,可以按照以下示例所示,将 LangSmith 追踪导出器附加到 Sentry 的默认 OpenTelemetry 检测中。
截至撰写本文时,Sentry 仅支持 OTEL v1 包。LangSmith 同时支持 v1 和 v2,但你必须确保安装 OTEL v1 包才能使检测正常工作。
npm install @opentelemetry/sdk-trace-base@1.30.1 @opentelemetry/exporter-trace-otlp-proto@0.57.2 @opentelemetry/context-async-hooks@1.30.1
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-4.1-nano"),
      messages: [{ role: "user", content }],
      experimental_telemetry: {
        isEnabled: true,
      },
      maxSteps: 10,
    });
    return { text };
  },
  { name: "parentTraceable" }
);

let result;
try {
  result = await wrappedText("天空是什么颜色的?");
} finally {
  await sentry?.traceProvider?.shutdown();
}

添加其他元数据

你可以向追踪记录中添加其他元数据,以帮助在 LangSmith UI 中组织和筛选它们:
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

await generateText({
  model: openai("gpt-4.1-nano"),
  prompt: "为 4 个人写一份素食千层面食谱。",
  experimental_telemetry: {
    isEnabled: true,
    metadata: { userId: "123", language: "english" },
  },
});
元数据将在你的 LangSmith 仪表板中可见,并可用于筛选和搜索特定的追踪记录。 请注意,AI SDK 会在内部的子跨度中传播元数据。

自定义运行名称

你可以通过将名为 ls_run_name 的元数据键传递到 experimental_telemetry 中来自定义运行名称。
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";

await generateText({
  model: openai("gpt-4.1-mini"),
  prompt: "为 4 个人写一份素食千层面食谱。",
  experimental_telemetry: {
    isEnabled: true,
    // highlight-start
    metadata: {
      ls_run_name: "我的自定义运行名称",
    },
    // highlight-end
  },
});