这次我们来看一个开源项目Langfuse。做大模型应用开发跑通一个 Chat Demo 并不难难的是上线之后怎么排查问题。用户输入了同样的 Prompt为什么这次回答和上次不一样某个 Agent 任务在链路的哪一步变慢了每天调用 LLM 到底花了多少钱、消耗了多少 token这些问题如果只靠日志和人工翻接口记录基本查不过来。Langfuse 解决的就是这个痛点它是一个专门面向 LLM 应用的可观测性平台提供 trace 追踪、日志记录、成本统计、Prompt 版本管理和在线评估能力。Langfuse 最值得关注的地方有三个第一开源可以自托管数据不一定要出内网第二部署本身不依赖 GPU用 Docker 就能跑起来门槛比本地跑大模型低很多第三它提供完整 WebUI 和 REST API既可以人工点开看调用链路也可以把 trace 数据接进自己的监控系统。本文会按“环境准备、安装部署、创建项目、获取密钥、SDK 接入、链路追踪、接口调用、问题排查”的顺序带你完整落地一套 Langfuse 监控服务。如果你是做 LLM 应用开发、Prompt 调优、Agent 链路分析、RAG 检索质量评估或者正在给团队搭建大模型监控体系的技术负责人这篇文章可以直接收藏照着做。1. Langfuse 核心能力速览能力项说明项目定位LLM 可观测性与trace 追踪平台部署方式Docker Compose 自托管也提供云服务主要功能trace 追踪、span 详情、token 成本统计、Prompt 版本管理、数据集与评估、在线调试硬件要求常见 Docker 环境即可无需 GPU内存和磁盘需按数据量预留支持平台Linux、macOS、WindowsWindows 建议用 WSL2 跑 Docker启动方式docker compose 拉取镜像后一键启动WebUI自带管理后台浏览器访问API 能力提供 REST API可上传 trace、查询 trace、管理 Prompt批量任务支持 trace 批量导出、数据集管理适合批量评估推荐场景本地开发调试、生产环境 LLM 调用监控、成本分析、Prompt 测试对比以上能力来自 Langfuse 项目和社区使用方式。实际部署时具体版本、镜像标签和部分功能入口会随官方版本更新建议以官方仓库和文档为准。2. 适用场景与使用边界Langfuse 适合这几类团队LLM 应用开发团队。需要看每次 Prompt 调用链快速定位是模型问题、检索问题还是上下文拼装问题。RAG 项目团队。需要观察检索文档片段、重排序结果和最终生成文本之间的关系。Agent 应用团队。需要追踪工具调用顺序、中间结果、延迟和 token 消耗。平台/运维团队。需要集中收集多个业务线的 LLM 调用日志做成本归因和异常告警。Prompt 工程团队。需要给不同 Prompt 版本打标做线上效果对比。它能解决的问题很直接每次 LLM 请求从进来到返回经过了哪些步骤每一步消耗多少 token耗时多少成功率如何全部在一条 trace 里展示。再配合成本统计你甚至能算出一个用户完成一次问答大概花了多少钱。但也要说清楚边界。Langfuse 不是业务数据库不适合把对话内容当业务数据存储它不是日志检索系统想查“某天所有包含关键词的日志”应该用 ELK 一类的方案它也不是模型网关不能用来做请求转发和限流。它更偏“监控和追踪”而不是“代理和执行”。使用合规方面需要注意几点上传到 Langfuse 的 trace 可能包含用户输入的 Prompt 和模型输出。涉及个人信息、手机号、身份证号、密钥等内容时先脱敏再上报。如果使用云端 SaaS 版本确认数据出境和隐私协议如果业务有隔离要求优先自托管。不要记录 API Key、Access Token 等敏感凭证。涉及版权内容、内部机密数据时要控制访问权限避免在团队内无差别暴露。3. Langfuse 本地部署环境准备先确认环境工具。项目建议要求操作系统Linux / macOS / Windows WSL2DockerDocker Engine 20.10Docker Compose v2 或 v1内存建议 4GB 以上实际取决于数据量磁盘预留 10GB 以上主要给 PostgreSQL 镜像和数据卷端口默认 3000HTTP 访问浏览器Chrome / Edge / Firefox 最新版本不需要 GPU。如果你之前跑过 ComfyUI、Stable Diffusion 这种本地模型会发现 Langfuse 的部署硬件门槛低很多。它的核心组件是 Web 服务加 PostgreSQL属于常规服务端应用。检查 Docker 是否可用docker --version docker compose version如果提示命令不存在先安装 Docker。Linux 用户注意把当前用户加入 docker 用户组避免每次加 sudosudo usermod -aG docker $USER这里操作完需要重新登录终端或执行newgrp docker让用户组生效。网络方面如果你在服务器部署记得放行 3000 端口。如果通过 Nginx 反向代理可以把 Langfuse 挂在子路径或独立域名下。4. Langfuse 安装部署与启动方式Langfuse 官方提供 Docker Compose 部署方式。这里给一套通用流程具体文件路径和镜像版本以官方仓库为准。4.1 克隆仓库或准备 compose 文件方式一从官方仓库获取部署文件。git clone https://github.com/langfuse/langfuse.git cd langfuse方式二手动创建部署目录把官方提供的docker-compose.yml和.env文件放到同一目录。mkdir -p /opt/langfuse cd /opt/langfuse建议部署前先看下当前版本对应的 compose 文件因为 Langfuse 迭代较快不同版本可能对 PostgreSQL、Redis、镜像标签有不同要求。4.2 配置环境变量复制一份.env并编辑cp .env.example .env vim .env需要重点关注几个配置配置项作用NEXTAUTH_URLWeb 登录回调地址本地一般填 http://localhost:3000SALT用于加密内部密钥的随机盐值ENCRYPTION_KEY数据加密密钥生产环境必须设置DATABASE_URLPostgreSQL 连接串REDIS_URLRedis 连接地址如果是本地快速测试保留.env.example里的默认值也能启动但生产环境一定要重新生成密钥相关的随机值。可以用下面命令生成随机串openssl rand -base64 32将输出填入密钥配置项。4.3 启动服务docker compose up -d首次启动会拉取镜像耗时取决于网络情况。启动完成后查看容器状态docker compose ps正常状态下Web 容器和数据库容器都应该处于Up状态。如果容器反复重启先看日志docker compose logs -f看到类似Ready或监听端口输出的日志说明服务启动完成。4.4 访问 WebUI 并创建管理员浏览器访问http://localhost:3000首次访问会引导创建管理员账号。创建完成后进入 Langfuse 主界面。可以类比一下本地跑 Stable Diffusion WebUI 的体验docker compose up -d之后浏览器打开一个管理页面后续操作基本都在网页里完成。区别在于 Langfuse 不需要你在浏览器里调模型参数它更像一个监控后台。如果端口 3000 被占用可以改宿主机映射端口把 compose 文件里3000:3000改成13000:3000然后重新启动docker compose up -d这种方式适合一台机器上已经跑了其他 Web 服务的场景。5. Langfuse 功能测试与效果验证服务启动后先做一轮功能验证。不要一上来就接生产项目先把最小链路跑通。5.1 创建组织和项目登录 Langfuse WebUI 后第一步创建 Project。Langfuse 的层级一般是组织 - 项目 - trace。建议按业务线划分项目比如“用户问答助手”“内容摘要服务”“客服 Agent”这样后续成本统计和日志查询都不会混在一起。创建项目后进入项目页面左侧能看到 Traces、Sessions、Prompts、Datasets、Metrics 等菜单。这些就是 LLM 监控的核心模块。先不用每个都点开接下来生成一条真实 trace再回来对照界面会更容易理解。5.2 获取 API 密钥上报 trace 时Langfuse SDK 需要认证信息。在项目设置里找到 API Keys 管理页创建一对公钥和私钥。公钥类以pk-开头私钥类以sk-开头实际用途有点类似 Access Key / Secret Key。这两个密钥要保存好私钥不要提交到 Git 仓库也不要写进前端页面。5.3 生成第一条 trace可以使用 Python SDK也可以直接用 curl 调 API。先看 Python SDK 的方式。安装 SDKpip install langfuse写一个最小测试脚本from langfuse import Langfuse langfuse Langfuse( public_keypk-你的公钥, secret_keysk-你的私钥, hosthttp://localhost:3000 ) trace langfuse.trace(namefirst-trace, inputHello Langfuse, outputHello World) trace.update( metadata{ env: test, user_id: demo_user } ) langfuse.flush() print(trace created)运行脚本python test_langfuse.py如果代码没有报错回到 Langfuse WebUI刷新 Trace 列表应该能看到这条first-trace记录。点进去可以看到trace 的唯一 ID输入和输出内容自定义 metadata创建时间到这里最简单的一条链路已经通了。判断成功的标准WebUI 能看到新 trace点进去内容完整metadata 显示正常。5.4 添加 generation 观测实际业务不会只有一条 trace还需要记录模型调用。Langfuse 里把单次模型请求叫做 generation。可以在 trace 下添加from langfuse import Langfuse langfuse Langfuse( public_keypk-你的公钥, secret_keysk-你的私钥, hosthttp://localhost:3000 ) trace langfuse.trace(nameqa-trace) generation trace.generation( namegpt-4o-mini-call, modelgpt-4o-mini, model_parameters{ temperature: 0.7, max_tokens: 200 }, input请用一句话解释什么是向量数据库, ) # 模拟模型返回 generation.end( output向量数据库是专门存储和检索向量数据的数据库常用于 RAG 场景。, usage{ input: 20, output: 30, total: 50 } ) langfuse.flush()运行后回到 WebUI刷新 trace 详情页可以看到这条 trace 下面挂了一个模型调用节点包含模型名、参数、输入输出、token 消耗和耗时。这里有个使用技巧先把 LLM 调用函数包一层后续所有模型请求都会自动带上模型名、参数和 token 统计不需要每个业务函数里手动写。Langfuse 官方还提供 LangChain、LlamaIndex、OpenAI SDK 等集成可以直接通过回调捕获调用记录。对于 Java 后端团队可以关注 Spring Boot 生态对 OpenTelemetry 和 Langfuse 的适配自己通过 REST API 上报也能达到类似效果。5.5 观察一个完整链路真实业务里一次问答通常是多步操作查缓存、检索向量库、拼接 Prompt、调用模型、后处理。把这些步骤的耗时和输入输出都记录下来才能定位慢在哪一步。在 Langfuse 中可以先创建 span再往 span 里挂 generation 或子 spanfrom langfuse import Langfuse langfuse Langfuse( public_keypk-你的公钥, secret_keysk-你的私钥, hosthttp://localhost:3000 ) trace langfuse.trace(namerag-query, user_iduser_001) # 检索步骤 retrieval_span trace.span(namevector-search) retrieval_span.update(inputquery什么是向量数据库?) retrieval_span.end(outputtop1向量数据库基础) # 生成步骤 generation trace.generation( namecompletion, modelgpt-4o-mini, input基于以下资料回答问题, ) generation.end( output向量数据库用于存储和检索向量。, usage{input: 80, output: 40, total: 120} ) langfuse.flush()在 WebUI 的 Trace 详情里就能看到一条树状链路trace: rag-queryspan: vector-searchgeneration: completion这样一来哪一步耗时长、哪一步 token 消耗高一眼就能看出来。这是 Langfuse 做“大模型监控”的核心价值。后续接入真实业务时只需把这种 span 埋点逻辑和业务代码结合比如给检索函数加装饰器、给模型调用包一层工具类。6. Langfuse 接口 API 调用示例与应用接入Langfuse 自带 REST API支持用接口查询 trace、上报 events、管理 Prompt。这个能力很关键意味着不是只有用官方 SDK 才能接入任何能用 HTTP 请求的语言都能上报。6.1 认证方式Langfuse 的公开 API 使用 Basic Auth。格式是Basic base64(public_key:secret_key)Python 里生成请求头import base64 public_key pk-你的公钥 secret_key sk-你的私钥 credentials base64.b64encode(f{public_key}:{secret_key}.encode()).decode() headers { Authorization: fBasic {credentials}, Content-Type: application/json }6.2 上传一条 tracecurl -X POST http://localhost:3000/api/public/traces \ -H Authorization: Basic base64(公钥:私钥) \ -H Content-Type: application/json \ -d { name: curl-trace, input: test from curl, output: response from curl, metadata: { source: curl } }注意这里的实际 API 路径和请求体字段会随 Langfuse 版本调整第一次对接时先打开官方 API 文档确认字段。Swagger 页面通常可以从 WebUI 的设置或/api/public相关入口进入。6.3 查询 trace 列表import requests import base64 public_key pk-你的公钥 secret_key sk-你的私钥 credentials base64.b64encode(f{public_key}:{secret_key}.encode()).decode() url http://localhost:3000/api/public/traces headers { Authorization: fBasic {credentials} } params { limit: 10 } response requests.get(url, headersheaders, paramsparams, timeout10) print(response.status_code) print(response.json())如果返回里包含 traces 列表说明查询接口可用。生产环境中可以把这个查询能力接进告警平台定时检查异常 trace。6.4 批量任务与数据集Langfuse 提供数据集Datasets功能可以把一组输入样本组织起来批量跑 Prompt 版本对比。操作思路类似在 WebUI 创建一个 dataset。上传一批测试用例比如“客服常见问题 200 条”。针对不同 Prompt 版本批量运行Langfuse 会记录每个版本的输出结果。在 UI 里对比效果选择更合适的版本作为线上 Prompt。这种方式比人肉复制粘贴测试省事很多。尤其是 Prompt 改动频繁的项目数据集就是 Prompt 的回归测试集。如果你在团队内负责 Prompt 版本管理这个模块值得优先用起来。Langfuse 也支持 trace 导出可以把历史 trace 数据按条件导出做离线分析。这里注意一点导出数据前要检查是否包含敏感信息导出文件要控制访问权限。6.5 Java/Spring Boot 项目怎么接入热搜词里有“springboot 集成 langfuse”说明很多 Java 团队也在关注这个方向。Langfuse 官方有 Java SDK同时也提供 REST API。从输入信息看Langfuse 社区已经有不少 Spring Boot 集成的实践但接口路径和 SDK 版本会随官方更新变化这里只给通用思路。Spring Boot 项目接入有两种常见方式方式一引入官方 Java SDK。你可以在项目里封装一个LangfuseClientBean利用 SDK 提供的方法上报 trace。优点是 SDK 帮你处理了序列化和认证细节缺点是需要跟随 SDK 版本更新。方式二通过 REST API 直接上报。用 Java 的RestTemplate或WebClient按照 Langfuse API 的格式发送 POST 请求。这种方式不依赖特定 SDK适合公司统一用 HTTP 调用的场景。不管哪种方式建议把上报逻辑封装成一个独立的组件避免业务代码里到处写 API 调用。比如// 伪代码需要按实际 SDK 或 API 结构调整 public void reportTrace(String name, String input, String output) { // 构造请求 // 调用 Langfuse API }对于 Spring AI 项目Langfuse 对 OpenTelemetry 的适配也值得关注。通过 OTLP 协议可以收集链路数据再上报到 Langfuse。这种方式对异构技术栈更友好不止 Java 能用Python、Node.js、Go 服务都可以接入。不过 OTel 接入的配置项较多首次使用需要预留时间调试。7. 资源占用与性能观察Langfuse 部署在 Docker 里资源占用需要实际跑起来观察。不同版本、不同数据量下差异会比较大先给出观察方法。查看容器资源docker stats这个命令能实时看到每个容器的 CPU 和内存占用。Langfuse 默认部署会包含 Web 服务、PostgreSQL、Redis 等容器日常测试环境下整体占用通常不高。但要注意PostgreSQL 是常驻内存的数据库数据量增长后内存占用和磁盘占用都会上升。评估资源时重点看三个指标内存。Web 服务在启动后和查询高峰时段会有波动。磁盘。PostgreSQL 数据卷会持续增长尤其在生产环境持续上报 trace 后增长速度取决于请求量和 input/output 大小。网络。WebUI 打开 trace 列表时会请求 API 返回数据数据量大时响应可能变慢。如果要长期使用建议给 PostgreSQL 数据卷单独挂载较大磁盘。配置 Langfuse 的数据保留策略定期清理或者归档过期 trace。如果公司已经有多套 PostgreSQL、Redis可以考虑复用现有基础设施减少资源重叠。按业务域拆多个项目而不是把全部 trace 塞进一个项目避免 UI 查询卡顿。另外Langfuse 不是每请求都必须同步上报。对延迟敏感的业务可以异步批量上报或者只对采样后的 trace 做完整上报。这样既能监控主要链路又不会明显拖慢业务响应。8. Langfuse 常见问题与排查方法问题现象可能原因排查方式解决方案浏览器访问 3000 端口打不开服务未启动或端口被占用docker compose ps 查看状态检查容器状态重启服务或更换端口容器一直重启环境变量缺失或数据库初始化失败docker compose logs -f 查看日志完善 .env 配置清空旧数据卷后重试登录页面提示无法连接数据库PostgreSQL 没起来或连接串错误docker compose ps 看数据库容器检查 DATABASE_URL 和数据库容器健康状态SDK 上报后 WebUI 看不到 tracehost 地址不对或认证失败检查 Python 脚本中的 host 和控制台输出把 host 改为 http://localhost:3000确认公钥私钥正确上报时报 401 错误API 密钥错误检查认证头生成方式重新生成 API Key确认 Basic Auth 编码正确上报时报 CORS 错误浏览器跨域调用查看请求来源地址通过服务端调用 API或配置反向代理同域访问页面数据加载很慢trace 数量过多检查数据量和数据库索引分项目、加保留策略、定期清理历史数据模型调用没有 token 统计generation 没有传入 usage检查上报代码在 generation.end 或对应参数里传 usage 信息升级版本后功能入口变化版本更新迭代查看官方 changelog 和文档按新版本 UI 调整入口必要时查看迁移文档排查时有一个最常用的通用思路先看容器日志再看网络连通性最后看认证信息。# 查看所有相关容器日志 docker compose logs -f web # 在容器内测试数据库连通性 docker compose exec postgres pg_isready如果数据库容器正常但 WebUI 报错多半是 Web 服务和数据库之间的连接配置问题。如果 SDK 上报报错先确认业务服务器和 Langfuse 服务之间网络通不通再确认密钥和 host 是否正确。有一个容易踩的坑在本地开发时前端页面和后端服务都在同一个机器上直接访问localhost:3000一般没问题。但如果 SDK 跑在 Docker 容器里容器内的localhost指向容器自身而不是宿主机。这时候需要把 host 改成宿主机 IP或者使用 Docker 网络中的服务名。9. Langfuse 使用最佳实践9.1 先小规模验证再全量接入第一次接入项目不要直接把所有请求全部上报。先在开发环境跑通一条完整链路确认 WebUI 能看到 trace、token 统计准确、查询响应正常再逐步放开到测试环境和生产环境。9.2 生产环境做采样生产环境的 LLM 请求量通常很大全量上报会占用较多存储资源。常见做法是重点用户全量上报。普通用户按比例采样比如 10% 或 1%。异常请求全量上报正常请求采样。Langfuse 的 SDK 支持对特定 trace 设置采样策略。这种分级采样既能保证核心链路可追踪又能控制存储成本。9.3 敏感信息过滤上报前对输入输出做脱敏处理。手机号、身份证号、邮箱、API Key、Token、内部系统地址这些都不要直接写入 trace。可以写一个脱敏工具类统一处理后再调用上报接口。如果使用 Langfuse 的 Prompt 管理和数据集功能上传前也要检查测试样本里是否包含真实用户数据。9.4 合理划分项目和命名规范项目按业务线划分trace 命名要有明确规则。比如业务线trace 命名示例客服问答customer-service-qa内容摘要content-summary推荐解释rec-explainer命名统一后在 Langfuse 里按名称筛选会非常方便。团队内部也要约定 metadata 里放什么字段比如user_id、session_id、env、version方便后续做多维分析。9.5 用数据集做 Prompt 回归Prompt 改动后不要只凭一两个测试用例判断效果。把高频问题、边界情况、容易出错的输入整理成数据集每次改动 Prompt 后批量跑一遍对比输出质量和成本。Langfuse 的数据集功能就是为这个场景设计的。9.6 对接告警和成本分析Langfuse 的 API 支持查询 trace 和 token 用量可以在定时任务里做以下检查今天 token 消耗是否突增。某个模型调用错误率是否上升。某条关键链路是否长时间没有新 trace。发现问题时通过钉钉、飞书、企业微信或邮件告警。这样 Langfuse 就不只是“事后查看”的工具而是能及时发现线上问题的监控系统。10. 总结与下一步Langfuse 是目前做 LLM 应用可观测性最值得先试的开源项目之一。它的部署门槛低没有 GPU 也能跑Kong 一个 Docker 环境就能在半小时内搭起来。对 LLM 应用开发者来说最值得先验证的功能是 trace 和 token 统计把一条真实业务请求埋点上报看 WebUI 上能不能完整显示输入、输出、耗时和成本。这一步跑通了后续的 Prompt 管理、数据集评估和告警联动都能在这个基础上扩展。最容易踩的坑有两个一是环境变量没有配置好导致容器反复重启二是 SDK 的 host 地址写错导致数据上报了但控制台看不到。部署时先把容器状态和服务日志确认好再做上报测试会省很多排查时间。接下来你可以继续做三件事把开发环境的模型调用接进 Langfuse跑一遍真实链路整理一份高频 Prompt 用例建一个数据集做版本对比然后评估生产环境的采样策略和脱敏方案。接入过程中遇到问题优先看官方文档和仓库的 issue版本更新后功能入口有变化也以官方说明为准。建议收藏这篇文章部署和接入时按步骤对照操作。