多模态与附件
Litefuse 支持多模态 trace,包括 文本、图片、音频和其他附件。
默认情况下,base64 编码的 data URI 会被 Langfuse SDK 自动处理。它们会从多模态 LLM 常用的 payload 中被提取出来,上传到 Litefuse 的对象存储中,并关联到对应的 trace。
以下场景同样适用:
- 通过外部 URL 引用媒体文件。
- 通过 SDK 中的
LangfuseMedia类自定义媒体文件的处理方式。 - 直接通过 Litefuse API 集成。
下面会进一步介绍如何上手以及底层原理。
示例

可用性
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 中从源地址渲染。
支持的格式:
自定义附件
如果你想要更多控制,或者你的媒体不是 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
- 如果使用 base64 编码的媒体:你需要从 trace payload 中提取出来,方式与 Langfuse SDK 的处理类似。
- 初始化上传,获取
mediaId和presignedURL:POST /api/public/media。 - 上传媒体文件:
PUT [presignedURL]。
参见这个 端到端示例(Python),了解如何直接通过 API 上传媒体文件。
在 trace/observation 中引用 mediaId
使用 Litefuse 媒体 token 在 trace 或 observation 的 input、output 或 metadata 中引用 mediaId。
工作原理
对于不通过外部 URL 引用的媒体文件,Litefuse 按以下方式处理:
1. 媒体上传过程
检测与提取
- Litefuse 支持 trace 和 observation 在
input、output和metadata字段中包含媒体文件 - 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/jpegLANGFUSE_MEDIA_ID:Litefuse 对象存储中媒体文件的 IDSOURCE_TYPE:媒体文件的来源类型,可以是base64_data_uri、bytes或file
基于该 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..."
# }
# }
