JS/TS v4 → v5
JS/TS SDK v5 引入了**以 observation 为中心的数据模型**。在此模型中,关联属性(userId、sessionId、metadata、tags)传播到每个 observation,而非仅存在于 trace 上。这使得无需昂贵 join 的单表查询成为可能,显著提升了规模化时的查询性能。
这改变了你设置 trace 属性的方式:不再用 updateActiveTrace() 命令式地更新 trace,而是使用 propagateAttributes()——一个包装回调的函数,自动将属性应用于其作用域内创建的所有子 observations。
v5 改变了默认的 OpenTelemetry 导出行为:Langfuse 现在应用智能默认 span 过滤器。如果你之前期望导出所有 spans(包括非 LLM spans),请查看下面的第一个破坏性变更。
破坏性变更
智能默认 span 过滤取代导出全部行为
在以前的版本中,默认导出所有 OpenTelemetry spans 增加了来自基础设施和非 LLM 埋点(HTTP、DB、队列、框架内部)的 trace 噪声。为保持 traces 聚焦和有用,v5 引入了智能默认 span 过滤器。
默认情况下,如果满足以下任一条件,v5 导出 span:
- 该 span 由 Langfuse 创建(
langfuse-sdk) - 该 span 具有
gen_ai.*属性 - 该 span 埋点作用域匹配已知的 LLM 作用域前缀(例如
openinference、langsmith、haystack、litellm)
在 v5 之前,除非你实现了自定义 shouldExportSpan 函数,否则所有 spans 都被导出。
保留 v5 之前的"导出全部"行为
import { LangfuseSpanProcessor } from "@langfuse/otel";
const spanProcessor = new LangfuseSpanProcessor({
publicKey: process.env.LANGFUSE_PUBLIC_KEY!,
secretKey: process.env.LANGFUSE_SECRET_KEY!,
shouldExportSpan: () => true,
});
将自定义规则与默认行为组合
shouldExportSpan 在 v5 中是完全覆盖。如果你想扩展(而非替换)默认过滤,请与 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 树副作用及如何调试
当中间或父 spans 被丢弃而子 spans 仍被导出时,过滤可能会破坏 trace 树。如果 traces 显得断开,请启用 SDK 调试日志以检查被丢弃的 spans,然后在你的回调中将所需作用域加入允许列表。
- JS/TS 调试模式:设置
LANGFUSE_DEBUG="true"(或LANGFUSE_LOG_LEVEL="DEBUG")。 - 参见 SDK 高级功能和针对不需要 spans 的 OpenTelemetry 故障排查。
updateActiveTrace() 分解为 3 个函数
在新模型中,关联属性(userId、sessionId、metadata、tags)必须存在于每个 observation 上,而非仅在 trace 上。propagateAttributes() 包装一个回调——在回调内创建的当前和所有子 spans 自动继承这些属性。在回调_之前_创建的 spans 不会被追溯更新。
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();
});
},
);
关键差异:
| 属性 | v4 | v5 |
|---|---|---|
name |
updateActiveTrace() |
propagateAttributes(, cb) |
userId、sessionId、tags、version |
updateActiveTrace() |
propagateAttributes(, cb) |
metadata |
updateActiveTrace() |
propagateAttributes(, cb) |
input、output |
updateActiveTrace() |
setActiveTraceIO()(已弃用) |
public |
updateActiveTrace() |
setActiveTraceAsPublic() |
release |
updateActiveTrace() |
已移除——使用 LANGFUSE_RELEASE 环境变量 |
environment |
updateActiveTrace() |
已移除——使用 LANGFUSE_TRACING_ENVIRONMENT 环境变量 |
setActiveTraceIO()已弃用,仅为与依赖 trace 输入/输出的 trace 级 LLM-as-a-judge 评估器向后兼容而存在。对于新代码,请直接在根 observation 上设置输入/输出。
.updateTrace() → .setTraceIO() + .setTraceAsPublic()
相同的分解适用于所有 observation 包装器类(LangfuseSpan、LangfuseGeneration 等)。
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.observationsV2 |
langfuse.api.observations |
langfuse.api.scoreV2 |
langfuse.api.scores |
langfuse.api.metricsV2 |
langfuse.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 命名空间。
新的默认
langfuse.api.observations和langfuse.api.metrics方法指向 Observations v2 和 Metrics v2 端点,它们需要 Langfuse v4(Langfuse Cloud,或升级到 v4 的自托管服务器)。在自托管 Langfuse v3 上,请改用langfuse.api.legacy.observationsV1和langfuse.api.legacy.metricsV1。参见自托管兼容性矩阵。
@langfuse/langchain 内部变更
CallbackHandler 现在对 trace 级属性使用 propagateAttributes()。这影响以下用户:
- 继承
CallbackHandler的类 - 依赖内部 span 创建行为
- 依赖
traceMetadata接受非字符串值——非字符串值现在在传递给需要Record<string, string>的propagateAttributes之前通过JSON.stringify序列化
@langfuse/openai 内部变更
traceMethod 包装器现在将追踪的调用包装在 propagateAttributes() 中以设置 userId、sessionId、tags 和 traceName,而非在 observation 上调用 .updateTrace()。(如果你依赖属性也被设置在父 observations 上,请用 propagateAttributes 包装整个执行)。
已移除的属性
| 已移除 | 替代 |
|---|---|
release |
通过 LANGFUSE_RELEASE 环境变量设置 |
environment |
通过 LANGFUSE_TRACING_ENVIRONMENT 环境变量设置 |
public |
由 setActiveTraceAsPublic() / .setTraceAsPublic() 替代 |
迁移清单
- 审计依赖非 LLM OpenTelemetry spans 的 traces/仪表盘:这些可能在 v5 默认过滤器下停止出现
- 如需要,在
LangfuseSpanProcessor上设置shouldExportSpan: () => true以保留 v5 之前的"导出所有 spans"行为 - 如果你使用自定义过滤,请与
isDefaultExportSpan组合以保持默认的 LLM 聚焦行为 - 搜索
updateActiveTrace→ 拆分为propagateAttributes()+setActiveTraceIO()(当依赖旧版 trace 级 LLM-as-a-judge 配置时)+setActiveTraceAsPublic() - 搜索
.updateTrace(→ 拆分为propagateAttributes()+.setTraceIO()+.setTraceAsPublic() - 验证传播的 metadata 值为
Record<string, string>,值 ≤200 字符 - 用环境变量(
LANGFUSE_RELEASE、LANGFUSE_TRACING_ENVIRONMENT)替换release/environment属性用法 - 搜索
api.observationsV2/api.scoreV2/api.metricsV2→ 替换为api.observations/api.scores/api.metrics - 搜索
api.observations/api.score/api.metrics上的旧版 v1 用法 → 移到api.legacy.observationsV1/api.legacy.scoreV1/api.legacy.metricsV1 - 如果你自托管 Langfuse v3,请使用
api.legacy.observationsV1和api.legacy.metricsV1;默认的api.observations/api.metrics需要 Langfuse v4(参见自托管兼容性矩阵) - 移除任何剩余的
*V2别名引用(它们在 v5 中已被移除)