[Bug]: anthropic.messages.acreate(stream=True) caches an empty reply from a non-Anthropic model and replays it on every repeat

开启 LiteLLM 响应缓存后,对非 Anthropic 模型(如 Gemini)调用 litellm.anthropic.messages.acreate(stream=True) ,一次内容为空的回复会被写入缓存,之后相同请求都直接命中缓存、不再访问上游。优先排查缓存写入判定逻辑是否把空的 c

快速结论:开启 LiteLLM 响应缓存后,对非 Anthropic 模型(如 Gemini)调用 litellm.anthropic.messages.acreate(stream=True),一次内容为空的回复会被写入缓存,之后相同请求都直接命中缓存、不再访问上游。优先排查缓存写入判定逻辑是否把空的 content_block_start 当成了有效输出。

适用环境:LiteLLM v1.106.6,以及 main 分支 0aa7079f;使用 SDK 方式配置 litellm.cache = Cache(type="local"),未使用 config.yaml;模型为 gemini/gemini-2.5-flash。Issue 未提供操作系统、Python、CUDA、显卡等环境信息。

最快修复方案:升级到包含 PR #50057 合并修复的 LiteLLM 版本。

注意事项:Issue 未说明该修复对应的具体版本号,升级前需自行确认目标版本是否已包含 PR #50057。另外,#47576 讨论的是空 text block 本身,本 Issue 只针对其被缓存的问题,升级不会改变空回复的产生原因。

问题场景

在 LiteLLM SDK 中启用本地响应缓存,连续两次对同一 Gemini 模型发起 litellm.anthropic.messages.acreate(model="gemini/gemini-2.5-flash", ..., stream=True) 调用。上游返回的 Gemini 回复没有任何实际内容(只有一个空的 text part),LiteLLM 适配层将其转换为一个仅含空 text block 的流并写入缓存。第二次相同请求不再到达 provider,而是从缓存重放同一份空回复。

报错原文

call 1 events: ['message_start', 'content_block_start', 'content_block_stop', 'message_delta', 'message_stop']
call 2 events: ['message_start', 'content_block_start', 'content_block_stop', 'message_delta', 'message_stop']
call 2 content_block_start: ['data: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}']
requests to the server: 1

原因分析

Issue 中维护者给出的定位是:caching_handler.py 中的 is_response_without_output 把任何 content_block_start 都视为有输出,因此这个空 text block 被判定为有效回复并写入缓存。其他路径(litellm.acompletion(stream=True)、同步的 litellm.anthropic.messages.create(stream=True))会跳过无输出的回复,重复请求仍会到达 provider;只有异步 Messages 流路径出现该问题。

环境排查

  • 确认 LiteLLM 版本是否为 v1.106.6 或该修复合并前的版本。
  • 确认是否启用了响应缓存(litellm.cache = Cache(type="local") 或等价配置)。
  • 确认触发路径是否为 litellm.anthropic.messages.acreate(..., stream=True),并使用了非 Anthropic 模型(如 gemini/)。
  • 确认上游是否曾返回过内容为空的回复,可结合上面的 mock server 脚本离线复现。
  • Issue 未涉及 Python、CUDA、PyTorch、显卡等依赖版本,无需作为排查前提。

解决步骤

  1. 按 Issue 提供的复现脚本,在本地启用 local cache,连续两次调用 litellm.anthropic.messages.acreate(stream=True),统计请求到达 mock server 的次数,确认为 1 次(命中缓存)。
  2. 将 LiteLLM 升级到包含 PR #50057 的版本(该修复已由维护者确认合并)。
  3. 重新执行同一复现脚本,检查空回复是否仍被写入缓存、第二次调用是否会重新访问 provider。
  4. 如暂时无法升级,可考虑在调用侧对空回复做兜底处理,或调整缓存策略——此方向 Issue 中未提供验证,仅作为可优先尝试的临时手段。

验证方法

使用 Issue 中的 mock Gemini 服务器脚本,修复后应满足:requests to the server 为 2,即第二次相同请求重新到达 provider,而不是从缓存重放空回复;同时第一次与第二次调用的事件序列不再显示缓存重放了相同的空 content_block_start。该脚本以 len(hits) == 2 作为退出码判定标准,退出码为 0 即表示通过。

参考来源

BerriAI/litellm #49931

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 33388

发表回复

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