提交前必读(请勿删除本节)
您当前的 newapi 版本
main 分支最新提交 e0d5156115881780328d31fe9bce7fe25aa9c6c7(2026-07-21)
提交确认
问题描述
现象
Tiered billing(动态计费)模式下,使用 Claude 上游返回的 billing_usage 时,cache_creation_input_tokens(缓存写入 Token)在上游返回了总量但未拆分 5m/1h 的情况下,被完全漏计,值为0。总费用未包含缓存写入 Token 的费用。
问题根源
上游数据特征: Claude API 返回了 cache_creation_input_tokens: n(总量),但 cache_creation 子对象为 null,没有 ephemeral_5m_input_tokens / ephemeral_1h_input_tokens 拆分字段。
两处级联 Bug:
① service/billing_usage.go — 数据映射层
cacheCreation5m := claudeUsage.GetCacheCreation5mTokens() // 0(CacheCreation==nil)
if cacheCreation5m == 0 {
cacheCreation5m = claudeUsage.ClaudeCacheCreation5mTokens // 0(也被设为0)
}
// cacheCreation5m = 0,总量 n 丢掉了
GetCacheCreation5mTokens() 返回 0(CacheCreation 为 nil),回退到 ClaudeCacheCreation5mTokens 也是 0(因为 relay 代码同样从 GetCacheCreation5mTokens() 赋值),导致 cacheCreation5m = 0,没有继续兜底到 CacheCreationInputTokens 总量。
② service/tiered_settle.go — 计费参数构建层
cc5m := float64(usage.PromptTokensDetails.CacheCreationTokensTotal()) // = n ✅
if usage.UsageSemantic == "anthropic" {
cc5m = float64(usage.ClaudeCacheCreation5mTokens) // = 0 🔴
}
cc5m 先通过 CacheCreationTokensTotal() 正确初始化为 n,然后被 ClaudeCacheCreation5mTokens(0)无条件覆盖,导致表达式计算时 cc=0。
重现步骤
curl -X POST 'https://xxx.com/v1/chat/completions' -H 'Content-Type: application/json' -H 'Authorization: Bearer sk-xxx' -d '{
"model": "claude-opus-4-8",
"messages": [
{
"role": "user",
"content": "1+5=?"
}
]
}'
预期结果
总费用计算正确
相关截图
总费用计算不正确,未包含缓存写入 Token 的费用。

提交前必读(请勿删除本节)
您当前的 newapi 版本
main分支最新提交e0d5156115881780328d31fe9bce7fe25aa9c6c7(2026-07-21)提交确认
问题描述
现象
Tiered billing(动态计费)模式下,使用 Claude 上游返回的 billing_usage 时,cache_creation_input_tokens(缓存写入 Token)在上游返回了总量但未拆分 5m/1h 的情况下,被完全漏计,值为0。总费用未包含缓存写入 Token 的费用。
问题根源
上游数据特征: Claude API 返回了 cache_creation_input_tokens: n(总量),但 cache_creation 子对象为 null,没有 ephemeral_5m_input_tokens / ephemeral_1h_input_tokens 拆分字段。
两处级联 Bug:
① service/billing_usage.go — 数据映射层
cacheCreation5m := claudeUsage.GetCacheCreation5mTokens() // 0(CacheCreation==nil)
if cacheCreation5m == 0 {
cacheCreation5m = claudeUsage.ClaudeCacheCreation5mTokens // 0(也被设为0)
}
// cacheCreation5m = 0,总量 n 丢掉了
GetCacheCreation5mTokens() 返回 0(CacheCreation 为 nil),回退到 ClaudeCacheCreation5mTokens 也是 0(因为 relay 代码同样从 GetCacheCreation5mTokens() 赋值),导致 cacheCreation5m = 0,没有继续兜底到 CacheCreationInputTokens 总量。
② service/tiered_settle.go — 计费参数构建层
cc5m := float64(usage.PromptTokensDetails.CacheCreationTokensTotal()) // = n ✅
if usage.UsageSemantic == "anthropic" {
cc5m = float64(usage.ClaudeCacheCreation5mTokens) // = 0 🔴
}
cc5m 先通过 CacheCreationTokensTotal() 正确初始化为 n,然后被 ClaudeCacheCreation5mTokens(0)无条件覆盖,导致表达式计算时 cc=0。
重现步骤
curl -X POST 'https://xxx.com/v1/chat/completions' -H 'Content-Type: application/json' -H 'Authorization: Bearer sk-xxx' -d '{
"model": "claude-opus-4-8",
"messages": [
{
"role": "user",
"content": "1+5=?"
}
]
}'
预期结果
总费用计算正确
相关截图

总费用计算不正确,未包含缓存写入 Token 的费用。