一张图看全貌
七个组件挨个讲
1. Langfuse Web(Next.js App)
这是用户唯一看到的组件——浏览器打开的 UI、以及 SDK POST 数据进来的接收端,都是它。一个进程同时承担"前端 + API Gateway"两个角色。
- 接 SDK 流量:
/api/public/ingestion(trace/span/score 批量写入)、/api/public/prompts/*(prompt CRUD)、/api/public/datasets/*等 - 渲染 UI:用 SSR 读 Postgres / ClickHouse,展示六大面板
- 水平扩展:无状态,Pod 随便加,前面挂 Ingress / ALB 即可
Web 收到 ingestion 请求后 不 直接写 ClickHouse,而是扔到 Redis 队列交给 Worker。这样 SDK 永远感知不到 ClickHouse 繁忙或重启——对 SDK 来说,只要 Redis 能收,就算成功。
2. Langfuse Worker
后台 worker,独立部署,单独扩容。做两件事:
- 消费 ingestion 队列:把 SDK 批量上报的 trace/observation/score 批量写入 ClickHouse
- 执行异步作业:跑在线 eval(LLM-as-Judge)、dataset run、batch export
扩容经验:Web 和 Worker 可以不同步扩。写入高峰扩 Worker,UI 查询高峰扩 Web。
3. ClickHouse(OLAP 主存储)
Langfuse 的"账本"。所有 trace / observation / score / event 全部落在 ClickHouse 里。为什么不是 Postgres?
为什么 ClickHouse
- 观测数据 append-heavy,OLAP 列存压缩率高(比 Postgres 省 10×)
- 聚合查询(按模型/用户/时间段求 token 和 cost)是日常,ClickHouse 秒级
- 原生支持 TTL、分区、Projection,留存周期管理方便
- 千万级写入 + 亿级扫描都轻松
代价
- 单点/HA 部署比 Postgres 复杂
- 更新/删除贵(Langfuse 设计是 append-only,没问题)
- 慢查询排查要懂
EXPLAIN和索引结构 - ZooKeeper / Keeper 依赖(Replicated 表需要)
4. Postgres(OLTP 元数据)
关系型数据,不适合放 ClickHouse 的那部分:
- 用户、组织、项目、API Key
- Prompt 版本、label(production/staging)
- Dataset 定义(不含 run 结果)
- Evaluator 配置、rubric
- SSO / OIDC / 权限
日常写入量小,Postgres 14+ 单实例扛得住,HA 上 RDS / CloudSQL / Patroni 任一方案。
5. Redis(队列 + 缓存)
两用途:
- Ingestion 队列:Web 接到 SDK 数据,入 BullMQ 队列,Worker 消费
- Prompt 缓存:SDK 拉 prompt 后本地缓存,Web 侧也缓存,减轻 Postgres 压力
生产推荐 Redis 7+ 主从或 Cluster,AOF 开启防丢数据(虽然队列丢了理论上 SDK 会重试)。
6. S3 / MinIO(大 body 对象存储)
LLM 调用的 input / output 可能几十 KB 甚至 MB(想想你喂进去的长 RAG 上下文)。全塞 ClickHouse 会膨胀,Langfuse 把大 body 抽出来扔对象存储,ClickHouse 只存引用:
ClickHouse observations 表: id=obs_123 input_ref=s3://langfuse-blobs/projects/proj-1/obs/obs_123/input output_ref=s3://langfuse-blobs/projects/proj-1/obs/obs_123/output token_in=1234, token_out=567, model=gpt-4o, ... S3 object: s3://langfuse-blobs/.../input (原始 prompt, gzipped)
这让 ClickHouse 表保持轻,聚合查询快;代价是详情页要额外访问 S3。内网 MinIO / 云上 S3 / R2 都可以——Langfuse 用 S3 协议,改 endpoint 就能切。
Langfuse 3.0 后支持多模态 trace:图片、音频、PDF 作为 attachment 写进 trace。这些 blob 100% 走 S3,不进 ClickHouse,不进 Postgres。
7. 可选:ZooKeeper / Keeper
只有当你用 ClickHouse Replicated 表做多副本时需要。单机起步阶段不用装,后面第 8 章讲 K8s 生产部署时再展开。
完整的数据流:一次 LLM 调用的生命周期
- App 发起 LLM 调用,SDK
trace()/generation()捕获 input/output/model/token - SDK 在后台线程 批量(默认 1 秒或 100 条)POST 到
/api/public/ingestion - Web 接收,快速校验 API Key + project,push 到 Redis
ingestion队列,立即返回202 - Worker 从队列消费,把 trace/observation 写入 ClickHouse;大 body 另存 S3,写引用
- 若该 project 配了在线 evaluator,Worker 额外派发 eval job:调裁判 LLM → 产生 score,回写 ClickHouse
- 用户打开 UI,Web SSR 从 ClickHouse 聚合、从 Postgres 取元数据,从 S3 取大 body 详情
整条路径里,SDK 永远只接触 Web;Postgres 不在热写路径;ClickHouse 永远在 Worker 后面。扩容与故障边界都被清晰隔离。
读写路径对比
| 操作 | 热路径组件 | 目标存储 | 延迟 |
|---|---|---|---|
| SDK 写 trace | Web → Redis | Redis 队列 | < 20ms |
| Trace 落库 | Worker → ClickHouse | ClickHouse | ~1-5s(批量) |
| UI 看 trace 列表 | Web → ClickHouse | ClickHouse | ~100-500ms |
| UI 看 trace 详情 | Web → ClickHouse + S3 | ClickHouse + S3 | ~200-800ms |
| 读 Prompt(SDK) | SDK 缓存 → Web → Redis → Postgres | Postgres(冷) | < 5ms(热) |
| 运行在线 eval | Worker → LLM Provider | ClickHouse 回写 score | 秒-十秒 |
可以省掉哪些组件?
完整七件套不是必须的,按规模可以降级:
- Demo / 开发:Web + Postgres + Redis + ClickHouse,四件,官方 docker compose 就是这套,不需要 S3(blob 存本地卷)、不要 Worker(Web 内跑)
- 小生产(< 500 万 trace/月):上 Worker 独立进程,加 MinIO 做 blob,ClickHouse 单机
- 中生产:ClickHouse 2 副本 + Keeper,Postgres RDS HA,Redis 主从,Web/Worker 各 2+ 副本
- 大生产(> 1000 万 trace/月):ClickHouse 分片 + 副本,独立监控栈(Prometheus 看 Langfuse 自身),多可用区
S3 / MinIO 在任何"有真实 prompt 的"环境都省不了——不走 S3 就意味着大 body 进 ClickHouse,表膨胀到一定程度,查询慢到不能用。早装比晚装便宜。
和 OpenTelemetry 的关系
Langfuse 从 2024 底开始原生支持 OpenTelemetry OTLP。这意味着:
- 你已有的 OTel pipeline(OTel Collector → 后端)可以把 LLM span 再分叉一路发给 Langfuse
- 用
@traceloop/instrumentation-*、Arize Phoenix OpenInference 这些 OTel instrumentation,能一键把 LangChain / LlamaIndex / OpenAI SDK 的调用变成 Langfuse trace - 如果你完全不想用 Langfuse SDK,直接发 OTLP 也行
第 4 章我们会演示三种接入方式并排比较。现在只需要记住:Langfuse 既是自己的 SDK,又是 OTLP 兼容后端。
本章小结
- 七个组件:Web / Worker / ClickHouse / Postgres / Redis / S3 / (Keeper)
- 热写路径:SDK → Web → Redis → Worker → ClickHouse,SDK 永远不直连存储
- ClickHouse 承担 OLAP;Postgres 承担 OLTP(元数据);S3 承担大 body
- 按规模降级:demo 四件 / 小生产五件 / 大生产全家桶
- Langfuse 既有自研 SDK 也原生兼容 OpenTelemetry OTLP