安装
安装 Vercel AI SDK、一个模型提供者包和 LangSmith。本指南的以下代码片段使用 Vercel 的 OpenAI 集成,但您可以使用任何其他 Vercel AI SDK 提供者。- AI SDK v7
- AI SDK v5 和 v6
LangSmithTelemetry 需要 AI SDK v7,并且可在 langsmith>=0.7.2 中使用。npm install ai @ai-sdk/openai zod langsmith
yarn add ai @ai-sdk/openai zod langsmith
pnpm add ai @ai-sdk/openai zod langsmith
wrapAISDK 支持 AI SDK v6,并且需要 langsmith>=0.3.63。如果您使用的是较旧版本的 AI SDK 或 langsmith,请参考基于 OpenTelemetry (OTEL) 的方法。npm install ai @ai-sdk/openai zod langsmith
yarn add ai @ai-sdk/openai zod langsmith
pnpm add ai @ai-sdk/openai zod langsmith
环境配置
Shell
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>
基本设置
- AI SDK v7
- AI SDK v5 和 v6
注册一次 您应该会在 LangSmith 仪表板中看到一个跟踪,像这个一样。您还可以跟踪带有工具调用的运行:这将产生一个类似这个的跟踪。
LangSmithTelemetry,然后像往常一样使用 AI SDK 方法。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: "为4人份写一份素食千层面食谱。",
});
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: "我的订单是什么?在哪里?我的用户ID是123",
},
],
tools: {
listOrders: tool({
description: "列出所有订单",
inputSchema: z.object({ userId: z.string() }),
execute: async ({ userId }) => `用户 ${userId} 有以下订单:1`,
}),
viewTrackingInformation: tool({
description: "查看特定订单的追踪信息",
inputSchema: z.object({ orderId: z.string() }),
execute: async ({ orderId }) => `这是 ${orderId} 的追踪信息`,
}),
},
stopWhen: stepCountIs(5),
});
使用 您还可以跟踪带有工具调用的运行:
wrapAISDK 包装一次 AI SDK 方法,然后像往常一样调用包装后的方法。import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import { wrapAISDK } from "langsmith/experimental/vercel";
const { generateText } = wrapAISDK(ai);
await generateText({
model: openai("gpt-5.5"),
prompt: "为4人份写一份素食千层面食谱。",
});
import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import { wrapAISDK } from "langsmith/experimental/vercel";
import { z } from "zod";
const { generateText, tool } = wrapAISDK(ai);
await generateText({
model: openai("gpt-5.5"),
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} 的追踪信息`,
}),
},
maxSteps: 5,
});
结合 traceable
您可以将 traceable 调用包装在 AI SDK 调用周围,或者放在 AI SDK 工具调用内部。如果您想在 LangSmith 中对运行进行分组,这很有用。
- AI SDK v7
- AI SDK v5 和 v6
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: "列出所有订单",
inputSchema: z.object({ userId: z.string() }),
execute: async ({ userId }) => `用户 ${userId} 有以下订单:1`,
}),
viewTrackingInformation: tool({
description: "查看特定订单的追踪信息",
inputSchema: z.object({ orderId: z.string() }),
execute: async ({ orderId }) => `这是 ${orderId} 的追踪信息`,
}),
},
stopWhen: stepCountIs(5),
});
return text;
},
{ name: "wrapper" },
);
await wrapper("我的订单是什么?在哪里?我的用户ID是123。");
import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import { wrapAISDK } from "langsmith/experimental/vercel";
import { traceable } from "langsmith/traceable";
import { z } from "zod";
const { generateText, tool } = wrapAISDK(ai);
const wrapper = traceable(
async (input: string) => {
const { text } = await generateText({
model: openai("gpt-5.5"),
messages: [
{
role: "user",
content: input,
},
],
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} 的追踪信息`,
}),
},
maxSteps: 5,
});
return text;
},
{ name: "wrapper" },
);
await wrapper("我的订单是什么?在哪里?我的用户ID是123。");
在无服务器环境中进行跟踪
在无服务器环境中进行跟踪时,请在环境关闭前等待所有运行刷新完毕。- AI SDK v7
- AI SDK v5 和 v6
将 LangSmith
Client 实例传递给 LangSmithTelemetry,然后调用 await client.awaitPendingTraceBatches()。确保也将其传递给您创建的任何 traceable 包装器: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: "列出所有订单",
inputSchema: z.object({ userId: z.string() }),
execute: async ({ userId }) => `用户 ${userId} 有以下订单:1`,
}),
viewTrackingInformation: tool({
description: "查看特定订单的追踪信息",
inputSchema: z.object({ orderId: z.string() }),
execute: async ({ orderId }) => `这是 ${orderId} 的追踪信息`,
}),
},
stopWhen: stepCountIs(5),
telemetry: { integrations: [telemetry] },
});
return text;
},
{
name: "wrapper",
client,
},
);
try {
await wrapper("我的订单是什么?在哪里?我的用户ID是123。");
} finally {
await client.awaitPendingTraceBatches();
}
将 LangSmith
Client 实例传递给 wrapAISDK 和您创建的任何 traceable 包装器,然后调用 await client.awaitPendingTraceBatches():import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import { Client } from "langsmith";
import { wrapAISDK } from "langsmith/experimental/vercel";
import { traceable } from "langsmith/traceable";
import { z } from "zod";
const client = new Client();
const { generateText, tool } = wrapAISDK(ai, { 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: "列出所有订单",
parameters: z.object({ userId: z.string() }),
execute: async ({ userId }) => `用户 ${userId} 有以下订单:1`,
}),
viewTrackingInformation: tool({
description: "查看特定订单的追踪信息",
parameters: z.object({ orderId: z.string() }),
execute: async ({ orderId }) => `这是 ${orderId} 的追踪信息`,
}),
},
maxSteps: 5,
});
return text;
},
{
name: "wrapper",
client,
},
);
try {
await wrapper("我的订单是什么?在哪里?我的用户ID是123。");
} finally {
await client.awaitPendingTraceBatches();
}
Next.js,有一个方便的 after 钩子,您可以在其中放置此逻辑:
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 });
}
传递 LangSmith 配置
您可以传递 LangSmith 特定的配置,例如元数据、运行名称、标签和自定义客户端实例。- AI SDK v7
- AI SDK v5 和 v6
如果您全局注册集成,该配置将应用于未来的 AI SDK 调用:要将配置应用于单个运行,请在该 AI SDK 调用中传递一个遥测集成:
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: "为4人份写一份素食千层面食谱。",
});
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { LangSmithTelemetry } from "langsmith/experimental/vercel";
await generateText({
model: openai("gpt-5.5"),
prompt: "为4人份写一份素食千层面食谱。",
telemetry: {
integrations: [
LangSmithTelemetry({
metadata: { individual_key: "value" },
name: "my_individual_run",
}),
],
},
});
如果您将配置传递给 要将配置应用于单个运行,请在该 AI SDK 调用中传递 LangSmith 提供者选项:
wrapAISDK,该配置将应用于包装后的方法:import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import { wrapAISDK } from "langsmith/experimental/vercel";
const { generateText } = wrapAISDK(ai, {
metadata: { key_for_all_runs: "value" },
tags: ["myrun"],
});
await generateText({
model: openai("gpt-5.5"),
prompt: "为4人份写一份素食千层面食谱。",
});
import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import {
createLangSmithProviderOptions,
wrapAISDK,
} from "langsmith/experimental/vercel";
const { generateText } = wrapAISDK(ai);
await generateText({
model: openai("gpt-5.5"),
prompt: "为4人份写一份素食千层面食谱。",
providerOptions: {
langsmith: createLangSmithProviderOptions<typeof ai.generateText>({
metadata: { individual_key: "value" },
name: "my_individual_run",
}),
},
});
编辑(脱敏)数据
您可以通过指定自定义的输入/输出处理函数来自定义 AI SDK 发送给 LangSmith 的输入和输出内容。如果您处理的是敏感数据,希望避免发送到 LangSmith,这很有用。 因为输出格式取决于您使用的 AI SDK 方法,我们建议为每次 AI SDK 调用单独定义和传递遥测配置。您还需要为 AI SDK 调用内部的子 LLM 运行提供单独的函数,因为顶层的generateText 调用会在内部调用 LLM,并且可能多次调用。
以下是 generateText 的一个示例:
- AI SDK v7
- AI SDK v5 和 v6
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: "法国的首都是哪里?",
telemetry: { integrations: [telemetry] },
});
console.log(text);
import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import {
createLangSmithProviderOptions,
wrapAISDK,
} from "langsmith/experimental/vercel";
const { generateText } = wrapAISDK(ai);
const langsmith = createLangSmithProviderOptions<typeof ai.generateText>({
processInputs: (inputs) => {
return {
messages: inputs.messages?.map((message) => ({
providerMetadata: message.providerOptions,
role: "assistant",
content: "REDACTED",
})),
prompt: "REDACTED",
};
},
processOutputs: () => {
return {
role: "assistant",
content: "REDACTED",
};
},
processChildLLMRunInputs: (inputs) => {
return {
messages: inputs.prompt.map((message) => ({
...message,
content: "REDACTED CHILD INPUTS",
})),
};
},
processChildLLMRunOutputs: () => {
return {
content: "REDACTED CHILD OUTPUTS",
role: "assistant",
};
},
});
const { text } = await generateText({
model: openai("gpt-5.5"),
prompt: "法国的首都是哪里?",
providerOptions: { langsmith },
});
console.log(text);
execute 方法包装在 traceable 中:
- AI SDK v7
- AI SDK v5 和 v6
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: "我的订单是什么?我的用户ID是123。",
},
],
tools: {
listOrders: tool({
description: "列出所有订单",
inputSchema: z.object({ userId: z.string() }),
execute: traceable(
async ({ userId }) => {
return `用户 ${userId} 有以下订单: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();
import { openai } from "@ai-sdk/openai";
import * as ai from "ai";
import { Client } from "langsmith";
import { wrapAISDK } from "langsmith/experimental/vercel";
import { traceable } from "langsmith/traceable";
import { z } from "zod";
const client = new Client();
const { generateText, tool } = wrapAISDK(ai, { client });
await generateText({
model: openai("gpt-5.5"),
messages: [
{
role: "user",
content: "我的订单是什么?我的用户ID是123。",
},
],
tools: {
listOrders: tool({
description: "列出所有订单",
parameters: z.object({ userId: z.string() }),
execute: traceable(
async ({ userId }) => {
return `用户 ${userId} 有以下订单:1`;
},
{
processInputs: () => ({ text: "REDACTED" }),
processOutputs: () => ({ text: "REDACTED" }),
run_type: "tool",
name: "listOrders",
},
) as (input: { userId: string }) => Promise<string>,
}),
},
maxSteps: 5,
});
await client.awaitPendingTraceBatches();
traceable 的返回类型比较复杂,因此需要进行类型转换。如果您希望避免类型转换,也可以省略 AI SDK 的 tool 辅助函数。
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

