JS/TS v4 → v5
JS/TS SDK v5 引入了 以 observation 为中心的数据模型。在该模型中,关联属性(userId、sessionId、metadata、tags)会传播到每个 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 前缀(例如
openinference、langsmith、haystack、litellm)
在 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 加入回调的白名单。
- JS/TS debug 模式:设置
LANGFUSE_DEBUG="true"(或LANGFUSE_LOG_LEVEL="DEBUG")。 - 参见 SDK 进阶功能 和 关于不需要的 span 的 OpenTelemetry 故障排查。
updateActiveTrace() 拆分为 3 个函数
在新模型中,关联属性(userId、sessionId、metadata、tags)必须存在于每个 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();
});
},
);关键差异:
| 属性 | v4 | v5 |
|---|---|---|
name | updateActiveTrace({name: ...}) | propagateAttributes({traceName: ...}, cb) |
userId、sessionId、tags、version | updateActiveTrace({...}) | propagateAttributes({...}, cb) |
metadata | updateActiveTrace({metadata: any}) | propagateAttributes({metadata: Record<string,string>}, cb) |
input、output | updateActiveTrace({...}) | setActiveTraceIO({...})(已弃用) |
public | updateActiveTrace({public: true}) | setActiveTraceAsPublic() |
release | updateActiveTrace({release: ...}) | 已移除——使用 LANGFUSE_RELEASE 环境变量 |
environment | updateActiveTrace({environment: ...}) | 已移除——使用 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 命名空间。
如果你使用自托管 Litefuse,暂时不要使用新的默认方法 langfuse.api.observations 或 langfuse.api.metrics。它们现在指向 Observations v2 和 Metrics v2 endpoint,这些目前在自托管部署中尚不可用。请改用 langfuse.api.legacy.observationsV1 和 langfuse.api.legacy.metricsV1。
@langfuse/langchain 内部变更
CallbackHandler 现在使用 propagateAttributes() 处理 trace 级属性。这影响以下用户:
- 继承
CallbackHandler - 依赖内部 span 创建行为
- 依赖
traceMetadata接受非字符串值——非字符串值现在会通过JSON.stringify序列化后再传给propagateAttributes,因为后者要求Record<string, string>
@langfuse/openai 内部变更
traceMethod 包装器现在用 propagateAttributes() 包裹被追踪的调用,以设置 userId、sessionId、tags 和 traceName,而不再调用 observation 上的 .updateTrace()。(如果你依赖这些属性也设置在父 observation 上,请用 propagateAttributes 包裹整个执行过程)。
已移除的属性
| 已移除 | 替代方案 |
|---|---|
release | 通过 LANGFUSE_RELEASE 环境变量设置 |
environment | 通过 LANGFUSE_TRACING_ENVIRONMENT 环境变量设置 |
public | 由 setActiveTraceAsPublic() / .setTraceAsPublic() 替代 |
迁移清单
- 审计依赖非 LLM OpenTelemetry span 的 trace/仪表盘:在 v5 默认过滤器下它们可能不再出现
- 如有需要,在
LangfuseSpanProcessor上设置shouldExportSpan: () => true,以保持 v5 之前的 “导出所有 span” 行为 - 如果你使用自定义过滤,请与
isDefaultExportSpan组合,以保留默认的聚焦 LLM 的行为 - 搜索
updateActiveTrace→ 拆分为propagateAttributes()+setActiveTraceIO()(仅在依赖旧版 trace 级 LLM-as-a-judge 配置时)+setActiveTraceAsPublic() - 搜索
.updateTrace(→ 拆分为propagateAttributes()+.setTraceIO()+.setTraceAsPublic() - 确认 propagated metadata 的值是
Record<string, string>,且每个值长度 ≤200 - 将
release/environment属性的使用替换为环境变量(LANGFUSE_RELEASE、LANGFUSE_TRACING_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 - 如果你自托管 Litefuse,暂时不要使用
api.observations或api.metrics;在 Observations v2 和 Metrics v2 在自托管部署中可用之前,请使用api.legacy.observationsV1和api.legacy.metricsV1 - 移除剩余的所有
*V2别名引用(在 v5 中已被移除)