结论
LLM 应用需要一套专门的可观测性工具。传统日志接不住 prompt、token、版本、调用树。Langfuse 就是为这种"非线性 + 非结构化 + 概率性"的应用形态设计的。
约 3142 字大约 10 分钟
LangfuseLLM ObservabilityTracingAI Agent
2026-06-01
调用大模型这件事,看起来只是"输入一段 prompt、拿到一段文本",但真正的 LLM 应用远比一次 HTTP 请求复杂。
一个稍微复杂一点的 AI Agent,单次用户请求背后可能是:多次大模型调用、向量库检索、工具调用、Prompt 模板渲染、JSON 解析、错误重试、Token 计费……
LLM 应用需要一套专门的可观测性工具。传统日志接不住 prompt、token、版本、调用树。Langfuse 就是为这种"非线性 + 非结构化 + 概率性"的应用形态设计的。
Langfuse 是一个面向 LLM 应用的、开源的可观测性 + 评估 + Prompt 管理平台。
"把 LLM 应用当成一个真正的软件系统来观测、调试、评估。"
围绕这一句话,Langfuse 提供四大能力:
| 能力 | 解决的问题 |
|---|---|
| Tracing(追踪) | 把每一次请求的完整调用链可视化:输入、输出、token、延迟、工具调用、模型版本 |
| Evaluation(评估) | 对生产数据跑自动评估(LLM-as-a-Judge / 人工打分 / 用户反馈) |
| Prompt Management | 版本化提示词管理 + A/B 测试,告别把 prompt 写死在代码里 |
| Cost & Latency Analytics | 模型调用成本、延迟、错误率监控 |
它有两个使用形态:
你可能会问:我用 ELK / Grafana 不也能打日志吗?为什么要单独搞一套?
答案藏在 LLM 应用的特性差异里:
传统 REST API 的调用链是一条线:Service A → Service B → Database。
LLM 应用的调用链是树状的、动态的——同一个入口可能因为 prompt 走完全不同的子调用,可能有 RAG、可能有 tool call、可能有 agent 自循环。
传统日志的字段是有限的(user_id、status_code、latency_ms),LLM 应用的"有效负载"是几千 token 的 prompt 和几百 token 的生成文本。
传统系统:成功 = 200,失败 = 5xx。
LLM 系统:模型可能"成功返回"但答案错了;可能"返回格式合法"但语义跑偏;可能同一段 prompt 跑 10 次有 3 种不同答案。
一次请求可能嵌套 5 次模型调用、3 次 embedding、2 次工具调用,成本和延迟不是单点而是叠加的。你不知道哪一步最贵、哪一步最慢,问题就藏在这里。
Langfuse 的数据模型围绕三个最核心的对象展开。
一个 Trace 代表一次端到端的用户请求。
比如用户问 chatbot 一次问题,从用户发问到 bot 给出答复的整个生命周期,就是一个 trace。
Trace 是 Langfuse UI 上最常见的入口单元——时间线 / 树形图,可以下钻到每一个细节。
一个 Observation 是 trace 中的一个具体步骤。
Observation 有几种类型:
| 类型 | 含义 |
|---|---|
| Generation | 一次 LLM 调用(最常见的 observation 类型) |
| Span | 一次普通操作(工具调用、检索步骤、JSON 解析) |
| Event | 一个独立的离散事件(打点 / 日志) |
Observation 是树状嵌套的——一个 trace 里有多个 observation,observation 里还能嵌套子 observation。
一个 Session 把多个 trace 归为一组。
为什么需要 Session?因为一次"对话"往往包含多次请求:
把 A、B、C 用同一个 sessionId 串起来,Langfuse UI 就能给你完整回放这次对话的全过程。
一个典型的 RAG 问答 trace 长这样:
UI 上你能直接看到这个树状结构、每一步的延迟、token 消耗、模型版本。这就是 Langfuse 最常见的"看一眼"的能力。
除了 trace 这一组核心概念,Langfuse 还有几个常被低估但真正决定项目能不能跑起来的能力。
Score 是附加在 trace 或 observation 上的标签或指标。
它可以来自三个方向:
Score 是做"评估循环"的基础——没有 score,你没法量化"这次 prompt 改动到底有没有用"。
把 prompt 从代码里抽出来,做成版本化、可 A/B 测试的资产。
传统做法:prompt 写死在 Python 字符串里,改一次要重新部署代码。
Langfuse 的做法:prompt 存在 Langfuse 服务端,代码运行时动态拉取,UI 上能直接编辑、对比、回滚。
这对于多人协作的 prompt 工程特别重要——prompt 改动的责任人和改动历史要能追到人。
Dataset 是测试用例的集合,通常源自真实 trace。
线上抓一波失败 case → 转成 dataset → 拿这个 dataset 跑新版本 → 对比 score 提升/下降 → 决定上线。
这是 LLM 应用做"离线评估"的标准范式。
production traces → dataset → run new version → compare score → ship
这是从"写 prompt"升级到"做产品"的标志。
如果你想自己跑 Langfuse(出于数据合规 / 成本 / 学习目的),自部署版由这些组件构成:
docker-compose.yml 一行起,全部组件就跑起来了。
ClickHouse 是这套架构的关键设计选择——trace 是典型的"写多读多、字段动态、按时间聚合"场景,传统 PostgreSQL 撑不住这个量级,ClickHouse 的列式存储 + 压缩 + 聚合能力刚好对位。
讲完基础,最后给一个直接跟你日常工作相关的场景:把 OpenCode 接入 Langfuse。
OpenCode 是一个面向终端的 AI Agent,类似 Claude Code 的开源定位——你给它一个项目目录,它能读代码、改代码、跑命令、调工具,直到把任务做完。
你的日常开发里很可能就包含 OpenCode(或类似 Agent)的多个并行会话。
Agent 应用的可观测性需求比单次 LLM 调用更高:
没有 trace 的话,OpenCode 的运行就是个黑盒——它做了什么、花了多少、为什么这么做,你只能事后看 log 文件去拼。
具体能力:
接入后的效果:OpenCode 跑一个任务,Langfuse UI 上能看到完整时间线——每个 turn、每个工具调用、每段 token 计费、每次重试都能下钻到详情。
对于日常使用 OpenCode 的人:
对于做 LLM Agent 产品的人,这种"开箱即用的可观测性"是做产品迭代的基础设施——没有它你就是在盲飞。
从 demo 到 production 的鸿沟,从来不在"能不能跑",而在"出问题能不能定位、迭代有没有数据"。Langfuse 直接把这一层补齐。
Langfuse 不是唯一的 LLM 可观测性方案。最后给一个简短的对比视角,方便你判断什么时候用它:
LangSmith 跟 LangChain 生态深度绑定,UI 体验打磨得更好。Langfuse 是中立开源方案,OTel 协议中立、跟 LangChain / LlamaIndex / OpenAI SDK / OpenCode 都能平起平坐地集成。
能跑,但工作量大——自己定义 schema、写 ingestion、画时间线 UI。Langfuse 已经把这些都做了。
功能覆盖重叠度较高,区别更多在生态:Helicone 偏 AI Gateway,Phoenix 偏评估,Langfuse 是综合性的工程平台。
核心判断标准:
Langfuse 解决的不是"多打几条日志"这种小事,而是给 LLM 应用一套完整的工程基础设施——从单次 trace 可视化、到跨 session 的评估、到 prompt 版本管理、到线上 cost / latency 监控。
对于正在做 AI Agent / LLM 应用的人来说,这套基础设施是从 demo 到 production 的必经之路。
下次你的 Agent 在线上跑偏了、用户报告一个失败 case、或者你想验证某次 prompt 改动有没有效——打开 Langfuse 控制台看一眼,比翻 log 文件高效得多。
最直接的动作:拿你的 OpenCode 会话,接 omercnet/opencode-plugin-langfuse 跑一次,在 Langfuse UI 上看 trace。这是 5 分钟能体验到"可观测性差异"的最快路径。
数据模型、SDK 用法、集成列表
自部署架构和 docker-compose 步骤
@observe() 装饰器和原生 instrumentation