Langfuse 自托管:AI agent 追踪与 VPS 配置
在自有 VPS 上运行 Langfuse v4,了解最低内存、固定镜像标签、TLS 配置,以及 ClickHouse 保留策略和可恢复备份,避免磁盘被数据填满。
为何要跟踪 AI agent
您可以自行托管 Langfuse,查看 agent 在一次运行中实际执行了什么。Langfuse 是一个开源 LLM(大语言模型)可观测性工具。它会记录每条提示词、每次模型响应、每次工具调用和每个 token,然后将这些记录归入一个可打开查看的 trace。将其运行在您自己的 VPS 上,可以确保这些提示词不会离开您控制的服务器。
原因很简单。无法看到的问题,就无法修复,无论是成本问题还是质量问题。服务商账单只能告诉您,周二的成本是周一的 4 倍。trace 则会告诉您是哪次 agent 运行导致了这一结果,哪条提示词增长到 40,000 个 token,以及哪个重试循环在放弃前运行了 9 次。账单给出的是数字。trace 给出的是产生该数字的代码。
本指南会使用 3 个术语。trace 是 agent 的一次端到端运行。observation 是该运行中的一个步骤:普通代码对应一个 span,调用模型对应一次 generation。score 是附加到 trace 上的一个数字,可以来自人工审核或自动评估器。Langfuse 使用 OpenTelemetry(OTel),这是分布式跟踪的厂商中立标准,因此您现有的埋点可以将数据发送到 Langfuse。
Langfuse 自托管的实际运行组件
Langfuse v4 并非单个容器,而是由两个应用容器和四个存储服务组成。在单台 VPS 上,这六个组件均需运行。
langfuse-web提供 Web 界面和数据摄入 API。langfuse-worker在后台处理队列。它负责解析摄入批次、计算成本并运行每日保留任务。- Postgres 存储事务性数据,如用户、组织、项目、API 密钥和提示词(prompts)。
- ClickHouse 存储追踪数据本身,即观测记录和评分。它是一种专为分析查询设计的列式数据库,因此即使在处理数亿行数据时,仪表板依然能快速响应。
- Redis 作为队列和缓存,位于 Web 服务与工作进程之间。
- MinIO 在本地提供 S3 兼容的对象存储。它存储所有原始传入事件以及您附加的任何媒体文件。
Langfuse 公布了各组件运行所需的最低资源。下表展示了其中三个核心工作组件的资源需求。
此图表背后的数据
[
{
"label": "ClickHouse",
"cpu_cores": 2,
"memory_gib": 8
},
{
"label": "Langfuse web",
"cpu_cores": 2,
"memory_gib": 4
},
{
"label": "Langfuse worker",
"cpu_cores": 2,
"memory_gib": 4
}
]仅 ClickHouse 就需要 8 GiB 内存。Web 容器和工作进程容器各需 4 GiB。这些是表中 3 个组件的发布基准值。同一页面列出 Postgres 需要 4 GiB,Redis 或 Valkey 需要 1.5 GiB,MinIO 需要 4 GiB,因此所有六个组件的最低需求总计为 25.5 GiB。该项目的 Docker Compose 指南建议单机至少配置 4 核 CPU、16 GiB 内存和约 100 GiB 存储空间。这低于各组件最低需求之和,因此请将 16 GiB 视为共享 Compose 环境的最低门槛,而非冗余空间。
不要尝试在 2 GiB 内存的方案上运行。ClickHouse 启动后会接受一段时间的写入,但在后台合并(merge)期间会崩溃,因为合并操作会将表的大部分内容加载到内存中。此时,您会看到 docker compose ps 显示 clickhouse 容器状态为 restarting,dmesg 中包含类似 Out of memory: Killed process 1234 (clickhouse-serv) 的行,且所有 Langfuse 仪表板均返回 500 错误。在负载较轻的情况下,ClickHouse 会拒绝查询并在日志中记录 DB::Exception: Memory limit (total) exceeded。对于每天发送几千条追踪记录的单人开发者,8 GiB 内存尚可运行。建议规划 16 GiB 内存。如果同一台 VPS 还需要运行其他服务,请单独预留资源,因为即使是像 自托管 AFFiNE 工作区 这样相对轻量的技术栈也需要占用数 GiB 内存,而 ClickHouse 不会释放任何已占用的内存。
使用 Docker Compose 部署 Langfuse
克隆代码仓库。整个堆栈、连接配置以及默认环境变量均位于其 docker-compose.yml 中。
git clone https://github.com/langfuse/langfuse.git
cd langfuse文件中所有需要修改的值均已标记为 # CHANGEME。首先生成三个应用程序密钥。
openssl rand -base64 32 # NEXTAUTH_SECRET
openssl rand -base64 32 # SALT
openssl rand -hex 32 # ENCRYPTION_KEYENCRYPTION_KEY 必须是 256 位,即 64 个十六进制字符,这正是 openssl rand -hex 32 命令输出的内容。它用于加密存储在实例中的敏感数据,包括您保存的任何 LLM 提供商密钥。如果在已有数据后更改此值,这些数据将无法解密,因此请将其视为首次启动后即永久固定的配置。SALT 用于对您的 Langfuse API 密钥进行哈希处理,因此更改它将导致所有代理当前使用的密钥失效。
随后设置 POSTGRES_PASSWORD、CLICKHOUSE_PASSWORD、REDIS_AUTH 和 MINIO_ROOT_PASSWORD。MinIO 密码需在四处配置:MINIO_ROOT_PASSWORD 一处,以及 LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY、LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY 和 LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY。遗漏任何一处都会导致 MinIO 拒绝客户端连接并报错 SignatureDoesNotMatch,该错误会出现在 worker 日志中,而 Web 界面看起来可能依然正常。将这些值保存在 env 文件中而非直接写入受版本控制的 compose 文件,是 Docker Compose 环境变量文件与密钥 中介绍的最佳实践。
在启动前锁定镜像标签
随附的文件使用了 docker.langfuse.com/langfuse/langfuse:4 和 docker.langfuse.com/langfuse/langfuse-worker:4。这些标签会随版本更新。Langfuse 会在启动时自动执行 Postgres 和 ClickHouse 迁移,因此几个月后的一次常规 docker compose pull 操作,可能会变成一次未经计划的数据库模式迁移,而您当天可能并未进行备份。请在 docker-compose.override.yml 中将两者锁定为特定版本,Compose 会将其合并到随附文件中,从而确保后续的 git pull 不会覆盖您的修改。相同的镜像发布在 Docker Hub 上,下方的覆盖配置即从该处拉取镜像。
services:
langfuse-web:
image: docker.io/langfuse/langfuse:4.3.1
langfuse-worker:
image: docker.io/langfuse/langfuse-worker:4.3.1截至 2026 年 8 月,4.3.1 是当前的 4.3 版本。此后发布节奏很快,截至 2026 年 10 月 11 日,GitHub 上的最新版本为 v4.56.0。请查看项目的 GitHub 发布页面,在部署当天锁定当前版本,并谨慎地进行版本升级。随附文件中的存储镜像也应采取同样的处理方式,因为它们的标签同样会变动。postgres:17(POSTGRES_VERSION 变量的默认值)和 redis:7 遵循主版本号。clickhouse-server:25.12 遵循 25.12 发布分支,因此执行拉取操作可能会引入该分支下的最新补丁版本。此规则不仅适用于 Langfuse:自托管 openGym 运动追踪器 仅运行了该堆栈的一小部分,但仍建议使用具体的 git 标签,因为任何在启动时自动迁移数据库的程序,都可能将一次常规的拉取操作变成数据库模式变更。
启动服务。
docker compose up -d
docker compose ps
docker compose logs -f langfuse-worker首次启动会执行迁移,因此请等待两到三分钟,待服务就绪后再进行访问。Web 容器在启动后会记录 Ready。docker compose ps 应列出处于 running 状态的六个服务。如果容器陷入重启循环,其日志中会记录原因。ClickHouse 迁移在 Web 容器启动时执行,因此错误的 CLICKHOUSE_MIGRATION_URL 会显示在 docker compose logs langfuse-web 中,而不是您正在监控的 worker 日志中。该变量使用端口 9000 上的 ClickHouse 原生协议,而非 HTTP 端口 8123;将其指向 8123 会导致 Web 容器启动时的迁移失败。Worker 负责执行较慢的后台迁移,因此这些迁移的状态会记录在 worker 日志中。
从服务器内部检查健康状态。
curl -s "http://localhost:3000/api/public/health?failIfDatabaseUnavailable=true"
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/public/ready简单的 /api/public/health 调用仅能证明 API 进程存活,因为它默认不检查数据库。failIfDatabaseUnavailable=true 形式的检查才适合配置监控,当数据库不可达时,它会返回 503。当 Web 容器准备好接收流量时,/api/public/ready 返回 200;一旦接收到关闭指令,则返回 500。两者均为常规 HTTP 检查,因此 Uptime Kuma 状态页 可以监控它们,并在您的代理发现问题之前通知您堆栈已宕机。
将 TLS 放在前端并关闭多余端口
随附的 compose 文件为 web 容器发布了 3000:3000,为 MinIO 发布了 9090:9000。两者均绑定在所有网络接口上。在公网 IP 上,这意味着任何扫描 3000 端口的人都能访问您的注册页面,而扫描 9090 端口的人则可以直接连接到存储原始提示词的存储桶。
仅靠防火墙规则无法关闭这些端口。Docker 会将自身的 DNAT 规则写入 nat 表,这些规则的优先级高于 ufw 的过滤规则,因此 ufw deny 3000 会导致已发布的端口保持开放。此类问题非常普遍,已有专门指南说明:为什么 Docker 发布端口会绕过 ufw。请在您的 override 文件中改为绑定到回环地址。
services:
langfuse-web:
ports:
- "127.0.0.1:3000:3000"
environment:
NEXTAUTH_URL: https://langfuse.example.com
minio:
ports:
- "127.0.0.1:9090:9000"
- "127.0.0.1:9091:9001"NEXTAUTH_URL 必须是包含协议方案的完整公网地址,因为登录流程会根据该值构建回调 URL。如果将其保留为 http://localhost:3000 并置于 HTTPS 代理之后,登录往返请求会将浏览器重定向到无法访问的地址。
现在将反向代理指向 127.0.0.1:3000 并由其持有证书。在同一个 Compose 项目中使用 Traefik 是常见做法,其路由标签已在 在 Traefik 反向代理后运行多个应用 中介绍。如果服务器上仅运行 Langfuse,使用 Caddy 只需两行配置即可完成相同工作。使用 curl -sI https://langfuse.example.com/api/public/ready 进行验证,然后从另一台机器确认 curl http://YOUR_IP:3000 现在会超时。
关于 MinIO 有一点需要注意。Langfuse 会分发指向该 S3 端点的预签名 URL,供上传媒体的 SDK 和加载媒体的浏览器使用。因此,如果您使用包含图像或音频的多模态追踪,仅绑定回环地址的 MinIO 将导致这些附件无法从其他机器上传,也无法在浏览器中加载。在代理 MinIO 之前,请阅读对象存储配置页面,因为写入预签名 URL 的端点 LANGFUSE_S3_MEDIA_UPLOAD_ENDPOINT 必须与您发布的地址一致。纯文本追踪不受此影响。
首次访问时创建您的账户,随后请确保该实例仅供您使用。在账户创建完成后设置 AUTH_DISABLE_SIGNUP=true,这样陌生人访问页面时将无法进行注册。Langfuse 还提供 LANGFUSE_ALLOWED_ORGANIZATION_CREATORS,用于限制组织创建权限,但这属于企业版功能,仅在配置许可证密钥后生效。如果您已经在使用 Authentik 作为身份提供商,Langfuse 支持标准的 OIDC 连接,这样账户管理将与您的其他应用同步,而无需仅在该服务器的密码列表中维护。
发送第一条追踪记录
在 Web 界面中创建项目,然后从项目设置中复制其公钥和密钥。Python SDK 会读取 3 个环境变量。
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"LANGFUSE_BASE_URL 是 SDK v4 中的变量名。SDK v4 于 2026 年 3 月发布。旧代码和旧指南使用 LANGFUSE_HOST。如果追踪记录被发送到 Langfuse Cloud,而不是您的服务器,原因是基础 URL 未设置,因为默认值指向托管实例。
pip install langfuse opentelemetry-instrumentation-anthropic anthropicimport os
from anthropic import Anthropic
from langfuse import get_client, observe
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
AnthropicInstrumentor().instrument()
langfuse = get_client()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
@observe(as_type="tool")
def lookup_order(order_id: str) -> str:
return f"order {order_id}: shipped"
@observe()
def handle_request(question: str) -> str:
context = lookup_order("A-1042")
message = client.messages.create(
model="claude-haiku-4-5",
max_tokens=512,
messages=[{"role": "user", "content": f"{context}\n\n{question}"}],
)
return message.content[0].text
if __name__ == "__main__":
assert langfuse.auth_check()
print(handle_request("Where is my order?"))
langfuse.flush()@observe 装饰器会在函数周围创建一个观测,捕获函数参数和返回值,并将其嵌套在当前已激活的观测下。AnthropicInstrumentor 是 Anthropic 客户端的 OpenTelemetry 插桩,它会将每次 messages.create 调用转换为一条 generation,记录模型名称、token 用量和延迟,无需修改调用位置。
这两个调用会为您完成检查。langfuse.auth_check() 会在密钥无效或基础 URL 错误时返回 False。这样可以更快定位问题,而不必猜测仪表板为何为空。langfuse.flush() 会阻塞,直到队列中的 span 全部发送完毕。短生命周期进程必须调用它,因为 SDK 会在后台批量发送数据;如果脚本立即退出,尚未发送的批次也会随进程一起丢失。
如果整个团队都在发送 trace,而不是只有一个脚本发送,请在所有 agent 已经通过的网关中统一设置这 3 个变量,不要在每个人的 shell 中分别设置。这样,自托管的 OneCLI harness 就能为每位同事的运行保留监控,同时将密钥集中存放。
为什么 ClickHouse 的磁盘占用持续增长?
追踪数据(Traces)是大多数自托管用户遇到的增长最快的数据类型。Agent 每运行一步都会写入一行数据,且输入和输出会被完整存储。因此,一个频繁交互且带有长提示词的 Agent 每天产生的字节数远超其所监控的应用。若不加干预,ClickHouse 会填满磁盘;一旦磁盘写满,数据摄入将直接停止,而非仅仅变慢。
这里涉及两个独立的增长源,需要分别处理。
首先是您自己的追踪数据,解决方法是设置保留策略。在自托管实例中,数据保留是 Enterprise Edition 的功能,需要许可证密钥。如果没有许可证,Langfuse 会永久保留追踪、观测、评分和媒体文件,因此请据此规划磁盘空间,并参考本节末尾的磁盘告警设置。拥有许可证后,项目所有者和管理员可在项目设置中配置以天为单位的数据保留期。Langfuse 最短支持 3 天。系统会运行一个夜间任务,筛选出超过该时间窗口的追踪、观测、评分和媒体资源,并将其从 ClickHouse 和对象存储中删除。该任务需要对存储桶拥有 DeleteObject 权限,默认 compose 文件中的 MinIO root 凭据已具备此权限。删除操作是永久性的,因此如果您需要长期历史记录,请先配置对象存储导出。请勿手动为 Langfuse 的表编写 TTL 子句:保留任务负责同步 ClickHouse 和存储桶的状态,手动设置 TTL 只会删除其中一侧的数据。
请根据实际使用需求选择时间窗口。成本和质量审查通常针对几天前的数据,而非几个月前的数据。对于小型团队,30 天是一个合理的起点;如果您仅在出现故障时才查看追踪记录,14 天已足够。
其次是 ClickHouse 自身的系统日志表。这常令用户感到意外,因为即使配置了保留策略,磁盘空间仍在增长。ClickHouse 会写入 trace_log、text_log、opentelemetry_span_log、metric_log、asynchronous_metric_log 和 latency_log 用于自身诊断,这些表默认没有 TTL,且 Langfuse 从不读取它们。首先确认磁盘空间究竟被何处占用。
SELECT table, formatReadableSize(size) AS size, rows FROM (
SELECT table, database, sum(bytes) AS size, sum(rows) AS rows
FROM system.parts
WHERE active
GROUP BY table, database
ORDER BY size DESC
)使用 docker compose exec clickhouse clickhouse-client --password "$CLICKHOUSE_PASSWORD" 运行上述命令。如果系统表占用空间靠前,请通过配置覆盖将其关闭,因为 ClickHouse 在启动时会将 /etc/clickhouse-server/config.d/ 中的所有文件合并到主配置中。
<clickhouse>
<trace_log remove="1"/>
<text_log remove="1"/>
<opentelemetry_span_log remove="1"/>
<asynchronous_metric_log remove="1"/>
<metric_log remove="1"/>
<latency_log remove="1"/>
</clickhouse>挂载该文件并重启 ClickHouse。
services:
clickhouse:
volumes:
- ./clickhouse-config.d/system-logs.xml:/etc/clickhouse-server/config.d/system-logs.xml:ro这会停止新的写入。磁盘上已有的行仍会保留,因此请使用 DROP TABLE IF EXISTS system.trace_log 显式回收空间,对每个移除的表执行相同操作。如果您希望保留诊断信息,另一种方案是为每个表设置激进的 TTL,而不是使用 remove="1",具体细节请参考 Langfuse 扩展文档。这些 TTL 指令仅在系统表首次创建时生效,因此对于现有安装,请参考同一文档中关于改造现有表的说明。
还有一个表值得注意。blob_storage_file_log 用于跟踪上传到存储桶的事件文件。如果您同时在存储桶上设置了生命周期策略,请为该表设置匹配的 TTL,以防两者数据不同步。
ALTER TABLE blob_storage_file_log MODIFY TTL created_at + INTERVAL 30 DAY DELETE;同时为数据磁盘设置一个简单的 df -h 告警。追踪数据的增长并非线性。当您发布新 Agent 时,数据量会激增,不应等到数据摄入失败才发现问题。
备份 Postgres 和 ClickHouse
Langfuse 备份包含三个部分。Postgres 存储用户、组织、项目和 API 密钥。ClickHouse 存储追踪记录。MinIO 存储原始事件。如果仅恢复 Postgres,你将获得一个可登录但没有历史记录的系统。如果仅恢复 ClickHouse,你将获得历史记录,但无人能登录查看。这种分离并非 Langfuse 所独有,自托管 Chatwoot 客服系统也具有相同的结构:如果备份 Postgres 时未包含上传目录,恢复后的对话将丢失所有附件。
Postgres 是一个标准的 pg_dump,这也是 Langfuse 备份文档针对 Docker 安装所采用的方法。
docker compose exec -T postgres pg_dump -U postgres postgres \
| gzip > langfuse-pg-$(date +%F).sql.gzClickHouse 的备份需要更谨慎,因为在合并操作运行时直接复制实时数据目录无法保证备份的一致性。在单机环境下,最简单的方法是停止容器并归档数据卷。
docker compose stop clickhouse
docker volume ls | grep clickhouse
docker run --rm -v langfuse_langfuse_clickhouse_data:/data -v "$PWD":/backup alpine \
tar czf /backup/langfuse-ch-$(date +%F).tar.gz -C /data .
docker compose start clickhouse请使用 docker volume ls 输出的卷名称,而不是 YAML 文件中编写的名称。文件中声明的是 langfuse_clickhouse_data,而 Compose 会在名称前加上项目名称前缀,因此在名为 langfuse 的目录下克隆会产生 langfuse_langfuse_clickhouse_data。如果弄错了,docker run 会创建一个新的空卷且不会报错,导致你的归档文件为空。
Langfuse 在每次接收请求时都会将原始事件数据上传到存储桶,并在重试失败的接收任务时重新读取,因此短暂停止 ClickHouse 通常意味着工作进程随后会进行重试。请在业务低峰期执行此操作并尽量缩短时间。对于负载较高的实例,ClickHouse 自带的 BACKUP DATABASE default TO S3(...) 语句可以在不停止服务的情况下写入一致的备份。MinIO 是第三部分,使用 mc mirror 或将 MinIO 复制到远程存储桶即可覆盖此需求。无论生成什么备份,请务必将其移出服务器,这正是 VPS 上加密 restic 备份 的用途。
Redis 无需备份。它仅存储队列和缓存,因此丢失它只会导致当前传输中的事件丢失,不会影响旧数据。
一致性问题是真实存在的,必须明确说明。由于 Postgres 和 ClickHouse 的转储时间不同,恢复后可能会出现项目行记录没有对应追踪记录,或者追踪记录所属的项目已不存在的情况。Langfuse 可以容忍这种情况,但请尽量在低流量窗口期内连续执行两次转储。事件存储桶是真正的安全网,因为 Langfuse 在每次接收请求时都会将原始事件数据上传到那里。
请至少在测试环境中进行一次恢复演练。这样你现在就能发现卷名称错误,而不是等到故障发生时才发现。
优先关注的内容
以下四项内容在第一周内最值得关注。
- 单次追踪成本。 Langfuse 根据模型名称和 Token 用量计算成本,因此请按成本对追踪记录进行排序,并完整阅读成本最高的那一条。问题通常出在不断膨胀的 Prompt 上:比如将整篇文档粘贴到上下文中,或者未进行修剪的对话历史。一旦发现问题,控制 AI Agent 成本 就从猜测变成了工程任务。
- 输入与输出的 Token 用量拆分。 输入 Token 数量多且价格低廉,输出 Token 数量少但价格昂贵,而缓存后的输入 Token 价格更低。Claude Code Token 用量计算方式 中详细说明了同样的核算逻辑,该逻辑同样适用于您自行编写的任何 Agent。不过 Langfuse 只能看到您自己埋点的代码;如果额度主要消耗在团队日常使用的 Claude Code 上,可以在 VPS 上自建 Agent Console,按会话、子代理和模型查看这些 Token 究竟花在了哪里。
- 延迟百分位。 中位数往往掩盖了问题。p95 和 p99 才是超时问题的所在,而在 Agent 循环中,一次 p95 级别的缓慢工具调用会被迭代次数放大。
- 失败的工具调用。 按级别
ERROR过滤观察结果。一个有 5% 失败率的工具在汇总成功率中难以察觉,但在追踪记录中却非常明显,您可以观察到模型在不断重试,并因此消耗大量 Token 来绕过错误。
设置保留周期,并选定一个仪表盘,在每周部署的当天进行检查。没人查看的可观测性工具,只会成为填满磁盘的数据库。
FAQ
自托管 Langfuse 需要多少内存?
建议配置 4 核 CPU 和 16 GiB 内存,这是 Langfuse Docker Compose 指南针对单台虚拟机给出的建议,此外还需约 100 GiB 存储空间。各组件的发布版最低要求为:ClickHouse 需要 8 GiB,Web 和 Worker 容器各需 4 GiB。同一页面列出 Postgres 需 4 GiB、Redis 需 1.5 GiB、MinIO 需 4 GiB,六者合计 25.5 GiB,高于 Compose 建议的 16 GiB。8 GiB 内存可运行单个开发人员的实例。2 GiB 内存无法运行:ClickHouse 会在后台合并期间被内核终止,且 dmesg 显示 Out of memory: Killed process。
为什么设置数据保留策略后 ClickHouse 磁盘空间仍持续占满?
保留策略仅涵盖 Langfuse 自身的数据。ClickHouse 会额外写入诊断表 trace_log、text_log、opentelemetry_span_log、metric_log、asynchronous_metric_log 和 latency_log,这些表默认没有 TTL。通过查询 system.parts 并按表分组,查看占用空间最大的表,然后在 /etc/clickhouse-server/config.d/ 目录下的文件中添加 remove="1" 条目以禁用未使用的表,重启 ClickHouse,最后删除现有表以回收已用空间。
Langfuse 的最短数据保留期是多少?
三天。保留期可在项目设置中按项目配置,或通过组织管理 API 设置。系统每晚会运行作业,删除 ClickHouse 和对象存储中超过该时间窗口的追踪记录、观测数据、评分及媒体资产。在自托管实例中,此功能属于需要许可证密钥的 Enterprise Edition 特性。若无密钥,数据将永久保留。删除操作不可撤销,因此若需保留超出该窗口的历史记录,请先配置对象存储导出。
我必须同时备份 Postgres 和 ClickHouse 吗?
是的,因为它们存储的内容不同。Postgres 存储用户、组织、项目和 API 密钥,而 ClickHouse 存储追踪数据本身。仅恢复 Postgres 会导致实例虽然可以登录,但内部没有任何数据。同时备份 MinIO 存储桶,因为它存储了 Langfuse 接收时持久化的原始事件,这是该技术栈中最接近事实来源的数据。
我可以将现有的 OpenTelemetry 设置指向自托管的 Langfuse 吗?
可以。Langfuse v4 及其当前 SDK 基于 OpenTelemetry 构建,Anthropic 和 OpenAI 的 OTel 插桩可直接导出至该系统。在 Python 中,运行 pip install langfuse opentelemetry-instrumentation-anthropic,在启动时调用一次 AnthropicInstrumentor().instrument(),并将 LANGFUSE_PUBLIC_KEY、LANGFUSE_SECRET_KEY 和 LANGFUSE_BASE_URL 设置为你的主机地址。在排查仪表板缺失问题前,请先通过 langfuse.auth_check() 进行确认。