进阶 📋 6 个步骤 第 417 / 470 篇

用 Langfuse 给 Agent 加可观测与评估:Trace、Prompt 版本与数据集回归

用开源 Langfuse 给 Agent 接上 Trace 链路追踪、Prompt 版本管理与数据集回归,把线上一次回答到底走了哪几步看清楚。

2026.09.12· 24 分钟阅读· 约 1748 字· 📊 Langfuse / 🔍 Trace

Agent 从 Demo 走向生产,真正卡人的往往不是模型选得不好,而是没人说得清线上一次回答到底经历了什么:走了几轮工具调用?用的是哪个版本的提示词?token 烧在哪一步?Langfuse 就是解决这类问题的开源可观测与评估平台——它把链路追踪(Trace)、提示词版本、数据集评估和成本延迟分析放进同一个控制台。本篇带你从零接上第一条 trace,再走到「观测 → 评估 → 回归」的闭环。

📊 本教程适合:准备把 Agent 推上生产、需要排障与回归能力的开发者/小团队。可选两种部署:Langfuse Cloud 免费额度,或本地 Docker 自托管。不需要 GPU,它只做观测,不做模型推理。

先对齐:Langfuse 到底解决什么

能力一句话说明
Trace 链路追踪把一次请求里的模型调用、工具调用、子步骤串成一棵树,看清每一步
Prompt 版本管理提示词改动可追踪,出问题能定位到「哪一版」
数据集与评估把真实案例沉淀成回归集,批量跑分,防止改一处坏一处
成本与延迟按调用维度看 token 与耗时,找出最贵/最慢的那一步

它的定位是应用层的观测底座:你不需要把模型注册进去,只要在调用前后上报数据即可。

Step 1:选部署方式

1 云免费额度 or 本地自托管
# 方式 A:Langfuse Cloud(零运维,有免费额度)
#   注册后建项目,直接拿 key,跳到 Step 2

# 方式 B:Docker 自托管(数据留在自己机器上)
git clone https://github.com/langfuse/langfuse.git
cd langfuse
docker compose up -d
# 默认 Web 控制台在 http://localhost:3000
# 底层组件:PostgreSQL(事件)、ClickHouse(分析)、Redis(队列)、MinIO(对象存储)
💡 自托管不需要 GPU,主要资源消耗在数据库与 Web 服务上。个人开发者最轻量的用法就是 Docker 拉起一个实例,业务代码通过 SDK 接入。

Step 2:拿到 Key,配好环境变量

2 三个变量就够
pip install langfuse

# .env(不要提交到 git)
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_BASE_URL=https://cloud.langfuse.com
# 其它区域端点(按你的账号区域选择):
#   美国: https://us.cloud.langfuse.com
#   日本: https://jp.cloud.langfuse.com

端点别填错。区域选错会出现「数据上报成功但控制台看不到」的情况。自托管则把 LANGFUSE_BASE_URL 指向你自己的地址(如 http://localhost:3000)。

Step 3:最小接入——先看到第一条 Trace

3 只改一行 import

如果你用的是 OpenAI SDK,Langfuse 提供了一个「即插即用」的封装:把 import 换掉,其余写法不变,调用就会被自动记录。

# 原来是:from openai import OpenAI
# 现在换成 Langfuse 的封装(行为一致,额外记录每次调用)
from langfuse.openai import openai

completion = openai.chat.completions.create(
    name="first-trace",                     # 给这次调用起个名字,便于检索
    model="gpt-4o",                         # 模型名以官方文档为准
    messages=[
        {"role": "system", "content": "你是一个只输出计算结果的计算器。"},
        {"role": "user", "content": "1 + 1 = ?"},
    ],
    metadata={"env": "local"},              # 自定义元数据,方便筛选
)
print(completion.choices[0].message.content)

跑完去控制台看 Trace 列表,应该能看到这一条,点进去能看到输入、输出、模型、token 与耗时。

Step 4:给自定义函数加嵌套 Span

4 把「一次 Agent 运行」串成一棵树

真实 Agent 里除了模型调用,还有检索、工具、后处理。用 @observe() 装饰器可以把它们都挂进同一条链路,形成父子 Span:

from langfuse import Langfuse
from langfuse.decorators import observe, langfuse_context

langfuse = Langfuse()  # 读取环境变量里的 key 与端点

@observe(as_type="generation")
def call_llm(messages, model="gpt-4o"):
    """被装饰后,输入/输出/耗时/token 会被自动捕获。"""
    resp = openai.chat.completions.create(model=model, messages=messages)
    langfuse_context.update_current_observation(
        model=model,
        usage={
            "input": resp.usage.prompt_tokens,
            "output": resp.usage.completion_tokens,
        },
    )
    return resp.choices[0].message.content

@observe()
def run_agent(user_input: str):
    """顶层函数:它下面的所有 @observe 调用都会成为子 Span。"""
    langfuse_context.update_current_trace(
        user_id="user-123",
        session_id="session-abc",     # 同一会话的多轮会归到一起
        tags=["production"],
    )
    answer = call_llm([{"role": "user", "content": user_input}])
    return answer

if __name__ == "__main__":
    print(run_agent("用一句话解释什么是 RAG"))
🔎 有了 session_id 和 tags,你就能按「会话」或「环境」筛选排查。生产排障时,最常用的动作就是「找到某个用户的那次会话,逐 Span 看它在哪一步跑偏」。

Step 5:Prompt 版本管理 + 数据集回归

5 把调试变成可复用的资产

调试时踩过的坑,应该变成下次的测试用例。Langfuse 的路径是:

  1. 把提示词放到控制台管理:改一次生成一个版本,线上引用具体版本;出问题时能精确回滚到「上一版」。避免「改了 prompt 但没人记得改了啥」。
  2. 建数据集:把「信息缺失」「含无关材料」「来源冲突」这几类难例各存几条,作为回归集。
  3. 批量跑评估:改动前后各跑一遍同一数据集,对比答案质量、token、延迟,用数据决定是否上线。

数据合规提醒:Trace 里会包含真实的用户输入与模型输出,可能含个人信息。上线前务必评估:哪些字段需要脱敏、trace 保留多久、谁能查看。若涉及受监管数据,先确认平台的数据驻留区域与合规选项是否符合你的要求。

Step 6:生产上线检查清单

6 自托管从「能跑」到「能扛」
检查项动作
🔐 默认密钥上线前必须改掉 compose 里的 NEXTAUTH_SECRET、SALT、ENCRYPTION_KEY 与数据库密码
📉 采样率高流量场景把采样率降到 0.1 左右,控制 trace 量,别把存储打爆
🗄️ 存储长期运行建议换托管 Postgres / ClickHouse,替代本地数据卷
🐞 调试出口稳定后移除 OTel Collector 配置里的 debug exporter
🔄 回滚镜像打 tag 留档,回滚只需换 tag 重启
🧩 如果你的应用已经在输出 OpenTelemetry span,可以直接走 OTEL 接入,无需改动业务代码;Langfuse 也提供对常见框架(OpenAI、LangChain、Vercel AI SDK、Claude Agent SDK 等)的集成。

常见问题速查

现象大概率原因 & 解决
控制台看不到 trace区域端点填错、key 未生效,或程序退出太快没来得及上报(结束前 flush)
多轮对话散成很多条没设 session_id,把它设成同一个值即可归组
Span 没有嵌套关系子函数没有加 @observe(),或不在父函数的调用链里
成本统计不准自定义模型没上报 usage,或模型定价未配置
自托管启动失败端口占用或数据卷权限问题,先看容器日志再重试
📌 一句话总结:可观测不是「加个日志」,而是让每一次 Agent 运行都可解释、可比较、可回归。先接上 Trace 看清现状,再把难例沉淀成数据集,你就有了把 Agent 推上生产的底气。
← 返回教程中心