Skip to content

阶段 2:Langfuse 核心概念

预计学习时间:1 天
生活类比主线:Langfuse = 餐厅后厨的「一单到底」监控系统


目录

  1. 概念总览
  2. Trace:一张完整订单
  3. Observation:做菜的每一步
  4. Session:一桌客人的整场饭局
  5. Observation 类型详解
  6. 属性传播机制
  7. 数据在 UI 里长什么样
  8. 常见问题 QA
  9. 学习检查

1. 概念总览

Langfuse 把应用运行数据组织成三层结构:

Langfuse 核心概念层级

Session(可选,多轮对话)
  └── Trace(一次请求/操作)
        └── Observation(请求内的每一步,可嵌套)
              └── Observation(子步骤)
                    └── ...

餐厅类比

Langfuse 概念餐厅类比说明
Session一桌客人从进店到离店的整场体验多轮交互的容器
Trace一张订单(从下单到出餐)单次操作的完整记录
Observation做菜的每个步骤(切菜、炒菜、装盘)有起止时间的工作单元
Generation特别标记的「大师傅炒菜」步骤专指 LLM 调用
Tool「去冷库取食材」外部 API / 函数调用

2. Trace:一张完整订单

2.1 定义

Trace 代表一次完整的用户请求或业务操作。

例如:

  • 用户问 chatbot 一个问题 → 1 条 Trace
  • 用户点击「生成周报」→ 1 条 Trace
  • Claude Code 里你发一条消息、AI 完整回复 → 1 条 Trace(本仓库的实现方式)

2.2 Trace 包含什么

Trace: "用户问:北京明天天气怎么样?"
├── input:   用户原始问题
├── output:  最终回复给用户的内容
├── user_id: "user_123"(可选)
├── session_id: "sess_abc"(可选)
├── tags:    ["weather-bot", "prod"]
├── metadata: {"app_version": "1.2.0"}
├── latency: 总耗时
└── observations: [ ... 所有子步骤 ... ]

2.3 生活例子:点外卖

你在 App 里点了一份黄焖鸡米饭,这一单就是一条 Trace:

Trace ID: order_20260605_001
  输入:黄焖鸡米饭 × 1,少辣
  输出:预计 30 分钟送达
  用户:张三
  总耗时:28 分钟

不管中间经历了「接单 → 备菜 → 炒菜 → 配送」,对外就是一单


3. Observation:做菜的每一步

3.1 定义

Observation 是 Trace 内部的一个工作步骤,有明确的开始和结束时间,可以嵌套。

Trace: 回答天气问题

├── Observation (span): "解析用户意图"          50ms

├── Observation (tool): "调用天气 API"         200ms
│   input:  {city: "北京", date: "明天"}
│   output: {temp: 28, weather: "晴"}

├── Observation (retriever): "检索知识库"     80ms

└── Observation (generation): "GPT-4o 生成回复"  1200ms
    model: gpt-4o
    input:  [system prompt + 天气数据]
    output: "北京明天晴,28°C..."
    usage:  {input: 320, output: 45, total: 365}

3.2 Observation vs Trace

TraceObservation
粒度一整次请求请求内的一步
数量关系1 个 Trace 含多个 Observation多个 Observation 属于 1 个 Trace
类比一整张订单订单里的每个工序

3.3 嵌套关系

Observation 可以父子嵌套,形成树状结构:

Agent 决定调用工具
└── Tool: 查数据库
    └── Span: SQL 执行

就像做黄焖鸡:

主工序:烹饪
├── 子工序:焯水
├── 子工序:炒糖色
└── 子工序:炖煮

4. Session:一桌客人的整场饭局

4.1 定义

Session 把多条相关的 Trace 归到同一个会话,适合多轮对话场景。

Session: "sess_abc"(用户张三的聊天)
├── Trace 1: "你好" → "您好,有什么可以帮您?"
├── Trace 2: "查订单" → "您有 2 笔待发货订单..."
└── Trace 3: "第一笔什么时候发?" → "预计明天..."

4.2 生活类比

  • Trace = 你向服务员提的一个具体问题
  • Session = 你在这家餐厅坐了一晚上的所有问答

没有 Session 也能用 Langfuse,但多轮 Agent / Chatbot 强烈建议设置 session_id,否则无法按对话聚合分析。

4.3 什么时候需要 Session

场景是否需要 Session
单次问答 API可选
多轮 Chatbot✅ 推荐
Claude Code 编程助手✅ 一个 coding session
批量离线任务通常不需要

5. Observation 类型详解

Langfuse 支持多种 Observation 类型,方便在 UI 里过滤和分析:

类型含义生活类比典型字段
span普通工作单元切菜、装盘name, input, output, duration
generationLLM 调用大师傅炒菜(核心环节)model, prompt, completion, usage, cost
tool工具/API 调用去冷库取食材tool name, input, output
retriever检索/RAG查菜谱本query, documents
agentAgent 决策步骤主厨决定做什么菜plan, actions
chain链式编排步骤传菜窗口交接pipeline step
embedding向量化调用把食材切标准化model, usage
event瞬时事件火警铃响了一下name, metadata
guardrail安全护栏食材安检check result

5.1 Generation 为什么特殊

Generation 是 LLM 应用的「主角」。它额外记录:

python
{
  "model": "gpt-4o",
  "model_parameters": {"temperature": 0.7, "max_tokens": 1024},
  "usage_details": {
    "input": 500,
    "output": 120,
    "total": 620
  },
  "cost_details": {
    "input": 0.0025,
    "output": 0.0012,
    "total": 0.0037
  }
}

普通 span 不自动算 token 和费用;generation 会。

5.2 类型怎么选

简单原则:

  • 调了 LLM → generation
  • 调了外部 API / 函数 → tool
  • 查了向量库 → retriever
  • Agent 在「思考下一步」 → agent
  • 其他内部逻辑 → span

6. 属性传播机制

Trace 上设置的属性会自动传播到其下所有 Observation:

python
trace = langfuse.trace(
    name="weather-query",
    user_id="user_123",      # ← 传播到所有子 observation
    session_id="sess_abc",   # ← 传播
    tags=["prod", "v2"],     # ← 传播
    metadata={"region": "cn"} # ← 传播
)

生活类比:订单上贴了「VIP 客户」「包间 8 号」标签,后厨每个工序的单据上都会自动带上这些标签,不用每道工序手写一遍。

常用属性

属性用途
user_id按用户查问题、算人均成本
session_id聚合多轮对话
tags环境、功能模块、实验分组
metadata任意 JSON,如 app 版本、实验 ID
release发布版本号
versionPrompt 版本

7. 数据在 UI 里长什么样

打开 Langfuse Cloud → Traces 页面,你会看到:

┌─────────────────────────────────────────────────────────────┐
│ Traces                                                       │
├──────────┬──────────┬────────┬────────┬───────────────────┤
│ Time     │ Name     │ Latency│ Tokens │ User              │
├──────────┼──────────┼────────┼────────┼───────────────────┤
│ 10:00:01 │ chat-turn│ 2.3s   │ 1,240  │ user_123          │
│ 10:00:15 │ chat-turn│ 1.8s   │ 890    │ user_123          │
└──────────┴──────────┴────────┴────────┴───────────────────┘

点开一条 Trace,左侧是树状时间线

chat-turn (2.3s)
├── parse-intent (50ms)
├── tool:weather-api (200ms)
└── generation:gpt-4o (1.8s)  ← 点击可看 Prompt/Completion

右侧显示选中节点的 input/output、token、metadata。


8. 常见问题 QA

Q1: Trace 和 OpenTelemetry 的 Trace 是一回事吗?

基本是。Langfuse Trace 与 OTel Trace 共享同一个 trace_id。详见 3_langfuse_and_opentelemetry.md

Q2: 一次 LLM 调用应该建 Trace 还是 Generation?

  • 整个用户请求 → 建 Trace
  • 其中的 LLM 调用 → 在 Trace 下建 Generation

不要每个 LLM 调用都单独建 Trace,否则无法看完整业务链路。

Q3: Observation 的 input/output 会无限大吗?

SDK 和平台都有截断策略。生产环境应对超大 payload 做截断或脱敏(见 7_best_practices.md)。

Q4: 没有 LLM 的纯业务逻辑需要记录吗?

建议记录关键步骤为 span,方便定位「慢在哪」。但不必逐行代码都 trace。


9. 学习检查

  • [ ] 能画出 Session → Trace → Observation 三层结构
  • [ ] 能说出 Generation 和 Span 的三个区别
  • [ ] 能举例说明何时用 tool vs retriever 类型
  • [ ] 理解 user_id / session_id 的传播行为
  • [ ] 已在 Langfuse UI 中点开一条 Trace 并对照本文概念

下一章3_langfuse_and_opentelemetry.md