核心可观测性功能多模态

多模态与附件

Litefuse 支持多模态 trace,包括 文本、图片、音频和其他附件

默认情况下,base64 编码的 data URI 会被 Langfuse SDK 自动处理。它们会从多模态 LLM 常用的 payload 中被提取出来,上传到 Litefuse 的对象存储中,并关联到对应的 trace。

以下场景同样适用:

  1. 通过外部 URL 引用媒体文件。
  2. 通过 SDK 中的 LangfuseMedia 类自定义媒体文件的处理方式。
  3. 直接通过 Litefuse API 集成。

下面会进一步介绍如何上手以及底层原理。

示例

Trace in Litefuse UI

可用性

Litefuse Cloud

目前 Litefuse Cloud 上的多模态附件免费。我们保留在不久的将来推出新的计费指标的可能性,以覆盖大型多模态 trace 带来的额外存储和计算成本。

自托管

多模态附件目前可用。你需要通过 Litefuse 环境变量(LANGFUSE_S3_MEDIA_UPLOAD_*)配置自己的对象存储桶。具体环境变量见自托管文档。所有主流云厂商都支持兼容 S3 的 API,也可以通过 minio 自托管。注意:所配置的存储桶必须有可公开解析的主机名,以便支持通过 SDK 直接上传以及在浏览器中直接获取媒体资源。

支持的媒体格式

Litefuse 支持:

  • 图片:.png、.jpg、.webp
  • 音频文件:.mpeg、.mp3、.wav
  • 其他附件:.pdf、纯文本

如果你需要支持其他文件类型,请提一个 issue

快速开始

Base64 data URI 编码的媒体

如果你在 LLM 应用中使用 base64 编码的图片、音频或其他文件,请升级到最新版本的 Langfuse SDK。Langfuse SDK 会自动检测并处理 base64 编码的媒体:把它们提取出来,作为 Litefuse 媒体文件单独上传,然后在 trace 中放入引用。

这适用于标准的 Data URI(MDN)格式的媒体,比如 OpenAI 等 LLM 使用的格式。

这个 notebook 包含一些使用 OpenAI SDK 和 LangChain 的示例。

外部媒体(URL)

如果媒体文件遵循常见格式,Litefuse 支持通过 URL 内联渲染。这种情况下,媒体文件不会上传到 Litefuse 的对象存储,而是直接在 UI 中从源地址渲染。

支持的格式:

![Alt text](https://example.com/image.jpg)

自定义附件

如果你想要更多控制,或者你的媒体不是 base64 编码,可以通过 SDK 使用新的 LangfuseMedia 类把任意媒体附件上传到 Litefuse。把媒体用 LangfuseMedia 包裹后再放入 trace 的 input、output 或 metadata 即可。详见多模态文档中的示例。

from langfuse import get_client, observe, propagate_attributes
from langfuse.media import LangfuseMedia
 
# Create a LangfuseMedia object from a file
 
with open("static/bitcoin.pdf", "rb") as pdf_file:
pdf_bytes = pdf_file.read()
 
# Wrap media in LangfuseMedia class
 
pdf_media = LangfuseMedia(content_bytes=pdf_bytes, content_type="application/pdf")
 
# Using with the decorator
 
@observe()
def process_document():
    langfuse = get_client()
 
    # Propagate metadata (including media) to all child observations
    with propagate_attributes(
        metadata={"document": pdf_media}
    ):
        pass
 
    # Or update the current span
    langfuse.update_current_span(
        input={"document": pdf_media}
    )
 
# Using with context managers
 
langfuse = get_client()
 
with langfuse.start_as_current_observation(as_type="span", name="analyze-document") as span: # Include media in the span input, output, or metadata
    span.update(
        input={"document": pdf_media},
        metadata={"file_size": len(pdf_bytes)}
    )
 
    # Process document...
 
    # Add results with media to the output
    span.update(output={
        "summary": "This document explains Bitcoin...",
        "original": pdf_media
    })
 

API

如果你直接通过 API 把 trace 发送到 Litefuse,需要按以下步骤操作:

上传媒体到 Litefuse

  1. 如果使用 base64 编码的媒体:你需要从 trace payload 中提取出来,方式与 Langfuse SDK 的处理类似。
  2. 初始化上传,获取 mediaIdpresignedURLPOST /api/public/media
  3. 上传媒体文件:PUT [presignedURL]

参见这个 端到端示例(Python),了解如何直接通过 API 上传媒体文件。

在 trace/observation 中引用 mediaId

使用 Litefuse 媒体 token 在 trace 或 observation 的 inputoutputmetadata 中引用 mediaId

工作原理

对于不通过外部 URL 引用的媒体文件,Litefuse 按以下方式处理:

1. 媒体上传过程

检测与提取

  • Litefuse 支持 trace 和 observation 在 inputoutputmetadata 字段中包含媒体文件
  • SDK 在客户端将媒体与 trace 数据分离,以优化性能
  • 媒体文件直接上传到对象存储(AWS S3 或兼容服务)
  • 原始媒体内容会被替换为一个引用字符串

安全与优化

  • 上传使用预签名 URL,并附带内容校验(content length、content type、content SHA256 hash)
  • 去重:如果文件已上传,会直接被替换为其 mediaId 引用字符串
  • 文件唯一性由项目、content type 和 content SHA256 hash 决定

实现细节

  • Python SDK:通过后台线程实现非阻塞执行
  • JS/TS SDK:异步、非阻塞实现
  • API 也支持直接上传(参见 指南

2. 媒体引用机制

Litefuse trace 中的 base64 data URI 和被包裹的 LangfuseMedia 对象,会被替换为指向 mediaId 的引用,使用以下标准化的 token 格式,以便在需要时重建原始 payload:

@@@langfuseMedia:type={MIME_TYPE}|id={LANGFUSE_MEDIA_ID}|source={SOURCE_TYPE}@@@
  • MIME_TYPE:媒体文件的 MIME 类型,例如 image/jpeg
  • LANGFUSE_MEDIA_ID:Litefuse 对象存储中媒体文件的 ID
  • SOURCE_TYPE:媒体文件的来源类型,可以是 base64_data_uribytesfile

基于该 token,Litefuse UI 能自动检测 mediaId 并内联渲染媒体文件。LangfuseMedia 类提供了从引用字符串提取 mediaId 的工具方法。

3. 解析媒体引用

在处理包含媒体引用的 trace、observation 或数据集 item 时,可以使用 Langfuse 客户端提供的 resolve_media_references 工具方法,把它们转换回 base64 data URI 格式。这在微调、数据集运行或重放 generation 时重新插入原始内容尤其有用。该工具方法会遍历解析后的对象,并返回一个深拷贝,其中所有媒体引用字符串都被对应的 base64 data URI 替换。

from langfuse import get_client
 
# Initialize Langfuse client
langfuse = get_client()
 
# Example object with media references
obj = {
    "image": "@@@langfuseMedia:type=image/jpeg|id=some-uuid|source=bytes@@@",
    "nested": {
        "pdf": "@@@langfuseMedia:type=application/pdf|id=some-other-uuid|source=bytes@@@"
    }
}
 
# Resolve media references to base64 data URIs
resolved_obj = langfuse.resolve_media_references(
    obj=obj,
    resolve_with="base64_data_uri"
)
 
# Result:
# {
#     "image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
#     "nested": {
#         "pdf": "data:application/pdf;base64,JVBERi0xLjcK..."
#     }
# }
这个页面对你有帮助吗?