diff --git a/server/model/app/response/ai_claude.go b/server/model/app/response/ai_claude.go index 443db4c..c02c320 100644 --- a/server/model/app/response/ai_claude.go +++ b/server/model/app/response/ai_claude.go @@ -10,6 +10,8 @@ type ClaudeMessageResponse struct { StopReason string `json:"stop_reason,omitempty"` // end_turn, max_tokens, stop_sequence StopSequence string `json:"stop_sequence,omitempty"` Usage ClaudeUsage `json:"usage"` + // 统一格式的用量统计(与 OpenAI chat.completions 对齐) + StandardUsage *ChatCompletionUsage `json:"standard_usage,omitempty"` } type ClaudeContentBlock struct { diff --git a/server/model/app/response/ai_proxy.go b/server/model/app/response/ai_proxy.go index cbc9035..d4f5938 100644 --- a/server/model/app/response/ai_proxy.go +++ b/server/model/app/response/ai_proxy.go @@ -8,6 +8,8 @@ type ChatCompletionResponse struct { Model string `json:"model"` Choices []ChatCompletionChoice `json:"choices"` Usage ChatCompletionUsage `json:"usage"` + // 统一格式的用量统计(用于各种上游的标准化) + StandardUsage *ChatCompletionUsage `json:"standard_usage,omitempty"` // 扩展字段:正则脚本执行日志 RegexLogs *RegexExecutionLogs `json:"regex_logs,omitempty"` } diff --git a/server/service/app/ai_claude.go b/server/service/app/ai_claude.go index d0e0763..0d3e395 100644 --- a/server/service/app/ai_claude.go +++ b/server/service/app/ai_claude.go @@ -49,6 +49,13 @@ func (s *AiProxyService) ProcessClaudeMessage(ctx context.Context, req *request. resp.Content[0].Text = injector.ProcessResponse(resp.Content[0].Text) } + // 5. 统一填充 standard_usage,转换为 OpenAI 风格的用量统计 + resp.StandardUsage = &response.ChatCompletionUsage{ + PromptTokens: resp.Usage.InputTokens, + CompletionTokens: resp.Usage.OutputTokens, + TotalTokens: resp.Usage.InputTokens + resp.Usage.OutputTokens, + } + return resp, nil } diff --git a/server/service/app/ai_proxy.go b/server/service/app/ai_proxy.go index 592f805..5bf120c 100644 --- a/server/service/app/ai_proxy.go +++ b/server/service/app/ai_proxy.go @@ -48,6 +48,15 @@ func (s *AiProxyService) ProcessChatCompletion(ctx context.Context, req *request } // 4. 处理响应并收集正则日志 + if resp != nil { + // 统一填充 standard_usage,方便上游使用统一格式解析 + resp.StandardUsage = &response.ChatCompletionUsage{ + PromptTokens: resp.Usage.PromptTokens, + CompletionTokens: resp.Usage.CompletionTokens, + TotalTokens: resp.Usage.TotalTokens, + } + } + if preset != nil && injector != nil && len(resp.Choices) > 0 { resp.Choices[0].Message.Content = injector.ProcessResponse(resp.Choices[0].Message.Content)