Spring AI 流式模式 Token 用量为什么一直是 0一行 streamUsage 配置完整修复【免费下载链接】spring-aiAn Application Framework for AI Engineering项目地址: https://gitcode.com/GitHub_Trending/spr/spring-ai用 Spring AI 的 ChatClient 调用大模型时.call() 能正常拿到 promptTokens、completionTokens而 .stream() 返回的用量却全是 0。本文从这个现象出发讲清流式与非流式在 usage 统计上的机制差异并给出一行配置恢复流式 Token 用量的完整做法。现象拆解.stream() 下用量字段为什么是 0先说结论这不是 Bug。默认配置下流式响应本来就不携带用量信息Spring AI 组装出的 ChatResponse 里 usage 各字段自然为 0。两种调用方式在 Token 用量上的差异如下维度非流式 .call()流式 .stream()响应方式单次请求完整 JSON 一次返回SSE 分块推送逐段返回内容增量usage 字段正常返回 promptTokens / completionTokens / totalTokens默认为 0根本原因服务端生成结束后统一计算并随响应返回请求未显式要求用量时服务端不在流中附带 usageSSEServer-Sent Events是一种服务端向客户端连续推送数据块的 HTTP 协议可以把它想象成水龙头分段放水总水量不变但水不是一次倒出来的而是一股一股地流。问题的本质在于时机服务端要等生成完全结束才知道这次一共用了多少 Token而流式模式早在生成结束前就开始发数据块了。所以默认情况下每个 SSE 数据块只带内容增量不带统计信息Spring AI 拿不到 usage填充到响应对象里的就是 0。你在用量面板上看到的三个 0就是这么来的。一行修复创建 ChatClient 时开启 streamUsage修复方式只有一个在 options 上打开流式用量开关。以 OpenAI 模型为例ChatClient chatClient ChatClient.builder(chatModel) // 关键配置streamUsage(true) 开启流式用量统计 .defaultOptions(OpenAiChatOptions.builder().streamUsage(true)) .build();配置完成之后.stream() 调用拿到的响应就会包含真实用量用法和 .call() 一致。两点说明避免踩坑基础接口 ChatOptions 并不直接暴露这个开关它由具体模型的 options 提供。例如 OpenAiChatOptions 的 Builder 提供了 streamUsage(boolean) 方法部分资料称之为 withStreamUsage其实现是把 StreamOptions 中的 includeUsage 置为 true。ChatClient 的 defaultOptions() 接收的是 ChatOptions.Builder所以直接传 OpenAiChatOptions.builder() 即可不必先 build()。机制说明开启 streamUsage 后用量从哪来开关打开后数据链路在四个环节发生变化请求侧框架在聊天补全请求中附加 stream_options 参数把 includeUsage 设为 true明确告诉服务端请把用量随流发过来。流式数据块中间的 SSE 数据块保持原样只带内容增量响应首包照常到达。补全时机流结束前服务端在最后一条数据块中补上完整 usage 信息promptTokens、completionTokens、totalTokens一次给全。框架映射Spring AI 把该字段映射进对应 ChatResponse 的元数据从 Flux 的最后一个元素读取 usage 即可拿到真实数值。由此引出一条实践约束消费流式响应时用量要读最后一个 ChatResponse如经元数据的 getUsage()在中间数据块上读永远是 0。选型建议流式 vs 非流式按场景定实时对话用 .stream() 并开启 streamUsage(true)。用户体验优先用量在流末尾补齐不影响逐字输出。离线批处理用 .call()。无流式体验需求usage 随响应直接返回记账逻辑最简单可靠。成本审计 / 计费对账优先非流式确需流式则必须叠加 streamUsage。核心标准只有一条——落库前确认 usage 不为 0。常见疑问Q开启 streamUsage 会影响首包延迟吗不会。它只是在请求里多带一个参数首个 SSE 数据块仍是内容usage 只附加在末尾数据块上。Q非流式 .call() 需要开吗不需要也没有实际作用。非流式响应本身就携带 usagestream_options 参数只在流式场景下被服务端解析。Q除了代码能在配置文件中统一开启吗可以。OpenAI 的自动配置属性类OpenAiChatProperties暴露了 streamOptions 配置项其中包含 includeUsage可在 application properties 里统一打开免去每个 ChatClient 单独设置。自查清单一句话总结流式用量为 0 是开关没打开不是统计不到。上线前对照检查流式链路已开启 streamUsage(true)usage 不再全为 0用量从 Flux 的最后一个 ChatResponse 读取而非中间数据块非流式链路回归验证确认行为未受影响计费 / 审计模块对usage 为 0留有兜底告警或重新估算而不是静默落库【免费下载链接】spring-aiAn Application Framework for AI Engineering项目地址: https://gitcode.com/GitHub_Trending/spr/spring-ai创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考