bug: startActiveObservation with asType does not write observation type to span unless .update() is called

用户在使用 @langfuse/tracing SDK(版本约 5.3.0)时,通过 startActiveObservation 创建观察(observation),并指定 asType 为 "chain" 、 "retriever" 或 "embedding" 等类型。问题仅影响 startAc

bug: startActiveObservation with asType does not write observation type to span unless .update() is called

bug: startActiveObservation with asType does not write observation type to span unless .update() is called

快速结论:该问题发生在使用 Langfuse JavaScript SDK 的 startActiveObservation 方法并设置 asType 参数时,观察类型属性未正确写入 OpenTelemetry span,导致观察在 Langfuse 界面显示为通用的 SPAN 而非指定类型。优先排查是否在回调中调用了 .update({}) 作为临时解决方法。

问题场景

用户在使用 @langfuse/tracing SDK(版本约 5.3.0)时,通过 startActiveObservation 创建观察(observation),并指定 asType"chain""retriever""embedding" 等类型。问题仅影响 startActiveObservation,而 startObservation 不受影响。

报错原文

startActiveObservation("my-retriever", async () => {
  // do work — never call obs.update()
}, { asType: "retriever" });
// → appears as SPAN in Langfuse, not RETRIEVER

原因分析

LangfuseBaseObservation 构造函数中,createObservationAttributes(负责写入 OBSERVATION_TYPE 属性)仅在 params.attributes 存在时被调用:

if (params.attributes) {
  this.otelSpan.setAttributes(
    createObservationAttributes(params.type, params.attributes)
  );
}

startActiveObservation 创建指定类型的观察时未传递 attributes 参数:

case "chain":
  observation = new LangfuseChain({ otelSpan: span });
  break;
case "retriever":
  observation = new LangfuseRetriever({ otelSpan: span });
  break;

因此 params.attributes 始终为 undefined,条件判断失败,导致类型属性从未写入 span。类型仅在用户手动调用 .update() 时才被写入,但这不是文档中要求的操作,且失败时无任何告警。

环境排查

  • 确认 SDK 版本:@langfuse/tracing@langfuse/otel 是否为 v5.3.0 或更新版本(问题在 v5.3.0 中确认存在)
  • 确认 OpenTelemetry 集成版本:@opentelemetry/sdk-node 约 v0.218.0
  • 确认是否使用 Langfuse Cloud(问题在 Cloud 版本中报告)
  • 确认是否存在其他自定义 attributes 传递——如果传递了 attributes,类型属性可能意外正确写入

解决步骤

  1. 临时解决方法(已验证有效):在回调函数的第一行显式调用 obs.update({}),强制写入类型属性:
    startActiveObservation("my-retriever", async (obs) => {
      obs.update({});
      // do work
    }, { asType: "retriever" });
  2. 官方修复:该问题已在 langfuse/langfuse-js#836 中修复,预计在后续版本中发布。修复方法是在 LangfuseBaseObservation 构造函数中无条件调用 createObservationAttributes,将 params.attributes ?? {} 作为参数传递。
  3. 升级 SDK:当新版本发布后,升级 @langfuse/tracing 到包含修复的版本(可关注 v5.3.1 或更高版本)。
  4. 检查调用方式:如果无法升级,检查代码中所有 startActiveObservation 调用,确保在回调中尽早调用 .update() 或传递 attributes 参数。

验证方法

在 Langfuse 界面查看对应观察的类型列:如果修复成功,观察应显示为指定的类型(如 RETRIEVERCHAIN 等),而非通用的 SPAN。也可以通过 OpenTelemetry 导出器直接检查 span 属性,确认 langfuse.observation.type 属性是否已正确设置。

参考来源

langfuse/langfuse #13746: bug: startActiveObservation with asType does not write observation type to span unless .update() is called

langfuse/langfuse-js #836 (修复 PR)

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 8004

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注