本文面向 mystu 铁矿石价格预测 Agent 的日常开发与排障,结合 Langfuse Cloud 实际 Trace 界面(如 mystu-agent-stream)说明:上传到 Langfuse 的数据具体是什么如何在 UI 里学习查看能从中获得什么价值,以及在日常开发中如何借助 Trace 提升质量、加快迭代

技术实现与采集链路见 langfuse-tracing-explained.md;Cloud 密钥配置见 AGENTS.md 环境变量表。


1. 先建立直觉:Trace 不是日志,是「可回放的黑匣子」

普通日志告诉你:某行代码执行了、某个异常抛出了
Langfuse Trace 告诉你:用户说了什么 → Agent 读了哪些记忆 → 模型想了什么 → 调了哪些工具 → 每一步花了多久、多少 token、多少钱

对 mystu 这类 LangGraph + DeepSeek + 工具 + HITL 审批 的 Agent,一次用户提问背后往往有十几次内部步骤。没有 Trace,你只能看到最终 JSON 或 SSE 文本;有了 Trace,你能逐步展开整条推理链。

用户消息

记忆注入 SystemMessage

LangGraph 图执行

ChatDeepSeek 第 1 轮

要调工具?

Tool Span

ChatDeepSeek 第 2 轮

直接回复

Langfuse UI 树状展示

一句话:Trace 是「一次 Agent 运行的完整录像」;Session 是「一段对话里多次运行的合集」。


2. 上传到 Langfuse 的数据具体是什么

mystu 通过 Langfuse Python SDK v4 + LangChain CallbackHandler 上报。数据经 HTTPS 批量发到 Cloud Ingest API(https://cloud.langfuse.com/api/public/otel/v1/traces),最终在 UI 的 Tracing 页展示。

下面按 从粗到细 说明每一层字段的含义,并对照你在 Cloud 上看到的列名。

2.1 Trace 层(一次 HTTP 请求 = 一条 Trace)

mystu 的三条 Agent 接口各产生独立 Trace,名称固定为:

接口 Trace 名称 Tag
POST /agent/api/chat mystu-agent-chat chat
POST /agent/api/chat/stream mystu-agent-stream stream
POST /agent/api/chat/resume mystu-agent-resume resume

Trace 层会上传:

字段 含义 mystu 来源
Trace ID 全局唯一标识 SDK 自动生成
Trace Name 可检索的名称 langfuse_trace_name metadata
Session ID 同一会话的多条 Trace 归组 thread_id(UUID)
User ID 按登录用户筛选 mystu user_id
Tags 轻量分类 chat / stream / resume
Start / End Time 整次运行起止 Callback 生命周期
Latency 总耗时(秒) UI 列表「Latency (s)」列
Environment 环境标识 .envLANGFUSE_TRACING_ENVIRONMENT
Metadata 业务扩展字段 thread_iduser_idapillm_modeldecision(resume 时)

不会单独作为 Trace 根节点上传、但会出现在子节点里的:

  • FastAPI 路由层 HTTP 请求体(mystu v1 未做 HTTP 根 trace)
  • 用户 Session Cookie、密码等鉴权信息(不应出现在 trace 中)

2.2 Observation 层(Trace 里的树节点)

Trace 展开后是一棵 Observation 树。你在 Cloud UI 表格里看到的每一行(ChatDeepSeekLangGraphtodoListMiddleware.before_model 等)都是一个 Observation。

常见 type 与 mystu 中的对应关系:

UI 中的 Name Type 实际上传了什么
LangGraph SPAN 整图执行的起止;子节点包含 model、tool、middleware
ChatDeepSeek GENERATION 一次大模型调用:messages in → AIMessage out
todoListMiddleware.before_model SPAN deepagents 中间件在调模型前的钩子(状态变更)
todoListMiddleware.after_model SPAN 模型返回后的中间件处理
run_createAgent SPAN LangGraph 内部节点 / 子链
工具名(如 place_order、记忆工具、MCP 天气) SPAN 工具名 + 入参 + 返回值
RunnableSequence SPAN LangChain 组合 Runnable 的包装层
GENERATION(ChatDeepSeek)——最有价值的节点

这是开发中最常打开的节点。上传内容示例:

Input(模型看到的 prompt):

{
  "messages": [
    {
      "role": "system",
      "content": "## 用户长期记忆\n- 偏好普氏 62% 指数\n..."
    },
    {
      "role": "human",
      "content": "你是说"
    }
  ]
}

对应 mystu 中 _build_invoke_messages 组装的结果:记忆 SystemMessage + 用户 HumanMessage + 历史 checkpoint 消息

Output(模型返回):

{
  "role": "assistant",
  "content": "……",
  "tool_calls": [...]
}

Usage / 成本相关(自动采集):

字段 UI 列名 说明
Input Tokens Input Tokens prompt 侧 token
Output Tokens Output Tokens 生成侧 token
Total Tokens Total Tokens 合计
Input / Output / Total Cost Cost ($) Cloud 按模型单价估算

Metadata(GENERATION 常见键):

示例 含义
ls_model_name deepseek-chat 实际模型名
ls_provider deepseek 提供商
ls_temperature 0.7 采样温度
ls_max_tokens 4096 最大生成 token
langgraph_checkpoint_ns ... LangGraph checkpoint 命名空间
langgraph_node model / tools 当前图节点
langgraph_step 数字 图执行步序
langgraph_path 路径数组 在子图中的位置
is_langchain true LangChain 集成标记

这些 metadata 对排障极有用:你可以确认某次慢请求是不是因为 max_tokens 过大、是不是卡在某个 graph 节点

SPAN(工具 / 中间件 / 图节点)

Input:工具调用参数 JSON,或中间件进入时的 state 摘要。
Output:工具返回值、或 {"graph": null, "update": {...}} 这类 state patch。

对 mystu 的 HITL 工具 place_order,Span 里能看到:

  • 模型拟下单的 contractsidequantity
  • 若用户尚未 approve,Trace 在 interrupt 前停止,Span 可能只到「tool call 意图」
流式 /chat/stream 额外行为

流式场景下,GENERATION 的 output 会随 token 逐步更新;mystu 在 astream_chatfinallysafe_flush(),保证 SSE 结束后完整 span 写入 Cloud。
因此在 UI 里,stream 与 chat 的 Trace 结构相同,区别主要在 Tag 为 stream、Trace 名为 mystu-agent-stream

2.3 Session 与 User(跨 Trace 聚合)

概念 上传时机 在 UI 哪里看
Session 每条 Trace 携带 session_id = thread_id 左侧 Sessions,或 Trace 详情页 Session 链接
User 每条 Trace 携带 user_id 左侧 Users,按用户统计成本与行为

典型场景:用户先发 /chat 触发 HITL interrupt,再发 /chat/resume approve——这是 两条 Trace、同一个 Session。在 Sessions 视图里能一次看完「提问 → 待审批 → 批准后执行」全故事。

2.4 什么不会自动上传(避免误解)

不会上传 原因
Checkpoint SQLite 原始 blob 存在 mystu 本地 data/checkpoints.sqlite,不是 Langfuse 职责
MySQL 用户表、Redis Session 业务鉴权数据,与 LLM 观测无关
未命中采样的请求 LANGFUSE_SAMPLE_RATE < 1.0 时部分请求无 Trace
tracing 鉴权失败后的请求 mystu 启动时 auth_check 失败会降级,不再注入 Callback

2.5 数据上传时机小结

Langfuse Cloud Langfuse SDK CallbackHandler mystu Agent Langfuse Cloud Langfuse SDK CallbackHandler mystu Agent 图开始 / 模型开始 / 工具开始 构建 Observation 入内存队列 模型结束 / 工具结束 / 图结束 更新 output / usage safe_flush() HTTPS 批量 POST(OTLP) 200 OK(失败仅打日志,不影响对话)

3. 如何在 Langfuse Cloud 里学习查看 Trace

以下以 Cloud 项目 Tracing 页(https://cloud.langfuse.com/project/.../traces)为准。自托管 UI 布局基本一致。

3.1 界面导览(对照截图)

┌─────────────────────────────────────────────────────────────┐
│  Langfuse Cloud    My Project    [Past 1 day ▼]  [Search]   │
├──────────┬──────────────────────────────────────────────────┤
│ Home     │  Traces 列表                                      │
│ Tracing ◀│  ┌────────────────────────────────────────────┐  │
│ Sessions │  │ Start Time │ Name │ Trace Name │ Input │… │  │
│ Users    │  │ 10:50:31   │ ChatDeepSeek │ mystu-agent-stream │  │
│ …        │  │ 10:50:31   │ LangGraph    │ mystu-agent-stream │  │
│          │  └────────────────────────────────────────────┘  │
│ Filters  │  点击某行 → 右侧/详情页展开 Observation 树        │
│ Latency  │                                                  │
│ Tokens   │                                                  │
│ Scores   │                                                  │
└──────────┴──────────────────────────────────────────────────┘

左侧 Filters 常用项:

筛选项 用法
Latency (s) 找慢请求,例如 > 10
Total Tokens / Cost 找贵请求、异常长上下文
Trace Name mystu-agent-stream 只看流式
Tags stream / chat / resume
Session ID 粘贴 thread_id 看整段对话
User ID 按 mystu 登录用户排查

顶部 Search 支持类 SQL 语法(以 Cloud 当前文档为准),例如:

tags:stream
name:ChatDeepSeek
latency:>5

3.2 第一次看 Trace:推荐点击顺序

拿到一条 mystu-agent-stream 后,按此顺序读:

1. 看 Trace 根信息
名称 / Session / User / 总 Latency

2. 展开 LangGraph 根 Span

3. 找到 ChatDeepSeek GENERATION

4. 读 Input messages
记忆 + 用户话 + 历史

5. 读 Output
纯文本 or tool_calls

有 tool_calls?

6. 点开工具 Span
核对参数与返回值

7. 看 Tokens / Cost / Metadata

8. 若有多轮 Generation
重复 3–7

读 Input 时要问的三个问题:

  1. SystemMessage 里的记忆对不对? —— 排查「Agent 忘了用户偏好」类问题
  2. HumanMessage 是不是用户原话? —— 排查前端传参或 thread 串线
  3. 历史消息是否过多? —— 排查 token 暴涨、变慢

读 Output 时要问的两个问题:

  1. 模型是否该调工具却没调? —— 改 prompt 或 iron_ore_forecast.md 规则
  2. tool_calls 参数是否合理? —— 改工具描述或加 HITL

3.3 Sessions 视图:一段对话的「连续剧」

路径:Observability → Sessions

  1. Session ID(= mystu thread_id)搜索
  2. 时间线上排列该会话下所有 Trace(chat + resume + 再次 chat)
  3. 适合还原:中断审批前后用户连问三句 的完整脉络

3.4 Users 视图:按人统计

路径:Observability → Users

  • 某测试账号是否刷了大量请求
  • 单用户 token / 成本是否异常
  • 对比不同角色(admin / user)的使用模式

3.5 与 mystu 本地信息的对照表

你在 mystu 有什么 在 Langfuse 找什么
浏览器里的 thread_id Session ID / Trace metadata thread_id
登录用户名 / id User ID
SSE 里看到的最终回复 最后一个 ChatDeepSeek 的 Output
「工具待审批」卡片 chat Trace 末尾 + resume Trace;Tag resume + metadata decision
.envLLM_MODEL Generation metadata ls_model_name

4. 从 Trace 里能获取什么价值

4.1 开发阶段

价值 具体能做什么
可见性 不再猜「模型到底看了什么」;Input 里 messages 一字不差
可复现 把某条 Generation 的 Input 复制到 Playground(Langfuse 左侧)或本地 CLI 重跑
定位瓶颈 Latency 列 + 树深度:是模型慢、工具慢还是图编排慢
Token / 成本意识 改 prompt 前后对比 Total Tokens,避免记忆注入过长
工具契约验证 Tool Span 的 args 是否与 @tool schema 一致

4.2 测试与联调

价值 具体能做什么
回归对比 iron_ore_forecast.md 后,同一句提问对比两次 Trace 的 tool_calls 差异
流式完整性 确认 mystu-agent-stream 的 Output 与浏览器 SSE 最终文本一致
HITL 全链路 Session 里 chat + resume 两条 Trace 是否衔接、decision 是否写入 metadata
多用户隔离 不同 user_id 的 Trace 是否各自独立、记忆是否未串线

4.3 上线后运维(若启用生产 tracing)

价值 具体能做什么
故障排查 用户报「答非所问」→ 用 Session ID 打开 Trace 看 Input
成本监控 Dashboard 看日 token / 费用趋势(Cloud 内置)
质量趋势 配合 Scores(人工或 LLM 评分)看回复质量是否下降
采样降本 生产 LANGFUSE_SAMPLE_RATE=0.1 仍保留统计代表性

5. 什么场景「需要」打开 Trace

不是每次改代码都要看 UI,但以下场景 强烈建议 打开 Langfuse:

5.1 必看场景

场景 为什么必须看 Trace
模型行为不符合预期 只有 Input 能证明「它到底读了什么规则/记忆」
工具该调未调 / 乱调 Output 里 tool_calls 与 Tool Span 是 Ground Truth
HITL 审批异常 需对比 chat 与 resume 两条 Trace
流式输出缺字 / 截断 对比 stream Trace 的 GENERATION Output 与前端
延迟投诉(>5s) Latency + 各 Span 耗时定位是模型还是工具
Token 费用突然升高 Input 是否注入了过长记忆或重复 system prompt
多轮对话「失忆」 Session 内多条 Trace 的 messages 顺序与 checkpoint 是否一致

5.2 可选但高效场景

场景 用法
改完 system prompt 抽 3 条典型问题看 Generation Output
新增 MCP / 内置工具 看首条 Tool Span 参数是否被模型理解
调整 LANGFUSE_SAMPLE_RATE 确认采样后仍能看到代表性 Trace
Code Review Agent 相关 PR Reviewer 贴 Trace 链接比贴日志更有说服力

5.3 不必依赖 Trace 的场景

场景 更合适的手段
401 / 500 纯接口错误 服务端日志 + .env 配置
MySQL / Redis 连接失败 基础设施监控、conftest 式单测
静态页面样式问题 浏览器 DevTools
Checkpoint 文件损坏 本地 SQLite + LangGraph 文档

6. 日常开发工作流:用 Trace 提升质量、加快效率

下面是一套可在 mystu 团队内复用的 「Trace 驱动开发」 节奏。

6.1 功能开发:先定义「Trace 里应长什么样」

在写 Agent 行为(改 prompt、加工具)之前,先写一句 可观测验收标准

用户问「帮我查普氏 62 近期走势」时,Trace 中应出现:
- 1 次 ChatDeepSeek GENERATION
- 0 或 1 次行情相关 Tool Span(视工具设计)
- Output 不含「我是通用 AI 助手」类违禁自称
- Total Tokens < 8000

开发完成后,在 Cloud 搜 trace_name:mystu-agent-chat对照清单打勾——比纯人工点 UI 测更快、可重复。

6.2 本地调试循环(5 分钟一轮)

改代码 / prompt

python main.py 重启

前端或 curl 发一条 chat/stream

Cloud Tracing 刷新
Filter: Past 15 min

Generation Input/Output OK?

提交 PR / 继续下一功能

效率技巧:

  1. 固定测试话术 —— 例如 always 用「你是说」+ 固定 thread_id 便于 Session 筛选
  2. 浏览器书签 —— Cloud Tracing 页 + Filter tags:stream
  3. 并行看 Session 与 Trace —— 两个 Tab,一个看整段对话,一个看单次细节
  4. 复制 Input 到 Playground —— Langfuse 左侧 Prompt Management → Playground,免改代码试 prompt

6.3 排障剧本(按现象查 Trace)

现象 A:「Agent 没按记忆回答」
  1. Session ID = 用户 thread_id
  2. 打开最新 ChatDeepSeek → Input → messages[0] SystemMessage
  3. 若无记忆块 → 查 mystu 记忆 API / _build_invoke_messages
  4. 若有记忆但模型忽略 → 改 iron_ore_forecast.md 中记忆使用规则,再对比 Trace
现象 B:「下单没有弹出审批」
  1. 找 chat Trace → 最后 ChatDeepSeek Output 是否含 place_order tool_calls
  2. 若无 tool_calls → prompt / 模型问题
  3. 若有 tool_calls 但前端无 interrupt → 查 API 响应 status: interrupt,Trace 仍到 interrupt 前
  4. 打开 resume Trace → metadata decision 是否为 approve / reject
现象 C:「流式很慢」
  1. Filter tags:stream,按 Latency 降序
  2. 看 LangGraph 子 Span 哪一段最长
  3. 若 ChatDeepSeek GENERATION 占绝大部分 → 模型侧或 input 过长
  4. 若某 Tool Span 长 → 优化工具或改 MCP 超时
现象 D:「Cloud 401 / 无 Trace」
  1. 查 mystu 启动日志是否有「Langfuse client 已初始化并通过鉴权」
  2. .env 使用 LANGFUSE_BASE_URL=https://cloud.langfuse.com(勿留 localhost:3000
  3. 密钥须来自 当前 Cloud Project → API Keys
  4. 详见 langfuse-self-host-install.md §5 的 Cloud 对照说明

6.4 Code Review:用 Trace 当「测试证据」

PR 描述建议附:

## Trace 验证
- Session: `6d782489-7b01-428b-b6d4-b684e7072ad3`
- Trace: mystu-agent-stream, 2026-06-25 10:50
- 结论: 记忆注入正常;place_order 参数 contract=… 符合预期

Reviewer 30 秒能在 Cloud 复现,比截图聊天窗口更可信。

6.5 与自动化测试配合

层级 工具 Trace 角色
单元测试 pytest tests/test_langfuse_tracing.py Mock Callback,不连 Cloud
集成测试 TestClient + mock agent 验证 config 注入
手工 E2E 真 LLM + Cloud 验收行为与 token
CI(可选) 采样 + Langfuse API 对 main 分支做 nightly trace 抽检

原则:CI 不替代 Trace 人工验收 Agent 质量,但 Trace 可减少「上线前再手测一遍」的重复劳动。

6.6 生产环境节制使用

配置 建议
LANGFUSE_SAMPLE_RATE 生产 0.10.3,开发 1.0
LANGFUSE_TRACING_ENVIRONMENT production / staging / development 分开
敏感字段 勿在 metadata 写密码;必要时用 Langfuse mask 功能
留存 Cloud 项目 Settings 配置 retention,符合合规

7. 实战示例:解读一条 mystu-agent-stream Trace

以下结构与你 Cloud 上 Trace Name = mystu-agent-stream 的典型记录一致(名称因 deepagents 版本可能略有差异)。

Session: 6d782489-7b01-428b-b6d4-b684e7072ad3
User: 7
Trace: mystu-agent-stream          Tag: stream
Latency: ~8s    Total Tokens: ~3500
│
├── Span: LangGraph
│   ├── Span: todoListMiddleware.before_model
│   ├── Generation: ChatDeepSeek
│   │     Input:  [System: 用户长期记忆…, Human: 你是说]
│   │     Output: AIMessage(解释 / 追问 / tool_calls)
│   │     Metadata: ls_temperature=0.7, ls_model_name=deepseek-chat
│   ├── Span: todoListMiddleware.after_model
│   └── Span: …(若有 tools 则继续展开)

从这条 Trace 你能立刻得到:

  1. 业务:用户短句「你是说」触发了带记忆的完整 prompt,模型如何承接上下文
  2. 性能:8s 是否合理、Input token 是否因记忆过长
  3. 架构:middleware 与 LangGraph 各 Span 是否正常出现——若缺层,可能是 Callback 或 deepagents 升级问题
  4. 成本:该次对话 Cloud 显示的 $ 估算,便于评估上线规模

8. 进阶能力(按需探索)

Langfuse Cloud 左侧还有 mystu v1 尚未接入、但值得知晓的能力:

能力 用途
Scores 对 Trace 打 1–5 分或 thumbs,做质量趋势
Datasets + Experiments 固定问题集回归 prompt 版本
Prompt Management 版本化 system prompt,与 Trace 关联
Dashboards 自定义 latency / cost 图表
Monitors 异常延迟告警(Cloud 能力以官方为准)

mystu 当前通过 iron_ore_forecast.md + Callback metadata 完成核心观测;若未来要把 prompt 迁到 Langfuse 托管,可参考 .cursor/skills/langfuse/references/prompt-migration.md


9. 检查清单:今天就能用起来的 10 条

  • Cloud Project 已创建 API Key,mystu .env 配置 LANGFUSE_BASE_URL=https://cloud.langfuse.com
  • 启动 mystu 后日志有「已通过鉴权」
  • 发一条 /chat/stream,Tracing 页出现 mystu-agent-stream
  • 点开 ChatDeepSeek,确认 Input 含记忆 SystemMessage
  • 记下浏览器里的 thread_id,在 Sessions 能搜到
  • 用 Tags 过滤 stream / chat / resume
  • 用 Latency 排序找最慢的一条并展开树
  • 对比 Total Tokens 与 Input 长度,评估记忆策略
  • 触发一次 HITL,Session 内看到两条 Trace
  • 改 prompt 后固定测试句,对比前后 Trace Output

10. 延伸阅读

文档 内容
langfuse-tracing-explained.md 采集原理、Callback 工作流、mystu 代码挂载点
langfuse-self-host-install.md 自托管安装;Cloud 用户只看 §5 环境变量对照
AGENTS.md mystu 环境变量与 Langfuse Skill
Langfuse Tracing 官方文档 UI 与概念最新说明
Langfuse LangChain 集成 CallbackHandler 与 metadata 约定

本文基于 mystu 仓库 Langfuse Cloud 集成与真实 Trace 界面整理。Trace 列名与 Search 语法以 Langfuse Cloud 当前版本为准。

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐