Spring AI 可观测性:让每一次模型调用都看得见

AI 应用上线后,最怕的不是模型偶尔回答得慢,而是你不知道它为什么慢;也不是一次请求多花了几个 token,而是你完全不知道成本从哪里冒出来。随着 RAG、工具调用、流式返回、多模型组合逐渐进入业务系统,AI 调用链路已经不再是一次简单的 HTTP 请求。

可观测性要解决的,就是通过指标、链路追踪和日志这些外部输出,反推出系统内部发生了什么。对于 Spring AI 应用来说,它尤其重要,因为模型服务往往按量计费,外部依赖多,链路也更复杂。

为什么 AI 应用必须具备可观测性

传统 Web 系统里,我们通常关注接口耗时、错误率、QPS、数据库连接数。到了 AI 应用中,还要额外关心 token 消耗、模型响应耗时、向量检索耗时、重排序耗时、工具调用耗时等指标。

用量统计

模型调用直接关联成本。如果没有细粒度统计,AI 成本就会变成黑盒:

  1. 哪个接口平均消耗 token 最多?
  2. 哪类用户请求触发了高成本调用?
  3. 哪个业务场景的输出过长?
  4. 批量任务是否意外触发了大量模型请求?

这些问题靠人工翻日志很难长期解决。可观测性可以把输入 token、输出 token、总 token、模型名称等信息记录下来,让成本分析有数据依据。

性能监控

一个典型的 RAG 问答链路可能包含多个阶段:

HTTP 请求 -> 文本向量化 -> 向量数据库检索 -> 重排序 -> Chat 模型推理 -> 流式返回

当用户反馈“回答很慢”时,慢点可能出现在任何一个环节。没有链路追踪时,排查只能靠猜;有了 tracing,就能看到每个 span 的耗时,快速判断瓶颈来自网络、模型、向量库还是业务代码。

优化决策

是否需要缓存?是否需要换更便宜的模型?是否要减少上下文长度?是否该引入重排序?这些都不应该只靠经验判断。

可观测性提供真实运行数据,让优化变成基于证据的工程决策。比如,当你发现相同问题反复出现,而且 token 消耗较高,就可以考虑加入缓存;当向量检索占比很高,就要检查索引和召回参数。

Spring AI 内置了哪些观测能力

Spring AI 借助 Spring 生态中的 Micrometer 和 tracing 能力,对常见 AI 组件提供了指标和链路追踪支持。重点组件包括:

组件 观测价值
ChatClient 查看对话调用链路、请求参数、耗时
ChatModel 观察模型调用、模型名称、token 使用
EmbeddingModel 观察向量化耗时和调用情况
ImageModel 观察图像生成请求
VectorStore 观察向量检索耗时与调用链路

这些指标能帮助开发者确认每一次 AI 调用的完整路径,而不是只看到最终接口返回。

使用 Zipkin 查看调用链路

为了直观看到链路追踪结果,可以使用 Zipkin。它是一个开源分布式追踪系统,常用于微服务调用链路分析,也适合观察 AI 应用中的模型调用过程。

可以通过 Docker 快速启动:

docker run -d --name zipkin-spring-ai -p 9411:9411 -e STORAGE_TYPE=mem openzipkin/zipkin:latest

启动后访问:

http://你的服务器IP:9411/zipkin/

如果是本机环境,通常可以访问:

http://127.0.0.1:9411/zipkin/

准备一个观察示例项目

示例项目可以命名为 spring-observability-demo,核心依赖包括 Web、WebFlux、Spring AI Alibaba DashScope,以及测试依赖。

关键配置如下:

spring:
  application:
    name: spring-observability-demo
  ai:
    dashscope:
      api-key: ${DASHSCOPE_API_KEY}

为了方便观察,可以提供两个接口:

  1. /callByClient:调用聊天模型。
  2. /embedding:调用 Embedding 模型。

控制器的大致结构如下:

@RestController
public class TestController {

    private final ChatClient chatClient;

    @Autowired
    private DashScopeEmbeddingModel embeddingModel;

    public TestController(DashScopeChatModel chatModel) {
        this.chatClient = ChatClient.builder(chatModel)
            .defaultAdvisors(new SimpleLoggerAdvisor())
            .build();
    }

    @RequestMapping("/callByClient")
    public String callByClient(String prompt) {
        return chatClient.prompt()
            .user(prompt)
            .call()
            .content();
    }

    @RequestMapping("/embedding")
    public String embedding(@RequestParam(defaultValue = "比特就业课") String text) {
        float[] embedded = embeddingModel.embed(text);
        return "Embedding长度为:" + embedded.length;
    }
}

这样可以分别观察 Chat 调用和 Embedding 调用在链路追踪中的表现。

接入 Actuator、Micrometer 和 Zipkin

要把追踪数据上报到 Zipkin,需要加入以下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>

<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
</dependency>

然后配置 tracing:

management:
  tracing:
    sampling:
      probability: 1.0
  zipkin:
    tracing:
      endpoint: http://127.0.0.1:9411/api/v2/spans

probability: 1.0 表示采样所有请求,方便开发阶段观察。生产环境可以根据请求量调低采样比例,避免追踪数据过多。

在 Zipkin 中观察 AI 调用

启动项目后,访问:

http://127.0.0.1:8080/callByClient?prompt=你好

再打开 Zipkin,就能看到对应服务名称和调用链路。左侧通常展示整个 trace 中的 span 列表,每个 span 对应一次框架操作、模型调用或相关处理环节;右侧会展示 span 的详细标签。

常见标签包括:

标签名 含义
gen_ai.operation.name AI 操作名称,例如 chatframework
gen_ai.system 来源系统,例如 spring_aidashscope
gen_ai.request.model 请求使用的模型
gen_ai.request.temperature temperature 参数
gen_ai.response.finish_reasons 模型停止生成的原因
gen_ai.response.id 模型服务返回的响应 ID
gen_ai.usage.input_tokens 输入消耗 token 数
gen_ai.usage.output_tokens 输出消耗 token 数
gen_ai.usage.total_tokens 总 token 数

访问 /embedding 接口后,也可以看到向量化相关调用。这样一来,Chat 模型和 Embedding 模型的调用路径都能被纳入观测范围。

落地时要关注的几个细节

第一,日志和 trace 要能关联。线上排查问题时,最好在日志中输出 trace id,这样可以从用户请求快速定位到 Zipkin 中的完整链路。

第二,token 指标要进入成本分析。只看接口耗时还不够,AI 应用必须把 token 使用量当成核心指标,因为它直接影响账单。

第三,不要在生产环境盲目全量采样。开发阶段可以使用 probability: 1.0,但高并发场景下需要根据请求量、存储成本和排查需求调整采样比例。

第四,重点观察慢请求。AI 请求天然比普通接口更慢,但慢在哪里很重要。可能是模型推理慢,也可能是向量库检索慢,还可能是上下文过长导致 token 激增。

总结

可观测性是 AI 应用从演示走向生产的必备能力。它让每一次模型调用可见,让每一笔 token 成本可追溯,也让每一个性能瓶颈可以被定位。

Spring AI 通过 Micrometer、Actuator、tracing 和 Zipkin 的组合,把 AI 调用纳入 Spring 体系中成熟的监控方式。对于包含 Chat、Embedding、VectorStore、RAG 和工具调用的系统来说,这套能力能帮助开发者更安心地上线、排查和优化。

真正稳定的 AI 应用,不只是能回答问题,还要能解释自己在系统层面经历了什么。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐