大数跨境

Langfuse 上手:给 LLM 应用做 trace 与离线评估

Langfuse 上手:给 LLM 应用做 trace 与离线评估 AllTests软件测试
2026-09-28
5
导读:Langfuse - 通过一个开放平台追踪、评估并改进人工智能代理。利用生产数据理解行为,协作修复,并以更低的成本和延迟交付更高质量的产品。
1、前言

最近半年测了几个 LLM 应用,最头疼的不是 bug,是没法复现 bug。

传统接口测试很好办:发请求、看状态码、断言返回体里的字段值。但换成大模型接口就乱套了——同一个 prompt,两次返回的文字不一样;状态码是 200,不代表答案是对的;线上用户抱怨"答非所问",你回去翻日志,只能看到一句孤零零的 completion,中间经历了几次工具调用、检索了哪些片段、花了多少 token,全都是黑盒。

更麻烦的是回归。改了一行 system prompt,到底是变好了还是变坏了?靠人逐条看答案?一次跑几十条 case 还能扛,上百条就废了。

Langfuse 就是冲着这个问题来的。它是一个开源的 LLM 可观测与评估平台,干两件事:把每次 LLM 调用的全过程录下来(trace),再把"拿一批测试用例跑一遍、自动打分"这件事产品化(dataset + experiment)。


2、简介

 

Langfuse 官网给自己的定位是 open-source LLM engineering platform,开源协议是 MIT,核心功能不收费。它有云版本(cloud.langfuse.com,每月 5 万次 observations 免费额度),也支持自托管,SDK 两边完全通用。

对测试同学来说,不用记它官网上那一长串功能名词,先把它对应到我们熟悉的概念上:

  • Trace / Observation:一次请求的完整录像。用户问了什么、模型回了什么、中间调了几次工具、检索召回了哪几段、每一步延迟和 token 消耗,全挂在一棵树上。出问题顺着树查,不用再翻日志。

  • Dataset:测试用例集。每条 case 有输入、有期望输出(也可以没有,靠规则判断)。可以手工录、可以从线上 trace 一键转成 case,也支持 CSV 导入。

  • Experiment / Run:一次测试执行。把 dataset 里的每条 case 喂给你的应用,跑完出一份报告。改 prompt、换模型、改 system message 之后重新跑一次,两次结果并排比。

  • Evaluator / Score:断言。可以是代码写的精确匹配、包含校验、正则;也可以是"再调一个模型当裁判"(LLM-as-a-judge);还支持人工标注队列。

  • Prompt Management:prompt 的版本管理和灰度发布。prompt 不进代码库,改完一键回滚,这对需要反复调 prompt 的测试和产品同学很实用。

一句话总结:Datadog 是给后端服务做监控的,Langfuse 就是给 LLM 应用做监控 + 测试的。它底层用 ClickHouse 存 trace,官方说月处理 observations 已经到百亿级别,Fortune 50 里有 21 家在用。


官网地址:

https://langfuse.com/


3、部署

 

想快速体验直接用云版就行,注册个账号拿 API key 就能连 SDK。但测试同学一般要在自己环境里玩,数据不出内网,这里走自托管的 docker compose 路径,这也是官方文档里最省事的方式。

环境准备

一台装了 git 和 docker(带 compose 插件)的机器就行。本地 Mac/Windows 用 Docker Desktop,服务器建议 4 核 16G 内存起步,磁盘 100G 左右——trace 数据攒起来很快。

拉代码并启动

git clone https://github.com/langfuse/langfuse.git
cd langfuse
docker compose up

官方仓库里带了一份 docker-compose.yml,它会一起拉起 Postgres、ClickHouse、Redis、MinIO 这几个依赖组件,不用你额外搭。启动前打开 yml,把里面所有标了 # CHANGEME 的密钥项改成自己的随机串,正式环境别偷懒。

起来大概两到三分钟,等 langfuse-web-1 这个容器日志打出 Ready,浏览器访问 http://localhost:3000 就能看到登录页。服务器部署的话记得在安全组放行 3000 端口,或者直接 SSH 端口转发。

建项目并拿 API Key

第一次访问会让你注册管理员账号(自托管模式下这个账号只在你自己实例里)。登录进去之后:

  • 新建一个 Organization,再在下面建一个 Project,比如叫 llm-app-test。

  • 进 Project 的 Settings → API Keys,新建一对 key:一个 pk-lf-...(public),一个 sk-lf-...(secret)。后面 SDK 要用到。

到这里 Langfuse 本身就装好了。接下来是把我们自己的应用接进去。


4、快速上手

 

这一节分两步走:先给一次 OpenAI 调用接上 trace,确认数据能在 Langfuse 里看到;再搭一个最小的离线评估,也就是把"测试用例集 → 执行 → 断言打分 → 版本对比"跑通。

第一步:给一次 LLM 调用加 trace

装 SDK:

pip install langfuse openai

配环境变量。自托管的话 LANGFUSE_BASE_URL 指向你自己的实例:

export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="http://localhost:3000"
export OPENAI_API_KEY="sk-..."

最省事的接法是用 Langfuse 包装过的 OpenAI 客户端——只改一行 import,其他代码完全不动:

from langfuse.openai import openai

completion = openai.chat.completions.create(
    name="test-chat",
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "你是一个简洁的助手。"},
        {"role": "user", "content": "1 + 1 等于几?"}
    ],
)
print(completion.choices[0].message.content)

跑一下这个脚本,然后回到 Langfuse 后台的 Tracing 页面,刷新就能看到这条 trace。点进去可以看到:完整的 prompt 和 completion、模型名、token 用量、延迟,全部自动记录,不用你手动埋点。短脚本记得最后调一下 langfuse.flush(),不然进程退出前 SDK 还没把数据发完就结束了。

如果你用的是 LangChain、LlamaIndex、Vercel AI SDK、OpenAI Agents SDK,官方都有对应的集成,基本也是改个 import 或传个 callback handler 的事。

第二步:搭一个最小离线评估(重点)

trace 解决的是"线上出问题怎么查",评估解决的是"改了东西怎么知道没改坏"。这部分才是测试同学真正花时间的地方。Langfuse 把它拆成三块:测试用例集(dataset)、被测应用函数(task)、断言函数(evaluator)。

1. 建测试用例集。下面这段脚本建了一个叫 sf-sites 的 dataset,塞了 5 条关于旧金山景点的问答题,每条都带期望输出。这就是我们的 golden set:

from langfuse import get_client

langfuse = get_client()
dataset_name = "sf-sites"

langfuse.create_dataset(
    name=dataset_name,
    description="旧金山景点问答 golden set",
)

items = [
    {"input": {"q": "连接旧金山和马林县的红橙色悬索桥叫什么?"},
     "expected_output": "Golden Gate Bridge"},
    {"input": {"q": "旧金山湾里那座 former 联邦监狱所在的岛叫什么?"},
     "expected_output": "Alcatraz Island"},
    {"input": {"q": "电报山上那座装饰艺术风格的塔叫什么?"},
     "expected_output": "Coit Tower"},
]

for it in items:
    langfuse.create_dataset_item(dataset_name=dataset_name, **it)

print("dataset ready")

跑完之后去 Langfuse 后台的 Datasets 页面,能看到刚建的这个用例集,每条 case 的输入和期望输出都列在那里。可以手工加、可以 CSV 导,也可以直接把线上某条 trace "转正"成一条回归 case——这招特别实用,线上用户报过的问题,一键收进 golden set,下次改 prompt 自动重跑。

图:Langfuse 的 Datasets 页面,每个 dataset 就是一组测试用例

2. 写被测函数和断言。被测函数就是把 dataset 里的 question 喂给你的应用,返回模型答案。断言这里用最简单的精确匹配:答案和期望完全一致记 1 分,否则 0 分。

from langfuse import Evaluation, get_client
from langfuse.openai import OpenAI

langfuse = get_client()
client = OpenAI()

def answer_question(question: str) -> str:
    # 实际项目里这里换成你自己的应用函数
    resp = client.responses.create(
        model="gpt-4o-mini",
        input=[
            {"role": "system", "content": "回答关于旧金山景点的问题。"},
            {"role": "user", "content": question},
        ],
    )
    return resp.output_text

def application_task(*, item, **kwargs):
    return answer_question(item.input["q"])

def exact_match(*, output, expected_output, **kwargs):
    return Evaluation(
        name="exact_match",
        value=1.0if output.strip() == expected_output else0.0,
    )

3. 跑一轮 experiment。一行 run_experiment,SDK 会自动并发地把 dataset 里每条 case 喂给 task,把每次调用的 trace 存好,再让 evaluator 打分:

dataset = langfuse.get_dataset("sf-sites")
result = dataset.run_experiment(
    name="旧金山景点问答",
    run_name="v1-原始prompt",
    task=application_task,
    evaluators=[exact_match],
)
print(result.format())
langfuse.flush()

终端会打印一份汇总,同时 Langfuse 后台的 Experiments 页面会多出一条 run。点进去能看到:每条 case 的输入、模型实际输出、exact_match 得分、以及背后那次 LLM 调用的延迟和 token。哪条 case 挂了,直接点进去看 trace 细节,和 debug 一个接口报错几乎一样。

4. 改 prompt 再跑一次做对比。实际测试中最常见的场景:v1 跑出来准确率不够,怀疑是 system prompt 太松。把 system message 改成"只返回景点官方名称,不要任何额外解释",然后把 run_name 改成 v2-收紧输出 再跑一遍。两次 run 用的是同一个 dataset,在后台可以并排对比平均分和每条 case 的差异——这就是 LLM 时代的回归测试。

精确匹配很严格,模型输出多一句"The answer is"都会判 0。正经项目里通常会叠一个 LLM-as-a-judge:再调一个模型,让它按"答案语义是否正确"打分,和精确匹配互补。也可以把这套脚本挂到 CI 上,prompt 或模型一变就自动跑一遍 golden set,分数掉了直接拦住发布。

小结

到这一步你已经把 Langfuse 的核心链路走通了:docker 起实例 → 改一行 import 收 trace → 建 dataset → 写 task 和 evaluator → 跑 experiment → 版本对比。后面要深入的方向,官方文档都有对应章节:LLM-as-a-judge 配置、人工标注队列(annotation queue)、prompt 灰度发布、把 experiment 接进 CI/CD。

对测试团队来说,它最大的价值不是"又一个监控大屏",而是把 LLM 应用的质量保障从"人肉看输出"往"可重复执行的回归测试"推了一步。这一步现在走起来还比较糙,但方向是对的。


扫描作者微信,交流、合作!
图片

【声明】内容源于网络
0
0
AllTests软件测试
分享软件测试、自动化测试、性能测试、测试开发等技术文章与资源,欢迎关注!
内容 257
粉丝 0
AllTests软件测试 分享软件测试、自动化测试、性能测试、测试开发等技术文章与资源,欢迎关注!
总阅读1.8k
粉丝0
内容257