Langfuse 不是一套行业标准。它是一个面向 LLM / Agent 应用的 observability、tracing、evaluation 和 prompt management 平台。
更准确的分类是:
| 类型 | 例子 | 作用 |
|---|---|---|
| 标准 / 协议 | OpenTelemetry、W3C Trace Context | 规定数据怎么表示、怎么传播 |
| 通用 APM | Datadog、New Relic、Grafana Tempo | 观察普通后端服务 |
| LLM 观测平台 | Langfuse、LangSmith、Helicone、Arize Phoenix | 观察 LLM 调用、prompt、token、RAG、agent |
| 模型网关 | LiteLLM、NewAPI、OpenRouter、自建 proxy | 管模型流量、鉴权、限流、计费、fallback |
Langfuse 有自己的 trace / observation / score / prompt / dataset 数据模型,也可以通过 SDK、API、OpenTelemetry、框架集成或模型网关上报数据。
采集哪些数据
Langfuse 采集的数据可以分成五类:
Trace:一次完整请求
Span:请求里的中间步骤
Generation:一次模型调用
Score:质量评价
Metadata:业务自定义字段
Trace:请求级信息
Trace 通常代表一次用户请求、一次 agent run、一次 RAG 查询或一次业务任务。
常见字段:
| 字段 | 含义 |
|---|---|
trace_id |
请求唯一 ID |
name |
请求名称,如 chat-request、rag-answer |
user_id |
用户 ID |
session_id |
会话 ID |
input |
用户输入 |
output |
最终输出 |
metadata |
业务自定义信息 |
tags |
标签,如 prod、rag、vip-user |
environment |
环境,如 dev、staging、prod |
release |
应用版本 |
timestamp |
发生时间 |
示例:
{
"name": "support-chat",
"user_id": "user_123",
"session_id": "session_abc",
"input": "我可以退款吗?",
"output": "根据政策,7 天内可以退款。",
"metadata": {
"tenant": "acme",
"plan": "pro",
"channel": "web"
},
"tags": ["prod", "support", "rag"]
}
Generation:模型调用信息
Generation 是 Langfuse 最核心的数据之一。每次模型调用都可以记录:
| 字段 | 含义 |
|---|---|
model |
使用的模型 |
provider |
OpenAI、Anthropic、Gemini、DeepSeek 等 |
input |
prompt / messages |
output |
completion |
usage.input |
输入 token |
usage.output |
输出 token |
usage.total |
总 token |
cost |
调用成本 |
latency |
模型调用耗时 |
temperature |
采样参数 |
max_tokens |
最大输出长度 |
prompt_name |
使用的 prompt |
prompt_version |
prompt 版本 |
metadata |
自定义字段 |
示例:
{
"name": "answer-generation",
"model": "gpt-4.1",
"input": [
{"role": "system", "content": "You are a support agent."},
{"role": "user", "content": "我可以退款吗?"}
],
"output": "根据退款政策,购买后 7 天内可以退款。",
"usage": {
"input": 1200,
"output": 180,
"total": 1380
},
"metadata": {
"temperature": 0.2,
"prompt_version": "v7"
}
}
用 Generation 可以回答:
- 哪个模型最贵?
- 哪个 prompt token 特别长?
- 哪类请求最耗 token?
- 哪个 prompt 版本成本升高?
- 某次回答差时,模型到底看到了什么?
Span:中间步骤信息
Span 用来记录非模型调用的中间步骤。
常见 Span:
| 类型 | 例子 |
|---|---|
| 检索 | vector search、BM25、hybrid search |
| rerank | reranker model 调用 |
| tool call | web search、SQL query、browser action |
| 业务 API | 查订单、查库存、查用户资料 |
| 文件处理 | PDF 解析、chunking、OCR |
| agent step | plan、act、observe、reflect |
| fallback | 主模型失败后切备用模型 |
Span 通常记录:
| 字段 | 含义 |
|---|---|
name |
步骤名 |
input |
输入 |
output |
输出 |
start_time / end_time |
耗时 |
metadata |
自定义信息 |
status |
成功 / 失败 |
error |
错误信息 |
示例:
{
"name": "vector-search",
"input": {
"query": "退款政策",
"top_k": 5
},
"output": {
"documents": ["doc_1", "doc_7", "doc_9"]
},
"metadata": {
"index": "support_kb",
"rerank": true
}
}
Score:质量评价
Score 是对 trace 或 generation 的评价结果。
来源可以是:
| 来源 | 例子 |
|---|---|
| 用户反馈 | 点赞 / 点踩、满意度 |
| 人工标注 | 客服质检人员打分 |
| 程序规则 | JSON 是否合法、是否有引用 |
| LLM-as-a-judge | 相关性、忠实度、是否幻觉 |
| 离线评测 | dataset experiment 结果 |
常见 score:
| 指标 | 含义 |
|---|---|
helpfulness |
是否有帮助 |
relevance |
是否相关 |
faithfulness |
是否忠于上下文 |
correctness |
是否正确 |
toxicity |
是否有害 |
hallucination |
是否幻觉 |
json_valid |
JSON 是否合法 |
citation_present |
是否有引用 |
user_feedback |
用户反馈 |
示例:
{
"name": "faithfulness",
"value": 0.86,
"comment": "回答基本忠于检索内容,但遗漏退款时限。"
}
能不能自定义指标
可以。Langfuse 的 metadata、tags、score、trace name、span name、业务字段都可以自定义。
可以自定义的内容:
| 类型 | 示例 |
|---|---|
| Trace name | checkout-chat、legal-rag |
| Span name | vector-search、rerank、sql-query |
| Metadata | tenant_id、plan、region |
| Tags | prod、vip、ab-test-b |
| Score name | faithfulness、contains_citation |
| Dataset | 自己维护评测集 |
| Prompt | 自己定义 prompt 名称和版本 |
客服机器人可以加:
{
"metadata": {
"tenant": "acme",
"channel": "web",
"user_plan": "enterprise",
"ticket_type": "refund",
"knowledge_base_version": "2026-07-01"
}
}
RAG 系统可以加:
{
"metadata": {
"retriever": "hybrid",
"top_k": 8,
"reranker": "bge-reranker-v2",
"index_version": "kb_2026_07"
}
}
Agent 系统可以加:
{
"metadata": {
"agent_version": "v12",
"tool_count": 5,
"max_steps": 12,
"stopped_reason": "final_answer"
}
}
如何上报
常见上报方式有五种。
方式一:直接用 SDK
适合想精确控制 trace、span、generation 结构的项目。
from langfuse import Langfuse
langfuse = Langfuse(
public_key="pk-lf-...",
secret_key="sk-lf-...",
host="https://cloud.langfuse.com",
)
trace = langfuse.trace(
name="chat-request",
user_id="user_123",
input={"message": "什么是 Langfuse?"},
metadata={
"tenant": "acme",
"environment": "prod",
},
)
generation = trace.generation(
name="answer-generation",
model="gpt-4.1",
input=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "什么是 Langfuse?"},
],
output="Langfuse 是 LLM 应用的观测平台。",
usage={
"input": 100,
"output": 30,
"total": 130,
},
)
langfuse.flush()
优点是结构清楚;缺点是代码侵入相对明显。
方式二:OpenAI / Anthropic SDK wrapper
如果项目已经直接调用 OpenAI 或 Anthropic SDK,可以通过 wrapper 自动捕获模型调用。
优点:
- 改动少
- 自动记录模型输入输出
- 自动记录 token 和 latency
缺点:
- 复杂 agent / tool call 结构不一定足够清楚
- 业务 metadata 仍要自己补
方式三:框架集成
如果项目使用 LangChain、LlamaIndex、Vercel AI SDK、Haystack、Semantic Kernel 等框架,可以用框架集成接入。
优点:
- 自动记录 chain / tool / model call
- agent 步骤更容易形成树状 trace
- 接入成本低
缺点:
- trace 结构取决于框架
- 字段不一定符合业务习惯
- 高质量接入仍需要补 metadata / score
方式四:OpenTelemetry
如果服务已经有 OpenTelemetry,可以把 LLM 调用作为 span 上报,再让 Langfuse 接收或映射。
适合:
- 已经有 OTel 基础设施
- 想和后端服务 trace 打通
- 想把 HTTP / DB / LLM 放在一条链路里
- 不想被单一平台 SDK 绑定太深
注意:OpenTelemetry 是标准;Langfuse 是消费和展示 LLM trace 的平台。OTel 能描述通用 span,但 prompt、completion、token、cost、score 这些 LLM 语义字段仍需要约定和映射。
方式五:通过模型网关接入
如果所有模型调用都经过 LiteLLM、NewAPI 或自建 proxy,可以在网关层统一接入 Langfuse。
优点:
- 应用层改动少
- 所有模型请求统一采集
- 方便统计模型成本、token、latency
- 对多 provider 友好
缺点:
- 网关层只能看到模型调用,不一定知道完整业务上下文
- RAG 检索、tool call、agent step 可能看不到
- 需要应用层补 trace id、user id、session id,才能串起来
更稳的结构是:
应用层上报 trace / span / metadata
网关层上报 generation / token / cost
两边用同一个 trace_id 关联
如何可视化显示
Langfuse UI 通常从四个视角展示数据。
Trace 列表
可以看到最近请求:
name user latency cost status
support-chat user_123 2.1s $0.004 ok
rag-answer user_456 5.8s $0.031 error
agent-run user_789 18.2s $0.12 ok
可以按时间、用户、tag、environment、model、prompt version、score、cost、latency、error 筛选。
Trace 详情
点进一条 trace,可以看到树状结构:
Trace: support-chat
├── Span: classify-intent
├── Span: vector-search
├── Span: rerank
├── Generation: answer-generation
└── Score: user_feedback = thumbs_up
每个节点可以展开看 input、output、metadata、model、token、cost、latency、error。
Dashboard
可以看聚合指标:
- 总请求数
- 总 token
- 总成本
- 平均延迟
- P95 延迟
- 错误率
- 不同模型成本占比
- 不同用户 / tenant 成本
- prompt 版本表现
Evaluation / Dataset / Experiment
可以看:
- 某个 dataset 的测试结果
- 不同 prompt 版本的 score
- 不同模型的回答质量
- 哪些样本失败
- 哪些 regression 新增了错误
已有项目如何接入
不要一上来全量改。按五步走。
第一步:确定要回答的问题
先列出最想知道的问题:
1. 哪些请求最贵?
2. 哪些请求最慢?
3. 用户差评是因为检索错还是模型答错?
4. 哪个 prompt 版本效果更好?
5. agent 失败时卡在哪一步?
再决定要采集哪些字段。不要一开始什么都采,否则很容易变成日志垃圾场。
第二步:先接最外层 Trace
在请求入口创建 trace:
trace = langfuse.trace(
name="chat-request",
user_id=current_user.id,
session_id=session_id,
input=user_message,
metadata={
"tenant": tenant_id,
"environment": "prod",
"app_version": APP_VERSION,
},
tags=["chat", "prod"],
)
这一步先保证每次用户请求都有一个可追踪 ID。
第三步:接模型调用 Generation
把原来的模型调用包一层:
result = llm.call(messages)
trace.generation(
name="main-answer",
model="claude-sonnet-4",
input=messages,
output=result.text,
usage={
"input": result.usage.input_tokens,
"output": result.usage.output_tokens,
"total": result.usage.total_tokens,
},
metadata={
"temperature": 0.2,
"prompt_version": "v7",
},
)
这一步先解决模型到底看到了什么、输出了什么、花了多少 token。
第四步:补关键 Span
不要把所有函数都接成 span。只记录会影响答案质量、成本、延迟的步骤。
RAG 项目优先接:
query rewrite
embedding
vector search
rerank
context assembly
generation
Agent 项目优先接:
planning
tool call
tool result
reflection
final generation
业务机器人优先接:
intent classification
policy lookup
order lookup
generation
human handoff
第五步:接 Score
先接最简单的用户点赞 / 点踩。
再接规则型 score:
JSON 是否合法
是否有引用
是否触发 fallback
最后再接 LLM-as-a-judge:
faithfulness
relevance
correctness
先跑通反馈闭环,再做复杂评测。
接入架构怎么选
小项目
直接 SDK:
应用代码 → Langfuse SDK → Langfuse
简单直接,但对代码有一定侵入。
LangChain / LlamaIndex 项目
用框架集成:
应用代码 → LangChain callback / LlamaIndex callback → Langfuse
适合自动记录 chain、tool、model call。
已经有 LiteLLM / NewAPI 网关
推荐双层接入:
应用层:Trace / Span / user_id / session_id / metadata
网关层:Generation / model / token / cost / latency
共同字段:trace_id
结构类似:
用户请求
↓
应用服务创建 trace_id
↓
RAG / Agent 步骤写 span
↓
模型请求带 trace_id 经过网关
↓
网关把 generation 上报 Langfuse
↓
Langfuse UI 合并展示
这样既能看业务链路,也能看模型成本和质量。
接入注意事项
不要泄露敏感信息
Langfuse 会存 prompt、输入、输出、metadata。里面可能有用户隐私、API key、内部文档、订单信息、代码 secret、商业数据。
接入前要决定:
- 哪些字段脱敏
- 哪些字段不上报
- 是否自托管
- 数据保留多久
- 谁能看 trace
不要把日志粒度打太碎
每个小函数都上报 span,会让 trace 很难读。
优先记录模型调用、RAG 检索、tool call、外部 API、失败 / fallback、质量相关节点。
统一命名
trace、span、score 名称要稳定。
不要一会叫 answer-generation,一会叫 main_llm_call,一会叫 chatgpt_response。命名不稳定,后面聚合会很痛苦。
给业务字段留 metadata
纯模型指标不够。一定要加业务维度:
tenant
user_plan
channel
region
app_version
prompt_version
knowledge_base_version
experiment_group
否则只能看到总体平均,看不到是哪类用户、哪版系统、哪组实验出了问题。
先做最小闭环
最小可用接入是:
Trace + Generation + user feedback
也就是记录一次请求、记录模型输入输出和 token、记录用户点踩 / 点赞。这个闭环跑通后,再加 RAG span、agent span、dataset、experiment。
总结
Langfuse 不是标准,而是一个 LLM observability 平台。它能接入标准协议,也能通过 SDK、框架集成、模型网关或 OpenTelemetry 上报数据。
最稳的已有项目接入路径是:
1. 请求入口创建 Trace
2. 模型调用记录 Generation
3. RAG / Agent 关键步骤补 Span
4. 用户反馈和规则结果写 Score
5. 再逐步接 Dataset / Experiment
如果项目已经有模型网关,推荐应用层记录业务 trace 和 span,网关层记录模型 generation、token、cost,再用 trace_id 串起来。