集成模型服务商OpenAI (JS/TS)

OpenAI SDK (JS/TS) 的可观测性

在找 Python 版本?请查看这里

Langfuse JS/TS SDK 提供了围绕 OpenAI SDK 的包装函数,让你能够轻松为 OpenAI 调用添加可观测性。这包括追踪延迟、流式响应的首 token 时间、错误和模型用量。

import OpenAI from "openai";
import { observeOpenAI } from "@langfuse/openai";
 
const openai = observeOpenAI(new OpenAI());
 
const res = await openai.chat.completions.create({
  messages: [{ role: "system", content: "Tell me a story about a dog." }],
});

Litefuse 会自动追踪:

  • 所有 prompt/completion,并支持流式与函数调用
  • 总延迟和首 token 时间
  • OpenAI API 错误
  • 模型用量(token)和成本(USD)(了解更多

工作原理

安装 Langfuse SDK

该集成与 OpenAI SDK 版本 >=4.0.0 兼容。

npm install @langfuse/openai openai

注册凭据

将你的 Litefuse 凭据加入环境变量。请确保你的项目根目录有一个 .env 文件,并使用 dotenv 等包加载这些变量。

.env
LANGFUSE_SECRET_KEY = "sk-lf-..."
LANGFUSE_PUBLIC_KEY = "pk-lf-..."
LANGFUSE_BASE_URL = "https://litefuse.cloud"

初始化 OpenTelemetry

Langfuse TypeScript SDK 的追踪建立在 OpenTelemetry 之上,因此你需要设置 OpenTelemetry SDK。LangfuseSpanProcessor 是将 trace 发送到 Litefuse 的关键组件。

import { NodeSDK } from "@opentelemetry/sdk-node";
import { LangfuseSpanProcessor } from "@langfuse/otel";
 
const sdk = new NodeSDK({
  spanProcessors: [new LangfuseSpanProcessor()],
});
 
sdk.start();

使用包装后的客户端调用 OpenAI 方法

环境配置好后,像往常一样从包装后的客户端调用 OpenAI SDK 方法。

import OpenAI from "openai";
import { observeOpenAI } from "@langfuse/openai";
 
const openai = observeOpenAI(new OpenAI());
 
const res = await openai.chat.completions.create({
  messages: [{ role: "system", content: "Tell me a story about a dog." }],
  model: "gpt-4o",
  max_tokens: 300,
});

完成!现在你已经在 Litefuse 中拥有 OpenAI 调用的完整可观测性。

查看 notebook 获取该集成的端到端示例:

故障排查

事件的排队与批处理

Langfuse SDK 会在后台对事件进行排队和批处理,以减少网络请求数量并提升整体性能。在长时间运行的应用中,无需任何额外配置即可工作。

如果你运行的是短生命周期应用,需要在应用退出前 flush Litefuse,以确保所有事件都已发送。

await langfuseSpanProcessor.forceFlush();
 
// If you have previously initialized a Langfuse client, you can use that for the flush call
await langfuse.flush();

了解更多关于事件排队与批处理的内容请见这里

Assistants API

本集成不支持对 Assistants API 进行追踪,因为 OpenAI Assistants 在服务端有状态,难以在不发起额外 API 请求的情况下捕获。我们在这个 FAQ 中提供了一些关于如何更好追踪 Assistants API 用法的信息。

高级用法

自定义 trace 属性

你可以将以下属性添加到 observeOpenAI 函数的 langfuseConfig 中,以使用更多 Litefuse 功能:

属性说明
generationName设置 generationName 以标识特定类型的生成。
langfusePrompt传入已创建或获取的 Litefuse prompt,将其与生成关联起来
generationMetadata通过 generationMetadata 设置希望在 Litefuse 中看到的额外信息。
sessionId当前的 会话
userId当前的 user_id
tags设置 tag 以对 trace 进行分类和过滤。

示例:

const res = await observeOpenAI(new OpenAI(), {
  generationName: "Traced generation",
  generationMetadata: { someMetadataKey: "someValue" },
  sessionId: "session-id",
  userId: "user-id",
  tags: ["tag1", "tag2"],
}).chat.completions.create({
  messages: [{ role: "system", content: "Tell me a story about a dog." }],
  model: "gpt-3.5-turbo",
  max_tokens: 300,
});

添加自定义属性需要使用 observeOpenAI 函数包装 OpenAI SDK,并将属性作为第二个 langfuseConfig 参数传入。由于这里的 Langfuse 客户端是单例,所有调用都使用同一个客户端, 你不必担心会错误地启动多个客户端。

关联到 Litefuse prompt

通过 Litefuse Prompt management,你可以高效地管理和版本化 prompt。你可以通过将 langfusePrompt 属性传给 observeOpenAI 函数,将 OpenAI 的生成关联到某个 prompt。

import { observeOpenAI } from "@langfuse/openai";
import OpenAI from "openai";
 
const langfusePrompt = await langfuse.prompt.get("my-prompt"); // Fetch a previously created prompt
 
const res = await observeOpenAI(new OpenAI(), {
  langfusePrompt,
}).completions.create({
  prompt: langfusePrompt.prompt,
  model: "gpt-3.5-turbo-instruct",
  max_tokens: 300,
});

生成的结果现在与 Litefuse 中的 prompt 关联起来,让你可以追踪 prompt 的使用情况和性能。

在使用 chat prompt 时,你必须将编译后的 prompt messages 类型断言为 OpenAI.ChatCompletionMessageParam[],或使用类型守卫工具函数,因为 Litefuse 的 message role 可以是任意字符串,而 OpenAI 的类型定义则更为严格。

流式响应中的 OpenAI token 用量

OpenAI 仅在 stream_options 中将 include_usage 参数设为 true 时,才会在流式响应中返回 token 用量。如果你希望直接获得 OpenAI 提供的 token 用量,可以在 stream_options 参数中设置 { include_usage: true }

import OpenAI from "openai";
import { observeOpenAI } from "@langfuse/openai";
 
const openai = observeOpenAI(new OpenAI());
 
const stream = await openai.chat.completions.create({
  model: "gpt-4",
  messages: [{ role: "user", content: "How are you?" }],
  stream: true,
  stream_options: { include_usage: true },
});
 
let result = "";
 
for await (const chunk of stream) {
  // Check if chunk choices are not empty. OpenAI returns token usage in a final chunk with an empty choices list.
  result += chunk.choices[0]?.delta?.content || "";
}

FAQ

    这个页面对你有帮助吗?