Langfuse 接入指南:指标、上报与可视化

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-requestrag-answer
user_id 用户 ID
session_id 会话 ID
input 用户输入
output 最终输出
metadata 业务自定义信息
tags 标签,如 prodragvip-user
environment 环境,如 devstagingprod
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-chatlegal-rag
Span name vector-searchreranksql-query
Metadata tenant_idplanregion
Tags prodvipab-test-b
Score name faithfulnesscontains_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 串起来。