核心可观测性SDK升级指引JS/TS v4 → v5

JS/TS v4 → v5

JS/TS SDK v5 引入了 以 observation 为中心的数据模型。在该模型中,关联属性(userIdsessionIdmetadatatags)会传播到每个 observation,而不再仅存在于 trace 上。这使得无需昂贵的 join 即可进行单表查询,在大规模场景下能显著提升查询性能。

这改变了你设置 trace 属性的方式:你不再用 updateActiveTrace() 命令式地更新 trace,而是使用 propagateAttributes()——一个包裹回调的函数,会自动把属性应用到回调作用域内创建的所有子 observation。

⚠️

v5 改变了默认的 OpenTelemetry 导出行为:Litefuse 现在会应用一个智能默认 span 过滤器。如果你之前期望所有 span 都被导出(包括非 LLM span),请先查看下方的第一项破坏性变更。

破坏性变更

智能默认 span 过滤替代 export-all 行为

在之前的版本中,默认导出所有 OpenTelemetry span 会引入大量来自基础设施和非 LLM instrumentation 的噪音(HTTP、DB、队列、框架内部)。为了让 trace 更聚焦、更有用,v5 引入了智能默认 span 过滤器。

默认情况下,只要满足以下任意一条,v5 就会导出该 span:

  • span 由 Litefuse 创建(langfuse-sdk
  • span 拥有 gen_ai.* 属性
  • span 的 instrumentation scope 匹配已知的 LLM scope 前缀(例如 openinferencelangsmithhaystacklitellm

在 v5 之前,除非你实现了自定义的 shouldExportSpan 函数,否则所有 span 都会被导出。

保持 v5 之前的 “导出全部” 行为

import { LangfuseSpanProcessor } from "@langfuse/otel";
 
const spanProcessor = new LangfuseSpanProcessor({
  publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
  secretKey: process.env.LANGFUSE_SECRET_KEY!,
  shouldExportSpan: () => true,
});

在默认行为基础上组合自定义规则

在 v5 中,shouldExportSpan 是一次完全覆盖。如果你希望扩展(而非替换)默认过滤,请与 isDefaultExportSpan 组合。

import { LangfuseSpanProcessor, isDefaultExportSpan } from "@langfuse/otel";
 
const spanProcessor = new LangfuseSpanProcessor({
  publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
  secretKey: process.env.LANGFUSE_SECRET_KEY!,
  shouldExportSpan: ({ otelSpan }) =>
    isDefaultExportSpan(otelSpan) ||
    otelSpan.instrumentationScope.name.startsWith("my_framework"),
});

可能的 trace 树副作用与调试方法

当中间或父 span 被丢弃,但子 span 仍被导出时,过滤可能破坏 trace 树。如果 trace 看起来断开,请启用 SDK debug 日志查看被丢弃的 span,然后将所需 scope 加入回调的白名单。

updateActiveTrace() 拆分为 3 个函数

在新模型中,关联属性(userIdsessionIdmetadatatags)必须存在于每个 observation 上,而不仅仅在 trace 上。propagateAttributes() 包裹一个回调——当前以及在该回调中创建的所有子 span 都会自动继承这些属性。在回调 之前 创建的 span 不会被回溯更新。

v4:

import { updateActiveTrace, startActiveObservation } from "@langfuse/tracing";
 
await startActiveObservation("my-operation", async (span) => {
  updateActiveTrace({
    name: "user-workflow",
    userId: "user-123",
    sessionId: "session-456",
    tags: ["production"],
    public: true,
    metadata: { testRun: "server-export" },
    input: { query: "hello" },
    output: { response: "world" },
  });
});

v5:

import {
  propagateAttributes,
  startActiveObservation,
  setActiveTraceIO,
  setActiveTraceAsPublic,
} from "@langfuse/tracing";
 
await propagateAttributes(
  {
    traceName: "user-workflow", // was "name"
    userId: "user-123",
    sessionId: "session-456",
    tags: ["production"],
    metadata: { testRun: "server-export" },
  },
  async () => {
    await startActiveObservation("my-operation", async (span) => {
      setActiveTraceIO({
        input: { query: "hello" },
        output: { response: "world" },
      });
      setActiveTraceAsPublic();
    });
  },
);

关键差异:

属性v4v5
nameupdateActiveTrace({name: ...})propagateAttributes({traceName: ...}, cb)
userIdsessionIdtagsversionupdateActiveTrace({...})propagateAttributes({...}, cb)
metadataupdateActiveTrace({metadata: any})propagateAttributes({metadata: Record<string,string>}, cb)
inputoutputupdateActiveTrace({...})setActiveTraceIO({...})(已弃用)
publicupdateActiveTrace({public: true})setActiveTraceAsPublic()
releaseupdateActiveTrace({release: ...})已移除——使用 LANGFUSE_RELEASE 环境变量
environmentupdateActiveTrace({environment: ...})已移除——使用 LANGFUSE_TRACING_ENVIRONMENT 环境变量
⚠️

setActiveTraceIO() 已被弃用,仅为兼容依赖 trace 输入/输出的 trace 级 LLM-as-a-judge 评估器而保留。新代码请直接在根 observation 上设置输入/输出。

.updateTrace().setTraceIO() + .setTraceAsPublic()

同样的拆分适用于所有 observation 包装类(LangfuseSpanLangfuseGeneration 等)。

v4:

import { startObservation } from "@langfuse/tracing";
 
const span = startObservation("my-op");
span.updateTrace({
  name: "my-trace",
  userId: "user-123",
  sessionId: "session-456",
  tags: ["prod"],
  public: true,
  input: { query: "hello" },
  output: { response: "world" },
});

v5:

import { propagateAttributes, startObservation } from "@langfuse/tracing";
 
propagateAttributes(
  {
    traceName: "my-trace",
    userId: "user-123",
    sessionId: "session-456",
    tags: ["prod"],
  },
  () => {
    const span = startObservation("my-op");
    span.setTraceIO({
      input: { query: "hello" },
      output: { response: "world" },
    });
    span.setTraceAsPublic();
    span.end();
  },
);
⚠️

.setTraceIO() 已被弃用,仅为兼容依赖 trace 输入/输出的 trace 级 LLM-as-a-judge 评估器而保留。

Public API 命名空间重映射(api.*

在 v5 中,高性能 Public API 资源现在是默认值。v2 别名已被移除。

v4 / 过渡期名称v5 名称
langfuse.api.observationsV2langfuse.api.observations
langfuse.api.scoreV2langfuse.api.scores
langfuse.api.metricsV2langfuse.api.metrics
langfuse.api.observations(旧版 v1)langfuse.api.legacy.observationsV1
langfuse.api.score(旧版 v1)langfuse.api.legacy.scoreV1
langfuse.api.metrics(旧版 v1)langfuse.api.legacy.metricsV1

如果你仍需要旧版 v1 行为,请切换到对应的 langfuse.api.legacy.*V1 命名空间。

⚠️

如果你使用自托管 Litefuse,暂时不要使用新的默认方法 langfuse.api.observationslangfuse.api.metrics。它们现在指向 Observations v2 和 Metrics v2 endpoint,这些目前在自托管部署中尚不可用。请改用 langfuse.api.legacy.observationsV1langfuse.api.legacy.metricsV1

@langfuse/langchain 内部变更

CallbackHandler 现在使用 propagateAttributes() 处理 trace 级属性。这影响以下用户:

  • 继承 CallbackHandler
  • 依赖内部 span 创建行为
  • 依赖 traceMetadata 接受非字符串值——非字符串值现在会通过 JSON.stringify 序列化后再传给 propagateAttributes,因为后者要求 Record<string, string>

@langfuse/openai 内部变更

traceMethod 包装器现在用 propagateAttributes() 包裹被追踪的调用,以设置 userIdsessionIdtagstraceName,而不再调用 observation 上的 .updateTrace()。(如果你依赖这些属性也设置在父 observation 上,请用 propagateAttributes 包裹整个执行过程)。

已移除的属性

已移除替代方案
release通过 LANGFUSE_RELEASE 环境变量设置
environment通过 LANGFUSE_TRACING_ENVIRONMENT 环境变量设置
publicsetActiveTraceAsPublic() / .setTraceAsPublic() 替代

迁移清单

  1. 审计依赖非 LLM OpenTelemetry span 的 trace/仪表盘:在 v5 默认过滤器下它们可能不再出现
  2. 如有需要,在 LangfuseSpanProcessor 上设置 shouldExportSpan: () => true,以保持 v5 之前的 “导出所有 span” 行为
  3. 如果你使用自定义过滤,请与 isDefaultExportSpan 组合,以保留默认的聚焦 LLM 的行为
  4. 搜索 updateActiveTrace → 拆分为 propagateAttributes() + setActiveTraceIO()(仅在依赖旧版 trace 级 LLM-as-a-judge 配置时)+ setActiveTraceAsPublic()
  5. 搜索 .updateTrace( → 拆分为 propagateAttributes() + .setTraceIO() + .setTraceAsPublic()
  6. 确认 propagated metadata 的值是 Record<string, string>,且每个值长度 ≤200
  7. release/environment 属性的使用替换为环境变量(LANGFUSE_RELEASELANGFUSE_TRACING_ENVIRONMENT
  8. 搜索 api.observationsV2 / api.scoreV2 / api.metricsV2 → 替换为 api.observations / api.scores / api.metrics
  9. 搜索 api.observations / api.score / api.metrics 上的旧版 v1 用法 → 改为 api.legacy.observationsV1 / api.legacy.scoreV1 / api.legacy.metricsV1
  10. 如果你自托管 Litefuse,暂时不要使用 api.observationsapi.metrics;在 Observations v2 和 Metrics v2 在自托管部署中可用之前,请使用 api.legacy.observationsV1api.legacy.metricsV1
  11. 移除剩余的所有 *V2 别名引用(在 v5 中已被移除)
这个页面对你有帮助吗?