Skip to content

修复 Claude Messages 流式响应中 message_delta.usage.output_tokens 可能为零的问题。#6234

Open
CSCITech wants to merge 2 commits into
QuantumNous:mainfrom
CSCITech:main
Open

修复 Claude Messages 流式响应中 message_delta.usage.output_tokens 可能为零的问题。#6234
CSCITech wants to merge 2 commits into
QuantumNous:mainfrom
CSCITech:main

Conversation

@CSCITech

@CSCITech CSCITech commented Jul 15, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

修复 Claude Messages 流式响应中 message_delta.usage.output_tokens 可能为零的问题。

当上游未在最终 message_delta 中提供输出 token、但转换过程中已经累计得到 CompletionTokens 时,现在会使用累计值补全 OutputTokens,并将其同步写回客户端收到的 usage.output_tokens

补全过程仅在原值为零且累计值大于零时执行,不会覆盖上游已经返回的有效输出 token。这样可以确保日志、结算用量和客户端收到的最终 usage 保持一致。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

  • Closes #(请填写对应 Issue 编号)

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

新增两个回归测试,分别覆盖:

  1. 从累计 CompletionTokens 恢复缺失的 OutputTokens
  2. 将恢复后的值写入 message_delta.usage.output_tokens

修复前,两个测试均能稳定复现问题:

expected: 99
actual:   0

修复后通过以下验证:
go test ./relay/channel/claude -count=1
ok  github.com/QuantumNous/new-api/relay/channel/claude

go test ./service/relayconvert/... -count=1
ok  github.com/QuantumNous/new-api/service/relayconvert
ok  github.com/QuantumNous/new-api/service/relayconvert/internal/oai_chat
ok  github.com/QuantumNous/new-api/service/relayconvert/internal/oai_responses

go vet ./relay/channel/claude ./service/relayconvert/...
通过,无警告

git diff --check
通过,无格式错误

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **Bug Fixes**
  * Improved Claude usage reporting for message deltas.
  * Now includes `output_tokens` in usage updates when it was previously missing.
  * If Claude provides completion token counts, those are used to populate missing output token values.
  * Preserves upstream output token values when already present, while maintaining accurate input and cache token details.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 69cd5042-70cd-4f5f-9ebb-24250b307e3f

📥 Commits

Reviewing files that changed from the base of the PR and between b8f80a1 and dc7eb3b.

📒 Files selected for processing (1)
  • relay/channel/claude/message_delta_usage_patch_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • relay/channel/claude/message_delta_usage_patch_test.go

Walkthrough

Claude message-delta usage conversion now derives missing output tokens from completion tokens and patches usage.output_tokens into the JSON response. Tests cover fallback derivation, preservation of upstream values, and JSON patching.

Changes

Claude usage patching

Layer / File(s) Summary
Output token fallback and JSON patch
service/relayconvert/internal/claude_messages/to_oai_chat_resp.go, relay/channel/claude/message_delta_usage_patch_test.go
Missing output tokens are derived from Claude completion tokens, written to usage.output_tokens, and covered by tests that also verify existing upstream values remain unchanged.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

I’m a rabbit with tokens to spare,
Patching output counts with care.
From completion they grow,
Into JSON they go,
While tests keep the trail clean and fair.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了本次修复:补全 Claude Messages 流式响应中的 message_delta.usage.output_tokens 可能为零的问题。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@relay/channel/claude/message_delta_usage_patch_test.go`:
- Around line 101-109: Add a regression case alongside the existing
buildMessageDeltaPatchUsage tests where both claudeResponse.Usage.OutputTokens
and claudeInfo.Usage.CompletionTokens are positive but different, and assert
that the returned usage preserves the upstream OutputTokens value rather than
applying the fallback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c99e79c0-64c9-4dc6-911d-928e16161e98

📥 Commits

Reviewing files that changed from the base of the PR and between a63364d and b8f80a1.

📒 Files selected for processing (2)
  • relay/channel/claude/message_delta_usage_patch_test.go
  • service/relayconvert/internal/claude_messages/to_oai_chat_resp.go

Comment thread relay/channel/claude/message_delta_usage_patch_test.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant