Skip to content
LangSmith 文档版本 跟随上游 源快照 16a82f4b 更新于 2026-10-18

追踪 Vercel AI SDK 应用(仅 JS/TS)

使用 LangSmith 追踪 Vercel AI SDK 应用,支持 AI SDK v5、v6 和 v7。

你可以使用 LangSmith 追踪 Vercel AI SDK 的运行。本指南展示如何为 AI SDK v5、v6 和 v7 设置追踪。

安装

安装 Vercel AI SDK、模型提供程序包和 LangSmith。本指南的以下代码片段使用 Vercel 的 OpenAI 集成,但你也可以使用任何其他 Vercel AI SDK 提供程序。

NOTE

LangSmithTelemetry 需要 AI SDK v7,并在 langsmith>=0.7.2 中可用。

bash
npm install ai @ai-sdk/openai zod langsmith
bash
yarn add ai @ai-sdk/openai zod langsmith
bash
pnpm add ai @ai-sdk/openai zod langsmith

环境配置

bash
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY=<your-api-key>

# The examples use OpenAI, but you can use any LLM provider of choice
export OPENAI_API_KEY=<your-openai-api-key>

# For LangSmith API keys linked to multiple workspaces, set the LANGSMITH_WORKSPACE_ID environment variable to specify which workspace to use.
export LANGSMITH_WORKSPACE_ID=<your-workspace-id>

基本设置

注册一次 LangSmithTelemetry,然后像平常一样使用 AI SDK 方法。

typescript
import { openai } from "@ai-sdk/openai";
import { generateText, registerTelemetry } from "ai";
import { LangSmithTelemetry } from "langsmith/experimental/vercel";

registerTelemetry(LangSmithTelemetry());

await generateText({
    model: openai("gpt-5.5"),
    prompt: "Write a vegetarian lasagna recipe for 4 people.",
});

你应该会在 LangSmith 仪表板中看到一条类似这样的追踪。

你也可以追踪带工具调用的运行:

typescript
import { openai } from "@ai-sdk/openai";
import { generateText, registerTelemetry, stepCountIs, tool } from "ai";
import { LangSmithTelemetry } from "langsmith/experimental/vercel";
import { z } from "zod";

registerTelemetry(LangSmithTelemetry());

await generateText({
    model: openai("gpt-5.5"),
    messages: [
        {
            role: "user",
            content: "What are my orders and where are they? My user ID is 123",
        },
    ],
    tools: {
        listOrders: tool({
            description: "list all orders",
            inputSchema: 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",
            inputSchema: z.object({ orderId: z.string() }),
            execute: async ({ orderId }) => `Here is the tracking information for ${orderId}`,
        }),
    },
    stopWhen: stepCountIs(5),
});

这会生成一条类似这样的追踪。

你可以完全像平常一样使用其他 AI SDK 方法。

使用 traceable

你可以将 traceable 调用包装在 AI SDK 调用之外,或放在 AI SDK 工具调用内部。如果你想在 LangSmith 中将运行分组在一起,这会很有用。

typescript
import { openai } from "@ai-sdk/openai";
import { generateText, registerTelemetry, stepCountIs, tool } from "ai";
import { LangSmithTelemetry } from "langsmith/experimental/vercel";
import { traceable } from "langsmith/traceable";
import { z } from "zod";

registerTelemetry(LangSmithTelemetry());

const wrapper = traceable(
    async (input: string) => {
        const { text } = await generateText({
            model: openai("gpt-5.5"),
            messages: [
                {
                    role: "user",
                    content: input,
                },
            ],
            tools: {
                listOrders: tool({
                    description: "list all orders",
                    inputSchema: 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",
                    inputSchema: z.object({ orderId: z.string() }),
                    execute: async ({ orderId }) => `Here is the tracking information for ${orderId}`,
                }),
            },
            stopWhen: stepCountIs(5),
        });
        return text;
    },
    { name: "wrapper" },
);

await wrapper("What are my orders and where are they? My user ID is 123.");

生成的追踪将如下所示。

在无服务器环境中追踪

在无服务器环境中进行追踪时,请在你的环境关闭之前等待所有运行完成刷新。

将 LangSmith Client 实例传给 LangSmithTelemetry,然后调用 await client.awaitPendingTraceBatches()。请确保也将其传入你创建的任何 traceable 包装器:

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

const client = new Client();
const telemetry = LangSmithTelemetry({ client });

const wrapper = traceable(
    async (input: string) => {
        const { text } = await generateText({
            model: openai("gpt-5.5"),
            messages: [
                {
                    role: "user",
                    content: input,
                },
            ],
            tools: {
                listOrders: tool({
                    description: "list all orders",
                    inputSchema: 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",
                    inputSchema: z.object({ orderId: z.string() }),
                    execute: async ({ orderId }) => `Here is the tracking information for ${orderId}`,
                }),
            },
            stopWhen: stepCountIs(5),
            telemetry: { integrations: [telemetry] },
        });
        return text;
    },
    {
        name: "wrapper",
        client,
    },
);

try {
    await wrapper("What are my orders and where are they? My user ID is 123.");
} finally {
    await client.awaitPendingTraceBatches();
}

如果你使用 Next.js,有一个方便的 after 钩子,可以把这段逻辑放在那里:

typescript
import { after } from "next/server";
import { Client } from "langsmith";

export async function POST(request: Request) {
    const client = new Client();
    const body = await request.json();

    after(async () => {
        await client.awaitPendingTraceBatches();
    });

    return Response.json({ ok: true, body });
}

详情请参阅在无服务器环境中追踪 JS 函数,包括在无服务器环境中管理速率限制的相关信息。

传递 LangSmith 配置

你可以传入 LangSmith 特有的配置,例如元数据、运行名称、标签和自定义客户端实例。

如果在全局注册该集成,配置会应用于后续的 AI SDK 调用:

typescript
import { openai } from "@ai-sdk/openai";
import { generateText, registerTelemetry } from "ai";
import { LangSmithTelemetry } from "langsmith/experimental/vercel";

registerTelemetry(
    LangSmithTelemetry({
        metadata: { key_for_all_runs: "value" },
        tags: ["myrun"],
    }),
);

await generateText({
    model: openai("gpt-5.5"),
    prompt: "Write a vegetarian lasagna recipe for 4 people.",
});

要将配置应用于单次运行,请在该 AI SDK 调用中传入遥测集成:

typescript
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { LangSmithTelemetry } from "langsmith/experimental/vercel";

await generateText({
    model: openai("gpt-5.5"),
    prompt: "Write a vegetarian lasagna recipe for 4 people.",
    telemetry: {
        integrations: [
            LangSmithTelemetry({
                metadata: { individual_key: "value" },
                name: "my_individual_run",
            }),
        ],
    },
});

编辑数据

你可以通过指定自定义输入/输出处理函数,自定义 AI SDK 发送给 LangSmith 的输入和输出。如果你要处理不希望发送到 LangSmith 的敏感数据,这会很有用。

由于输出格式会因所使用的 AI SDK 方法而异,我们建议在 AI SDK 调用中单独定义并传入遥测配置。你还需要为 AI SDK 调用中的子 LLM 运行提供单独的函数,因为在顶层调用 generateText 会在内部调用 LLM,并且可能多次调用。

以下是 generateText 的示例:

typescript
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { LangSmithTelemetry } from "langsmith/experimental/vercel";

const telemetry = LangSmithTelemetry({
    processInputs: (inputs) => {
        const messages = inputs.messages as Array<Record<string, unknown>> | undefined;
        return {
            messages: messages?.map((message) => ({
                providerMetadata: message.providerOptions,
                role: "assistant",
                content: "REDACTED",
            })),
            prompt: "REDACTED",
        };
    },
    processOutputs: (outputs) => {
        return {
            providerMetadata: outputs.providerMetadata,
            role: "assistant",
            content: "REDACTED",
        };
    },
    processChildLLMRunInputs: (inputs) => {
        const messages = inputs.messages as Array<Record<string, unknown>> | undefined;
        return {
            messages: messages?.map((message) => ({
                ...message,
                content: "REDACTED CHILD INPUTS",
            })),
        };
    },
    processChildLLMRunOutputs: (outputs) => {
        return {
            providerMetadata: outputs.providerMetadata,
            content: "REDACTED CHILD OUTPUTS",
            role: "assistant",
        };
    },
});

const { text } = await generateText({
    model: openai("gpt-5.5"),
    prompt: "What is the capital of France?",
    telemetry: { integrations: [telemetry] },
});

console.log(text);

实际返回值会包含原始的、未编辑的结果,但 LangSmith 中的追踪会经过编辑。

要编辑工具的输入/输出,请像下面这样将你的 execute 方法包装在 traceable 中:

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

const client = new Client();
const telemetry = LangSmithTelemetry({ client });

await generateText({
    model: openai("gpt-5.5"),
    messages: [
        {
            role: "user",
            content: "What are my orders? My user ID is 123.",
        },
    ],
    tools: {
        listOrders: tool({
            description: "list all orders",
            inputSchema: z.object({ userId: z.string() }),
            execute: traceable(
                async ({ userId }) => {
                    return `User ${userId} has the following orders: 1`;
                },
                {
                    processInputs: () => ({ text: "REDACTED" }),
                    processOutputs: () => ({ text: "REDACTED" }),
                    run_type: "tool",
                    name: "listOrders",
                },
            ) as (input: { userId: string }) => Promise<string>,
        }),
    },
    stopWhen: stepCountIs(5),
    telemetry: { integrations: [telemetry] },
});

await client.awaitPendingTraceBatches();

traceable 的返回类型很复杂,因此需要进行类型转换。如果你希望避免类型转换,也可以省略 AI SDK 的 tool 辅助函数。


BytesRouter 是社区翻译站点,所有译文仅供参考,一切以官方英文原文为准。