【第28篇】可观测性实战:LangFuse 方案详解

手把手教你为 AI 应用接入专有的可观测平台,追踪每一次模型调用、Token 消耗与成本。

写在前面

在前文中,我们分别介绍了 ARMS (阿里云商业方案,需挂载 Java Agent)和 Zipkin(开源通用链路追踪,基于 Micrometer + Brave)。这两个方案都能帮我们"看到" AI 应用内部发生了什么,但它们并不是为 AI 场景量身定做的------比如,你无法直接看到某次对话消耗了多少 Token、花了多少钱。

本篇文章的主角 LangFuse,正是为解决 AI 应用观测痛点而生的开源平台。我们将通过一个完整的 Spring AI Alibaba 示例项目,带你理解它背后的原理,并亲手将它跑起来。

🔖 本文适合:正在使用 Spring AI Alibaba 开发 LLM 应用的开发者,希望获得比普通链路追踪更深入的 AI 调用分析。


一、 AI 专用可观测性

在传统微服务中,我们关心的是:

  • 请求耗时
  • 错误率
  • 调用链关系

在 AI 应用中,还需要关注

  • 每次对话的 Token 输入/输出数量
  • 不同模型(如 qwen-max、gpt-4)的 单次与累计成本
  • Prompt 和 Completion 的 真实内容(用于调试和审计)
  • 工具调用(Tool Calling)的 参数与结果

通用链路追踪系统(如 Zipkin、Jaeger)并不解析 LLM 请求体,自然无法提供上述信息。而 LangFuse 在 OpenTelemetry 标准之上,额外解析了 AI 调用的语义字段,从而生成 Token 统计、成本分析等报表。


二、LangFuse 整体架构(含 Mermaid 图)

下图展示了用户请求进入 Spring Boot 应用,经过 OpenTelemetry 埋点,最终上报到 LangFuse 的完整数据流:
Spring Boot 应用
方法调用被拦截
创建/结束 Span
每隔几秒导出
OTLP/HTTP + Protobuf
解析 AI 语义
展示
HTTP 请求
用户 / 客户端
AI Controller

Chat / Image / Embedding
Spring AI Bean

如 ChatClient, ImageModel
OpenTelemetry Instrumentation

自动拦截 AI 调用
OpenTelemetry SDK

生成 Span + Metrics
OtlpHttpExporter

批量上报
LangFuse OTLP Collector

https://cloud.langfuse.com/api/public/otel
LangFuse 存储
LangFuse 控制台

Traces / Analytics / Prompts
开发者 / 运维

原理说明

  1. Spring AI 内部已集成 Micrometer Observation API。当调用 ChatClientImageModel 等方法时,会自动生成一个 Observation(观测上下文)。
  2. 项目中加入 opentelemetry-spring-boot-starter 后,Micrometer 的 Observation 会被桥接到 OpenTelemetry 的 Span
  3. OpenTelemetry SDK 负责采样、合并 Span,并通过 OtlpHttpExporter 定期将数据以 Protobuf 格式发送到配置好的 OTLP Endpoint。
  4. LangFuse 的 OTLP 接收器不仅存储通用 Span,还会识别 gen_ai. 开头的属性(如 gen_ai.request.modelgen_ai.usage.input_tokens),从而生成 AI 专用的可视化面板。

三、十分钟快速体验:从零到看见 Trace

3.1 准备环境

确保你的电脑上有:

  • JDK 17+(推荐 Eclipse Temurin 或 Oracle OpenJDK)
  • Maven 3.8+
  • Git
bash 复制代码
java -version
mvn -version
git --version

3.2 注册 LangFuse 云端账号(免费)

LangFuse 提供免费云端版,非常适合测试------不需要自己维护数据库。

  1. 访问 https://cloud.langfuse.com,点击 Sign up(可用 GitHub 登录)。
  2. 验证邮箱后登录,点击 + New Project ,取名 spring-ai-demo,环境选 Development
  3. 进入左下角 Settings → API Keys ,点击 Create API Key 。你会得到:
    • Public Key(形如 pk-lf-xxxxxxxx
    • Secret Key(形如 sk-lf-xxxxxxxx
      ⚠️ 密钥只显示一次,请妥善保存。

3.3 生成 Base64 认证头

LangFuse 的 OTLP 端点使用 HTTP Basic Auth ,用户名 = Public Key,密码 = Secret Key。我们需要将它们 base64 编码后放在 Authorization: Basic 头中。

在终端执行(替换成你真实的 Key):

bash 复制代码
echo -n "pk-lf-xxxxxx:sk-lf-xxxxxx" | base64
# 输出类似:cGstbGYtbnVsbDpzay1sZi1udWxs

记下这个 Base64 字符串,稍后要用。

3.4 获取通义千问 API Key

访问 阿里云百炼平台控制台,创建 API Key(形如 sk-xxxx)。

3.5 下载并配置示例项目

bash 复制代码
git clone https://github.com/alibaba/spring-ai-alibaba.git
cd spring-ai-alibaba/spring-ai-alibaba-observability-example/observability-langfuse-example

编辑 src/main/resources/application.yml,或通过环境变量配置。推荐使用环境变量(避免硬编码密钥):

bash 复制代码
export AI_DASHSCOPE_API_KEY="sk-你的通义千问Key"
export LANGFUSE_BASE64_AUTH="你的Base64字符串"

如果希望直接修改 application.yml,找到下面片段并替换:

yaml 复制代码
exporter:
  otlp:
    endpoint: "https://cloud.langfuse.com/api/public/otel"
    headers:
      Authorization: "Basic ${LANGFUSE_BASE64_AUTH}"   # 注意这里会读取环境变量

3.6 启动应用

bash 复制代码
mvn clean spring-boot:run

看见 Tomcat started on port 8080 即成功。

3.7 发起测试请求并查看观测数据

打开另一个终端,执行:

bash 复制代码
# 1. 普通对话
curl "http://localhost:8080/observability/chat?prompt=你好,请介绍自己"

# 2. 向量化(embedding)
curl "http://localhost:8080/observability/embedding"

# 3. 生成图片(会下载png)
curl "http://localhost:8080/observability/image/generate" -o test.png

# 4. 工具调用(天气)
curl "http://localhost:8080/observability/tools?prompt=杭州天气如何"

然后登录 LangFuse 控制台,点击 Traces,你会看到每条请求对应一条 Trace,点进去可以查看:

  • 模型名称(qwen-max)
  • 输入 Prompt 内容
  • 输出 Completion 内容
  • Token 用量(输入/输出)
  • 耗时与 Metadata

切换到 Analytics 页面,还能看到 Token 趋势图和成本估算。


四、核心依赖与原理详解

很多开发者困惑:为什么只加了几行依赖,AI 调用就能自动上报?下面我们来剖析 pom.xml 中关键的几个模块。

xml 复制代码
<!-- Spring AI 观测自动配置(关键!) -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-model-chat-observation</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-model-embedding-observation</artifactId>
</dependency>
<!-- 图片、向量存储等类似,不一一列举 -->

<!-- OpenTelemetry Spring Boot Starter -->
<dependency>
    <groupId>io.opentelemetry.instrumentation</groupId>
    <artifactId>opentelemetry-spring-boot-starter</artifactId>
    <version>2.9.0</version>
</dependency>

<!-- Micrometer 到 OpenTelemetry 的桥接 -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>

<!-- OTLP 导出器 -->
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>

原理详解

组件 职责
spring-ai-autoconfigure-*-observation 为每个 AI 模型(Chat、Embedding、Image)定义 Observation 约定:何时开始、结束、记录哪些字段(prompt、completion、token 用量等)。
opentelemetry-spring-boot-starter 自动配置 OpenTelemetry SDK,并开启对常见框架(WebClient、RestTemplate、数据源)的埋点。它会读取 otel.* 配置。
micrometer-tracing-bridge-otel 关键桥接层:使 Micrometer 的 Observation 与 OpenTelemetry 的 Span 互通。Spring AI 发出 Observation 事件 → 桥接器自动创建/结束 OpenTelemetry Span。
opentelemetry-exporter-otlp 将 OpenTelemetry Span 和 Metrics 通过 OTLP 协议(HTTP/gRPC)发送到远端 Collector。LangFuse 正是扮演了 OTLP Collector 的角色。

💡 通俗比喻:Observation 是"事件日记本",桥接器是"翻译官",OTLP 导出器是"快递员",LangFuse 是"AI 专项仓库"。


五、配置的常见困惑与最佳实践

原示例中存在两处 observations 配置,容易混淆。我们梳理出清晰、推荐的配置结构:

yaml 复制代码
spring:
  application:
    name: observability-langfuse-demo
  ai:
    dashscope:
      api-key: ${AI_DASHSCOPE_API_KEY}
    # 统一的 AI 观测开关
    observations:
      log-prompt: true          # 在日志中打印 prompt
      log-completion: true      # 在日志中打印 completion
      include-error-logging: true

# OpenTelemetry 相关配置
otel:
  service:
    name: ${spring.application.name}
  traces:
    sampler:
      always_on                # 100% 采样(生产环境可改为概率采样)
  exporter:
    otlp:
      endpoint: "https://cloud.langfuse.com/api/public/otel"
      headers:
        Authorization: "Basic ${LANGFUSE_BASE64_AUTH}"
  logs:
    exporter: none              # LangFuse 暂时不支持日志导出,避免报错

注意

  • spring.ai.observations.* 控制 Spring AI 内部的观测行为(是否记录详细内容)。
  • otel.* 控制 OpenTelemetry SDK 的导出行为。
  • 原文档中有 chat.client.observations 和顶层 observations,它们是不同作用的配置(一个针对 ChatClient 的特定配置,另一个被误用),建议统一使用 spring.ai.observations

六、代码走读:四个 Controller 分别展示了什么?

项目中有四个控制器,对应 AI 能力的观测演示。

6.1 ChatModelController -- 对话流式输出

java 复制代码
@GetMapping
public Flux<String> chat(@RequestParam(defaultValue = "hello!") String prompt) {
    return chatClient.prompt(prompt).stream().content();
}

当执行这个请求时,Spring AI 的 ChatClient 内部会触发 chat.observation,OpenTelemetry 会记录:

  • gen_ai.request.model(从配置自动获取)
  • gen_ai.request.prompt(如果开启 log-prompt)
  • gen_ai.response.completion
  • gen_ai.usage.input_tokens / output_tokens

6.2 ImageModelController -- 图片生成并直接返回

java 复制代码
ImageResponse imageResponse = imageModel.call(new ImagePrompt(DEFAULT_PROMPT));
String imageUrl = imageResponse.getResult().getOutput().getUrl();
// ... 代理输出图片流

图片生成也会产生一个独立的 Observation,记录生成参数(如尺寸、质量)和结果 URL。

6.3 EmbeddingModelController -- 文本向量化

嵌入模型调用一般用于 RAG 检索,LangFuse 会记录向量维度(1536 等)和耗时。

6.4 ToolCallingController -- 工具调用(天气查询)

Spring AI 的工具调用会被拆分为多个 Span:一个主 Chat Span + 每个 tool call 的子 Span。LangFuse 能清晰展示模型先决定调用工具,工具返回结果后模型再最终回答的过程。


七、生产环境部署与调优

7.1 打包与运行

bash 复制代码
mvn clean package -DskipTests
java -jar target/observability-langfuse-example-1.0.0-SNAPSHOT.jar

7.2 Docker 化

创建 Dockerfile

dockerfile 复制代码
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

构建并运行:

bash 复制代码
docker build -t spring-ai-langfuse .
docker run -p 8080:8080 -e AI_DASHSCOPE_API_KEY="xxx" -e LANGFUSE_BASE64_AUTH="xxx" spring-ai-langfuse

7.3 成本控制与采样

生产环境若流量很大,建议降低采样率,同时保留错误请求的 100% 采样。

yaml 复制代码
otel:
  traces:
    sampler:
      type: traceidratio
      ratio: 0.05   # 5% 采样

更高级的方案:使用 parentbased_traceidratio 保证已采样链路的完整性。

7.4 自建 LangFuse(数据不出网)

当你对数据隐私有要求时,可通过 Docker 自建:

bash 复制代码
git clone https://github.com/langfuse/langfuse.git
cd langfuse/infrastructure/docker
docker-compose up -d

然后修改 application.yml 中的 OTLP endpoint 为 http://your-server:3000/api/public/otel


八、常见问题解决(真·有效)

8.1 认证失败:401 Unauthorized

原因 :Base64 凭证错误,或未正确设置 Authorization 头。

解决方法

bash 复制代码
# 重新生成 base64(注意 -n 参数防止换行)
echo -n "你的公钥:你的私钥" | base64
# 复制输出的字符串,确保没有多余空格

8.2 控制台看不到任何 Trace

排查步骤

  1. 检查采样率:确认 otel.traces.sampler.always_on 生效。

  2. 开启 OpenTelemetry 调试日志:

    yaml 复制代码
    logging.level.io.opentelemetry: DEBUG

    重启后若看到 Exporting 1 spans... 说明数据已发送。

  3. 确认网络:curl https://cloud.langfuse.com/api/public/otel 能通。

  4. 等待 10~30 秒:LangFuse 控制台有缓存延迟。

8.3 编译报错 "Name for argument not present"

原因 :Maven 缺少 -parameters 编译参数,导致一些 Spring 参数名反射失败。

解决 :在 pom.xmlmaven-compiler-plugin 中加入:

xml 复制代码
<compilerArgs>
    <arg>-parameters</arg>
</compilerArgs>

九、LangFuse vs Zipkin vs ARMS 最终选型建议

维度 Zipkin LangFuse ARMS
Token/成本分析 ✅ 专精 ✅ 需购买
自建难度 低(单一 jar) 中(需 Postgres+ClickHouse) 不可自建
免费额度 无限制 每月 10k 事件免费 有限免费额度
LLM 调试体验 一般 极好(展示完整对话) 好(阿里云控制台)
推荐场景 简单链路 + 不想付费 AI 应用首选 企业级全栈 + 已有阿里云

一句话总结

  • 如果你是个人开发者或创业团队,做 AI 应用 → LangFuse 免费版性价比最高。
  • 如果你公司已有阿里云全套服务,且需要基础设施统一监控 → ARMS
  • 如果你只关心调用链是否存在断点,不关心 Token → Zipkin

十、总结与扩展

通过本文,你已经学会:

  • 为什么 AI 应用需要 LangFuse 这类专用观测平台。
  • OpenTelemetry 与 Spring AI 观测如何协作。
  • 完整搭建一个从配置到运行再到分析的示例项目。
  • 解决接入过程中 90% 的常见问题。

下一步可以做的

  1. 给应用增加 RAG 链路(如向量数据库检索),LangFuse 会自动记录检索耗时和返回文档数。
  2. 利用 LangFuse 的 Prompt Management 功能,将 prompt 版本与调用 trace 关联。
  3. 设置 评分与反馈(用户点赞点踩),LangFuse 支持关联到具体 trace,用于评估模型表现。

如果你在实操中遇到任何问题,欢迎在评论区留言。🚀

相关推荐
threelab1 小时前
Three.js UV 图像变换效果 | 三维可视化 / AI 提示词
javascript·人工智能·uv
feng14561 小时前
OpenSREClaw - 故障复盘和变更评审双 Agent 案例
运维·人工智能
普马萨特1 小时前
室内外定位导航的最新趋势(基于国际大会观察)
人工智能
Black蜡笔小新1 小时前
私有化本地化AI模型训推工作站/AI大模型训练工作站DLTM赋能安全监控迈入智能时代
人工智能
HackTwoHub1 小时前
全新 AI 赋能网安平台 基于 Mitmproxy 流量分析自动化资产挖、轻量化综合渗透工具箱
人工智能·web安全·网络安全·系统安全·安全架构·sql注入
LaughingZhu1 小时前
Product Hunt 每日热榜 | 2026-04-27
人工智能·经验分享·深度学习·产品运营
代码飞天2 小时前
机器学习算法和函数整理——助力快速查阅
人工智能·算法·机器学习
jinanwuhuaguo2 小时前
(第三十三篇)五月的文明奠基:OpenClaw 2026.5.2版本的文明级解读
android·java·开发语言·人工智能·github·拓扑学·openclaw
BU摆烂会噶2 小时前
【LangGraph】持久化实现的三大能力——时间旅行
数据库·人工智能·python·postgresql·langchain