Anthropic /v1/messages bridge for Responses-API models drops cache accounting (cache_read_input_tokens always 0)

当 LiteLLM 代理将 Anthropic `/v1/messages` 请求桥接到 OpenAI Responses-API 模型(如 GPT-5.x)时,返回的 Anthropic 格式 `usage` 中 `cache_read_input_tokens` 始终为 0(非流式场景下该字段直

快速结论:当 LiteLLM 代理将 Anthropic `/v1/messages` 请求桥接到 OpenAI Responses-API 模型(如 GPT-5.x)时,返回的 Anthropic 格式 `usage` 中 `cache_read_input_tokens` 始终为 0(非流式场景下该字段直接缺失)。优先检查 `litellm/llms/anthropic/experimental_pass_through/responses_adapters/` 下的 `streaming_iterator.py` 和 `transformation.py` 是否已修复缓存字段映射逻辑。

适用环境:LiteLLM v1.94.0(Issue 验证版本),涉及 Anthropic `/v1/messages` 桥接到 OpenAI Responses API 模型的场景(如 `openai/gpt-5.6-luna`、`openai/gpt-5.6-sol`)。

最快修复方案:暂无确认的一步修复方案(Issue 已在 2026-08-20 关闭,问题报告者提出修复建议并愿意提交 PR,但未在讨论中确认已合并)。

注意事项:报告者指出的修复方案(从 `input_tokens` 中减去缓存读取数)可能引发成本计算双重扣减问题,实施时需注意区分”客户端响应格式”与”内部计费对象”。

问题场景

用户通过 LiteLLM 代理,使用 Anthropic 格式的 `/v1/messages` 端点调用 OpenAI Responses-API 模型(如 GPT-5.6 系列推理模型)。当重复发送相同前缀的请求(系统提示超过 1024 tokens)时,Anthropic 格式的响应中 `usage` 对象的 `cache_read_input_tokens` 字段始终为 0(非流式场景该字段完全缺失),即使上游 OpenAI 实际已有缓存命中(覆盖率接近 100%)。

报错原文

Anthropic /v1/messages bridge for Responses-API models drops cache accounting (cache_read_input_tokens always 0)

原因分析

问题定位在 LiteLLM 的 Responses API 适配器代码中,两个文件存在不同问题:

  • 流式路径(`streaming_iterator.py`):代码先错误地将 `input_tokens_details` 赋值给缓存创建变量、`output_tokens_details` 赋值给缓存读取变量,随后又无条件用 Anthropic 命名的属性覆盖(这两个属性在 Responses usage 对象上不存在),导致两个值始终为 0。
  • 非流式路径(`transformation.py`):构建 `AnthropicUsage` 时只映射了 `input_tokens` 和 `output_tokens`,完全没有处理缓存字段。

此外,Issue 评论补充了两个重要发现:缓存写入计数(`cache_write_tokens`)同样丢失——LiteLLM 自身的规范化 usage(`prompt_tokens_details`)未携带缓存写入信息,导致适配器即使想映射也无数据可用;同时成本计算路径存在风险,修复时若直接在内部使用对象上将 `input_tokens` 减去缓存读取数,会在 `generic_cost_per_token` 计算时造成双重扣减。

环境排查

  • LiteLLM 代理版本:v1.94.0(Issue 报告和评论均已验证,main 分支在 2026-08-06 时仍存在同样问题)
  • 上游模型:OpenAI Responses API 模型(如 `openai/gpt-5.6-luna`、`openai/gpt-5.6-sol`)
  • 客户端:使用 Anthropic 格式的消费者(如 Claude Agent SDK、Claude Code)
  • 需确认路由配置:代理路由 `gpt-5.6-luna`(或任何 Responses-API 模型)到 `openai/gpt-5.6-luna`

解决步骤

  1. 确认 LiteLLM 版本是否为 v1.94.0 或 main 分支 2026-08-06 前后的代码快照,若已更新请检查 `litellm/llms/anthropic/experimental_pass_through/responses_adapters/` 是否已有修复提交。
  2. 检查 `streaming_iterator.py`:确认缓存字段是否正确从 `usage.input_tokens_details.cached_tokens` 读取,而不是错误地使用 `output_tokens_details` 或 Anthropic 命名属性。
  3. 检查 `transformation.py`(非流式):确认是否已添加缓存字段映射逻辑。
  4. 可优先尝试:参照 Issue 中建议的修复方案——从 Responses usage 的 `input_tokens_details.cached_tokens` 获取缓存读取数,并将其从 Anthropic 格式的 `input_tokens` 中减去(同时输出 `cache_read_input_tokens`)。
  5. 注意实施成本修复:内部计费用 `prompt_tokens` 应保持包含缓存读取数(避免 `generic_cost_per_token` 双重扣减),仅在客户端响应 payload 中输出 Anthropic 格式(排除缓存读取数)的数字,并在测试中断言计费成本。
  6. 补充处理缓存写入方向:检查 `input_tokens_details.cache_write_tokens` 映射到 Anthropic 的 `cache_creation_input_tokens`,否则冷调用的缓存创建计数将永久缺失。
  7. 验证成本聚合显示:Issue 评论发现 `cost_breakdown.total_cost` 和 `x-litellm-response-cost` 头在缓存命中时按未缓存价格计算(偏差达 9.5-10 倍),需确认修复后这些派生值也使用原始(含缓存信息的)usage 对象计算。

验证方法

对同一模型重复发送两次相同前缀的 `/v1/messages` 请求(系统提示 >1024 tokens),比较第二次调用返回的 `usage`:

  • 期望结果:`input_tokens` 减去了缓存读取部分(如从 25616 变为 3),且 `cache_read_input_tokens` 字段存在并显示完整缓存命中量(如 25613)。
  • 控制组:相同的提示通过 `/v1/chat/completions` 发送,确认上游缓存生效(`cached_tokens` 字段非零)。
  • 对于流式调用,确认每个 chunk 的 usage 汇总包含缓存读取字段。
  • 验证成本一致性:`response_cost`、`cost_breakdown.total_cost` 和 `x-litellm-response-cost` 头三者数值应一致,且反映缓存折扣价格。

参考来源

BerriAI/litellm #36091

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 19320

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注