bug: server stores list-type observation input as Python str() repr (single quotes) instead of JSON

用户在 Langfuse 中使用基于 OpenTelemetry (OTel) 的 Python SDK,搭配 LangChain,并使用了带 content_blocks 参数的 SystemMessage 。这会导致 message.content 变成 Python 的 list[dict]

bug: server stores list-type observation input as Python str() repr (single quotes) instead of JSON

bug: server stores list-type observation input as Python str() repr (single quotes) instead of JSON

快速结论:该 Bug 发生在使用 OTel 方式的 Langfuse Python SDK 配合 LangChain 的 SystemMessage(content_blocks=...) 时。Langfuse 服务器存储的观察值中的 list 类型内容被错误地保存为 Python 的 str() 表现形式(带单引号),而不是有效的 JSON 数组。优先排查:确认 LangChain 回调处理器中对象序列化是否使用了 str() 而非 json.dumps()

问题场景

用户在 Langfuse 中使用基于 OpenTelemetry (OTel) 的 Python SDK,搭配 LangChain,并使用了带 content_blocks 参数的 SystemMessage。这会导致 message.content 变成 Python 的 list[dict] 类型。在 Langfuse UI 和 API 中,该字段内容被显示为带单引号的 Python repr 字符串,而不是预期的 Markdown 文本或 JSON 数组。该问题在使用 langfuse==4.13.0 (OTel-based)、自托管 Langfuse Server 3.162.0、langchain-core==1.4.8 的环境中被复现。

报错原文

在 Langfuse API / UI 中,input[0].content 字段显示为:

[{'type': 'text', 'text': 'You are a test agent.\n\n# Role\n\n...'}]

该值实际类型为 str(而非 list),且以 Python repr 风格包裹(双引号被替换为单引号)。

原因分析

可能原因:问题可能不出在 Langfuse 服务端。服务端的 TypeScript 代码始终使用 JSON.stringify(),并且只保留字符串原样。当属性值本身已经是字符串时,服务端不会进行二次转换。然而,Python SDK 中的 LangChain 回调处理器 (langfuse.langchain.CallbackHandler) 在处理 SystemMessage.content 中的 list 类型值时,可能误用了 Python 的 str() 函数进行序列化,而非 json.dumps()。由于 OTel SDK 仅接受原始类型作为 span 属性值,任何 list/dict 类型都需要显式序列化;如果使用了 str(),就会产生带单引号的 Python repr 字符串。

环境排查

  • Langfuse Python SDK 版本 (尤其是 langfuse): 确认是否为 4.x 系列及具体版本号
  • Langfuse 服务端版本 (自托管用户关注)
  • LangChain 包版本: langchain-core, langchain, langchain-openai
  • 验证 SystemMessage.content 在 Python 中的实际类型 (是否为 list)

解决步骤

  1. 优先排查:检查 langfuse-python SDK 中 LangChain 回调处理器的消息序列化逻辑,确认是否存在 str(content) 的地方。
  2. 如果发现 str() 调用,应将其替换为 json.dumps(content),确保 list/dict 类型的 content 被序列化为合法的 JSON 字符串。
  3. 上述改动应在 langfuse/langfuse-python 仓库中进行提交。
  4. 部署修复后的 SDK 版本,并重新运行你的 LangChain 链路。

验证方法

在修复后,通过 Langfuse API 查询具体的 observation 对象:

GET /api/public/observations/{observation_id}

确认 input[0].content 字段:

  • 类型为 list (在 JSON 中为数组结构)
  • 值中的字符串使用双引号(标准 JSON 格式),而非单引号
  • 不再出现 Python 风格的 repr 字符串

参考来源

langfuse/langfuse #15143

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 13933

发表回复

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