From 61838cdb3dd923357eae44d1f136eed50cbd559e Mon Sep 17 00:00:00 2001 From: shaw Date: Tue, 23 Dec 2025 16:53:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=85=BC=E5=AE=B9GLM=E7=AD=89API?= =?UTF-8?q?=E7=9A=84usage=E6=95=B0=E6=8D=AE=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 部分第三方API(如GLM)的SSE响应格式与标准Claude API不同: - 标准Claude: input_tokens在message_start中 - GLM等API: 所有tokens都在message_delta中 现在从message_delta中也解析input_tokens和cache相关字段, 如果message_start中没有值则使用message_delta中的数据。 --- backend/internal/service/gateway_service.go | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/backend/internal/service/gateway_service.go b/backend/internal/service/gateway_service.go index 0aa3f56a..ed807a1b 100644 --- a/backend/internal/service/gateway_service.go +++ b/backend/internal/service/gateway_service.go @@ -734,7 +734,7 @@ func (s *GatewayService) replaceModelInSSELine(line, fromModel, toModel string) } func (s *GatewayService) parseSSEUsage(data string, usage *ClaudeUsage) { - // 解析message_start获取input tokens + // 解析message_start获取input tokens(标准Claude API格式) var msgStart struct { Type string `json:"type"` Message struct { @@ -747,15 +747,30 @@ func (s *GatewayService) parseSSEUsage(data string, usage *ClaudeUsage) { usage.CacheReadInputTokens = msgStart.Message.Usage.CacheReadInputTokens } - // 解析message_delta获取output tokens + // 解析message_delta获取tokens(兼容GLM等把所有usage放在delta中的API) var msgDelta struct { Type string `json:"type"` Usage struct { - OutputTokens int `json:"output_tokens"` + InputTokens int `json:"input_tokens"` + OutputTokens int `json:"output_tokens"` + CacheCreationInputTokens int `json:"cache_creation_input_tokens"` + CacheReadInputTokens int `json:"cache_read_input_tokens"` } `json:"usage"` } if json.Unmarshal([]byte(data), &msgDelta) == nil && msgDelta.Type == "message_delta" { + // output_tokens 总是从 message_delta 获取 usage.OutputTokens = msgDelta.Usage.OutputTokens + + // 如果 message_start 中没有值,则从 message_delta 获取(兼容GLM等API) + if usage.InputTokens == 0 { + usage.InputTokens = msgDelta.Usage.InputTokens + } + if usage.CacheCreationInputTokens == 0 { + usage.CacheCreationInputTokens = msgDelta.Usage.CacheCreationInputTokens + } + if usage.CacheReadInputTokens == 0 { + usage.CacheReadInputTokens = msgDelta.Usage.CacheReadInputTokens + } } }