
issue: Open WebUI analytics undercounts token usage for streaming native tool-call loops
快速结论:在使用 Open WebUI 原生/服务端工具调用(Native Tool Calling)的流式对话中,内置分析(Analytics)仅记录最后一次上游 LLM 调用的 token 用量,而非整个工具循环的累计用量。优先排查 Open WebUI 版本是否已包含修复(位于 main 分支及后续版本)。
问题场景
用户在 Open WebUI 中启用原生工具调用(Native/Server-Side Tool Calling),并开启流式聊天补全。用户与启用了工具的助手进行对话,助手在响应过程中多次调用 LLM(例如:LLM 返回工具调用 -> 执行工具 -> LLM 再次处理工具结果),最终仅显示一条可见的助手消息,但分析页面的 token 用量远低于实际值。
报错原文
# 并非报错,而是预期值与实际值不符的典型示例
Expected: input_tokens + output_tokens = 6000 (LLM call 1: 1000, LLM call 2: 2000, LLM call 3: 3000)
Actual in Analytics: approximately 3000 (only the last LLM call's usage is persisted)
原因分析
在 backend/open_webui/utils/middleware.py 的 streaming_chat_response_handler(...) 函数中,整个助手响应过程仅使用了一个名为 usage 的共享变量。当流式数据中的 usage 对象到达时,该变量会被直接覆盖(usage = normalize_usage(raw_usage))。在原生工具循环中,后续的 LLM 调用会重新进入同一个 stream_body_handler(...),再次覆盖该变量。
在消息持久化阶段,仅保存了变量 usage 的最终值(对应最后一次 LLM 调用的用量),导致分析模块(Analytics)从 ChatMessage.usage 字段读取到的只是不完整的 token 计数。
环境排查
- 确认 Open WebUI 版本:若版本低于包含修复的 main 分支,则存在此问题。
- 确认使用模式:仅在“原生工具调用(Native Tool Calling)”+“流式输出(Streaming)”的组合下才会触发。
- 检查后端日志:确认工具循环确实发生了多次 LLM 调用(例如观察来自 LLM 的多个
usage对象)。 - 建议升级到包含此修复的版本(如 main 分支或后续正式版)。
解决步骤
- 升级 Open WebUI:此问题已在 main 分支(对应 v0.10.2 之后及后续版本)中得到修复。升级到最新版本是首选方案。
- (如果无法升级)手动修改代码(不推荐):在
backend/open_webui/utils/middleware.py的streaming_chat_response_handler中,对于usage的处理不再是直接覆盖,而是进行累加。具体逻辑是将每次 LLM 调用返回的usage中的input_tokens、output_tokens和total_tokens分别累加,而不是简单地对usage重新赋值。修改后需要重启 Open WebUI 服务。注意:手动修改会导致后续升级时被覆盖,且官方提供的修复可能涉及更完整的考虑。 - (可优先尝试)排查已有应用:如果已经升级,但之前的对话记录仍显示不正确的 token 用量,这些旧数据不会被自动修复。只有修复之后的新对话才能正确累加。
验证方法
升级后,进行一次涉及多次 LLM 调用的原生工具调用对话(例如让助手依次调用两个工具或一个工具反复调用),并观察分析页面中该次对话或该模型的 token 用量。预期的总 token 数应大致等于上游 LLM 各个调用返回的总 token 数之和,而不仅仅是最后一次调用的结果。也可以通过查看数据库中的 chat_messages 表,检查对应消息的 usage 字段是否为累加值。


![RuntimeError: shape '[0, 6, 16]' is invalid for input of size 72](https://www.chat-gpts.plus/wp-content/uploads/2026/07/14879-05a9e426-768x403.jpg)
