fix(usage): 统一使用记录与仪表盘的缓存命中率计算口径

- 新增归一化总输入上下文计算逻辑,按 provider 区分 OpenAI/Gemini 与 Claude 的 cache token 语义
- 将管理端使用聚合、用户使用记录、仪表盘缓存统计、缓存亲和性分析统一为 token 级缓存命中率
- 修正 total_input_context 字段,避免 cache_read 在部分 provider 上被重复计入分母
- 同步更新相关 Rust 单元测试与网关集成测试断言
- 调整前端 dashboard mock 中 cache_hit_rate 的单位为百分比
This commit is contained in:
AAEE86
2026-04-12 00:57:40 +08:00
parent 7c5bb7f383
commit 335e440cc5
9 changed files with 218 additions and 74 deletions

View File

@@ -393,11 +393,11 @@ async fn gateway_handles_admin_usage_aggregation_stats_locally_with_trusted_admi
assert_eq!(items[0]["request_count"], 2);
assert_eq!(items[0]["output_tokens"], 40);
assert_eq!(items[0]["effective_input_tokens"], 150);
assert_eq!(items[0]["total_input_context"], 200);
assert_eq!(items[0]["total_input_context"], 160);
assert_eq!(items[0]["cache_creation_tokens"], 30);
assert_eq!(items[0]["cache_creation_ephemeral_5m_tokens"], 12);
assert_eq!(items[0]["cache_creation_ephemeral_1h_tokens"], 18);
assert_eq!(items[0]["cache_hit_rate"], 5.0);
assert_eq!(items[0]["cache_hit_rate"], 6.25);
assert_eq!(items[1]["model"], "claude-3-7");
assert_eq!(items[1]["output_tokens"], 20);
@@ -1498,7 +1498,7 @@ async fn gateway_handles_admin_usage_cache_affinity_hit_analysis_locally_with_tr
assert_eq!(payload["total_input_tokens"], 140);
assert_eq!(payload["total_cache_read_tokens"], 50);
assert_eq!(payload["total_cache_creation_tokens"], 15);
assert_eq!(payload["token_cache_hit_rate"], 26.32);
assert_eq!(payload["token_cache_hit_rate"], 35.71);
assert_eq!(payload["total_cache_read_cost_usd"], 0.02);
assert_eq!(payload["total_cache_creation_cost_usd"], 0.015);
assert_eq!(payload["estimated_savings_usd"], 0.18);

View File

@@ -4763,7 +4763,7 @@ async fn gateway_handles_users_me_usage_locally_without_proxying_upstream() {
payload["summary_by_model"][0]["effective_input_tokens"],
105
);
assert_eq!(payload["summary_by_model"][0]["total_input_context"], 145);
assert_eq!(payload["summary_by_model"][0]["total_input_context"], 120);
assert_eq!(payload["billing"]["id"], "wallet-auth-1");
assert_eq!(*upstream_hits.lock().expect("mutex should lock"), 0);