业务系统接入 Langfuse 后,第一阶段解决的是“能不能看清一次 LLM 请求”。Trace、Span、Generation、Score 都上报以后,你可以打开 Langfuse,看某一次请求的输入、输出、耗时、token、成本、错误和用户反馈。
但如果接下来要做的是一个单独的可视化分析平台,思路就要变一下。
这个平台不应该只是复刻 Langfuse。Langfuse 更适合做单条 trace 调试、prompt 回放、观测链路排障;新的分析平台应该面向业务分析:哪个租户最烧钱、哪个模型最慢、哪个 prompt 版本差评最多、哪个业务场景最容易触发 fallback、RAG 命中率是否下降。
真正要解决的问题是:业务已经把数据上报到 Langfuse 了,如何把这些数据取出来,整理成分析模型,再做一套自己的可视化平台。
先分清两层系统
不要把 Langfuse 和分析平台混成一个东西。
Langfuse:采集、调试、回放单次请求
分析平台:聚合、对比、趋势、业务决策
更合理的结构是:
业务系统 / 模型网关
↓
Langfuse:trace / generation / span / score 原始观测数据
↓
数据同步层:API 拉取、数据库同步或事件双写
↓
分析仓库:PostgreSQL / ClickHouse / BigQuery
↓
分析 API
↓
独立可视化平台
Langfuse 继续做原始链路观测;新平台基于这些数据重新建业务分析层。
平台要回答的问题
如果只是看“某一次请求发生了什么”,Langfuse 已经够用。独立平台真正要回答的是聚合问题。
| 方向 | 典型问题 |
|---|---|
| 成本 | 哪个业务线、租户、用户、模型最烧钱? |
| 性能 | 哪类请求最慢?P95 延迟卡在哪一步? |
| 质量 | 哪些场景差评多?哪个 prompt 版本效果差? |
| 模型 | 不同模型的成本、延迟、质量如何对比? |
| RAG | 检索是否命中?哪个知识库版本效果下降? |
| Agent | tool 成功率、平均 step 数、fallback 情况如何? |
| 业务 | 不同渠道、客户等级、功能模块的 AI 使用情况如何? |
也就是说,分析平台的核心不是再做一个“Trace UI”,而是做 LLM Analytics:把单次请求的观测数据,变成可按业务维度聚合、筛选和下钻的数据资产。
先给结论:怎么选数据路线
| 场景 | 推荐路线 | 原因 |
|---|---|---|
| 使用 Langfuse Cloud,先做 MVP | API 增量同步 | 不碰底层表结构,升级风险低 |
| 自部署 Langfuse,数据量不大 | API 同步或只读库同步 | 实现简单,先验证分析需求 |
| 自部署 Langfuse,数据量较大 | 只读库 / CDC / ClickHouse 同步 | 聚合查询更快,不拖慢 Langfuse |
| 长期内部平台 | 业务系统 / 网关双写 | 不被 Langfuse API 和内部 schema 绑定 |
第一版优先把已有 Langfuse 数据取出来,不急着改业务链路。等指标和页面稳定后,再把数据源前移到内部 SDK 或模型网关。
数据怎么获取
有三条路线。它们不是互斥关系,通常是从 A 开始,逐步走向 C。
路线 A:通过 Langfuse API 拉取
适合 Langfuse Cloud,或不想依赖底层数据库结构的团队。
Langfuse API
↓
Sync Worker
↓
Analytics DB
↓
Dashboard
同步任务按时间增量拉取,至少覆盖这些对象:
traces
observations / generations / spans
scores
sessions
prompt versions
metadata
注意不要只按“上次同步时间之后的新数据”拉。LLM trace 常常是先创建 trace,后面再补 generation、score、output、latency。如果窗口太窄,会漏掉后续更新。
推荐策略:
每 1-5 分钟同步一次
每次同步 now - 10min 到 now
按 trace_id / observation_id 做 upsert
每天补跑一次过去 24h 的修正任务
这条路最稳,缺点是受 API 分页、字段暴露和限流影响。适合第一版 MVP。
需要注意两点:
1. API 拉到的是 Langfuse 的观测对象,不等于已经适合分析
2. 拉回后必须转成自己的 fact / dim 表,而不是直接把 JSON 扔给前端
路线 B:自部署 Langfuse 时读只读库
如果 Langfuse 是自部署,并且数据量较大,可以从 Langfuse 的数据库或 ClickHouse 做只读同步。
但不要让前端直接查 Langfuse 生产库。分析查询通常是大范围聚合,和 Langfuse 自己的 trace 查询负载不同。更稳的方式是:
Langfuse DB / ClickHouse
↓
只读同步 / CDC / 定时 ETL
↓
analytics schema
↓
分析平台
这样做有三个好处:
- 避免拖慢 Langfuse;
- 避免前端绑定 Langfuse 内部表结构;
- 可以补充业务维度表,比如租户、渠道、套餐、工单类型。
数据量小可以先用 PostgreSQL + JSONB;数据量大、聚合查询多时,用 ClickHouse 更合适。
路线 C:业务系统或模型网关双写
长期最稳的是把数据源前移,不只从 Langfuse 取。
业务系统 / LLM 网关
↓
统一观测事件
├── Langfuse
└── Analytics Warehouse
或者:
内部 obs SDK
├── LangfuseAdapter
├── AnalyticsAdapter
└── NoopAdapter
这样 Langfuse 和分析平台都是下游消费者。以后即使换掉 Langfuse,分析平台也不会断。
这条路适合长期平台化,但第一版不一定要马上做。建议先用 API / DB 同步验证需求,再把稳定指标前移到双写链路。
推荐落地路线
实际项目里可以分两阶段。
第一阶段:先用 Langfuse 作为数据源。
Langfuse
↓
langfuse-sync-worker
↓
PostgreSQL / ClickHouse
↓
分析平台
目标是快速验证三件事:
1. 业务到底想看哪些图
2. 哪些筛选条件最常用
3. 现在上报的 metadata 缺了什么
第二阶段:做统一观测事件层。
业务系统 / 模型网关
↓
统一事件模型
├── 写 Langfuse
└── 写分析仓库
目标是让分析平台不再受 Langfuse API、分页、内部表结构影响。
分析仓库的数据模型
不要把 Langfuse 原始 JSON 直接丢给前端。要转成分析友好的事实表。
fact_traces
一行代表一次完整 AI 请求。
trace_id
project_id
app_name
environment
tenant_id
user_id
session_id
trace_name
status
started_at
ended_at
latency_ms
total_cost
total_input_tokens
total_output_tokens
total_tokens
model_list
prompt_name
prompt_version
tags
metadata
它回答:请求量、成本、延迟、错误、租户使用量、功能使用量。
fact_observations
一行代表 trace 里的一个节点,可以是 span、generation 或 event。
observation_id
trace_id
parent_observation_id
type -- span / generation / event
name
status
started_at
ended_at
latency_ms
input_ref / input_summary
output_ref / output_summary
metadata
error_type
error_message
它支撑 trace 树、步骤耗时、RAG / tool / fallback 分析。生产环境里不建议把大段 prompt、completion、RAG context 全塞进明细表,可以只放摘要和对象存储引用。
fact_generations
模型调用建议单独拆出来,方便成本和模型分析。
generation_id
trace_id
observation_id
provider
model
input_tokens
output_tokens
total_tokens
cost
latency_ms
first_token_latency_ms
prompt_name
prompt_version
status
error_type
started_at
ended_at
input_ref / output_ref
metadata
它回答:哪个模型贵、哪个模型慢、哪个 prompt 版本 token 暴涨、哪类请求成本异常。大文本同样放对象存储,表里只保留引用、摘要和聚合字段。
fact_scores
一行代表一次评价。
score_id
trace_id
observation_id
score_name
score_value
score_source -- user / human / rule / llm_judge
comment
created_at
metadata
它回答:差评率、低分场景、幻觉率、JSON 合法率、引用缺失率。
维度表
还需要几张业务维度表:
dim_tenant
dim_user
dim_model_price
dim_prompt_version
dim_app
dim_release
dim_knowledge_base
尤其是 dim_model_price。模型价格会变,私有模型和代理模型价格也不同。不要只把 cost 当成 Langfuse 给出的静态字段,最好能按历史价格重算。
provider
model
input_price_per_1m_tokens
output_price_per_1m_tokens
effective_from
effective_to
关键 metadata 必须补齐
如果业务系统只上报 prompt、completion、token、cost,后面只能做模型调用统计,看不出业务意义。
建议每条 trace 至少带:
tenant_id
user_id
session_id
app_name
feature_name
environment
release
channel
request_type
prompt_name
prompt_version
model
provider
trace_id
RAG 场景额外带:
retriever
top_k
reranker
index_name
index_version
doc_ids
chunk_ids
similarity_scores
rerank_scores
citation_present
Agent 场景额外带:
agent_name
agent_version
tool_name
tool_count
step_index
max_steps
stopped_reason
fallback_used
质量分析额外带:
user_feedback
human_review_score
rule_score
llm_judge_score
resolved
escalated_to_human
这一步很关键。没有业务 metadata,分析平台只能看到“模型请求很多”,但看不出“哪个产品功能出问题”。
同步任务怎么做
第一版可以做一个独立 worker:
langfuse-sync-worker
↓
1. 拉 traces
2. 拉 observations / generations
3. 拉 scores
4. 标准化字段
5. upsert 到 analytics tables
6. 记录 checkpoint
需要一张同步状态表:
sync_checkpoint
---------------
source_name
last_synced_at
last_window_start
last_window_end
status
error
updated_at
写入必须幂等:
trace_id 唯一
observation_id 唯一
score_id 唯一
重复拉取时 upsert
这样才能安全使用 overlap window。
可视化第一版做什么
不要第一版就做复杂大屏。先做五个必选页面,再补一个专项页面。
1. 总览
总请求数
总 token
总成本
平均成本 / 次
平均延迟
P95 延迟
错误率
用户反馈好评率
低分 trace 数
筛选条件:
时间
业务线
tenant
用户
模型
环境
prompt version
trace name
2. 成本分析
每日成本趋势
按模型成本排行
按 tenant 成本排行
按业务功能成本排行
输入 / 输出 token 占比
单位请求成本分布
这个页面回答“钱花到哪里去了”。
3. 延迟和错误分析
P50 / P95 / P99 latency
first token latency
模型调用耗时
RAG 检索耗时
tool call 耗时
fallback 次数
error rate
timeout rate
这个页面回答“慢在哪里、错在哪里”。
4. 质量和反馈分析
好评率
差评率
平均 score
低分 trace 分布
hallucination rate
citation missing rate
JSON invalid rate
这个页面必须能从聚合图下钻到具体 trace。
5. Trace 列表和详情(必选)
Trace 列表字段:
时间
trace name
user_id
tenant
status
latency
cost
model
score
tags
Trace 详情仍然是最重要的排障页面:
Trace: support-chat
├── Span: vector-search
├── Span: rerank
├── Generation: answer
├── Span: tool-call
└── Score: user_feedback = thumbs_down
每个节点展开看:
input
output
metadata
latency
token
cost
error
第一版如果时间紧,可以不完全重做 trace 详情,先在分析平台里提供“打开 Langfuse 原始 trace”的链接。聚合分析自己做,单条回放交给 Langfuse。
6. RAG / Agent 专项页(第二阶段)
RAG 看:
知识库版本
检索器类型
top_k
命中文档数
chunk 命中率
相似度分数
rerank 分数
引用是否出现
回答是否忠于 context
Agent 看:
平均 step 数
tool call 次数
tool 成功率
tool 错误率
fallback 次数
循环 / 超步数终止
stopped_reason
这类页面比普通大盘更能暴露 AI 应用的问题。
权限和脱敏
分析平台不能忽略权限。
至少要做:
tenant 级隔离
项目级权限
用户 PII 脱敏
input / output 可开关采集
字段级脱敏规则
按环境采样
按错误全量采集
生产环境建议支持三档:
不采集正文,只采 token / cost / latency
采集摘要,不采全文
采集全文,但做字段级脱敏
否则客服、医疗、金融、企业知识库场景会有数据合规风险。
最小可用版本
第一版只做这些就够:
1. 从 Langfuse 同步 traces / observations / scores
2. 建 fact_traces / fact_observations / fact_generations / fact_scores
3. 做总览、成本、延迟、质量、Trace 列表五个页面
4. Trace 详情先跳转 Langfuse,后续再自研
5. 补齐 tenant_id、feature_name、prompt_version、model、cost、latency、feedback
6. 大 input / output / context 先放对象存储,分析表只放摘要和引用
这已经能回答大部分管理和排障问题:
今天 AI 请求量多少?
花了多少钱?
哪个模型最贵?
哪个业务功能最慢?
哪个 prompt 版本差评最多?
哪些用户点踩了?
差评 trace 里模型到底看到了什么?
最终形态
长期来看,最好不要让分析平台只依赖 Langfuse。
更稳的最终结构是:
业务系统 / 模型网关
↓
统一观测事件层
├── Langfuse:调试和回放
├── ClickHouse:聚合分析
├── Object Storage:大输入输出和 RAG context
└── BI / 自研 Dashboard:业务可视化
Langfuse 是链路显微镜;分析平台是业务仪表盘。
前者看清一次请求,后者看清一类问题。要做独立可视化平台,关键就是把已经上报到 Langfuse 的观测数据,转成稳定的数据资产,再围绕成本、延迟、质量和业务维度搭建自己的分析平台。