[Bug]: Anthropic streaming with response_format and tools reports finish_reason “stop” when a user tool is called

当你在 LiteLLM 中同时对 Anthropic Claude 使用 stream=True 、 response_format (走 json_tool_call 路径)和 tools 时,如果模型在同一轮里既调用了内部 JSON 工具又调用了用户工具,流式响应会错误地把 finish_rea

快速结论:当你在 LiteLLM 中同时对 Anthropic Claude 使用 stream=True、response_format(走 json_tool_call 路径)和 tools 时,如果模型在同一轮里既调用了内部 JSON 工具又调用了用户工具,流式响应会错误地把 finish_reason 报成 "stop"。优先排查是否是流式迭代器覆盖 finish_reason 导致,并升级到包含修复 PR #46331 的版本。

适用环境:Issue 中确认的环境为 LiteLLM v1.106.0(main at 2b8e53b5ca),涉及 Anthropic Claude 流式调用,以及复用同一迭代器的 Bedrock invoke Claude 和 Vertex AI Claude 流式路径。Issue 未提供操作系统、Python、CUDA、显卡或具体依赖版本信息。

最快修复方案:升级到已包含 PR #46331 的 LiteLLM 版本。该 PR 修复后,当流式请求同时带 response_format 并调用了用户工具时,finish_reason 会保持 "tool_calls"。

注意事项:该修复针对的是 response_format 经由 json_tool_call 工具、而非 Anthropic 原生结构化输出的路径;如果你的调用走的是原生 structured outputs,则不属于本 Issue 覆盖范围。在你自行修改源码打补丁前,请注意 Issue 中的离线复现和修复仅针对流式迭代器路径,非流式路径本就正常。若无法立即升级,需确认 PR #46331 是否已进入你所用的分支或发行版本。

问题场景

用户在 LiteLLM 中调用 litellm.completion(),使用 Anthropic Claude 模型(如 anthropic/claude-sonnet-4-5),同时传入 stream=True、tools 和 JSON Schema 形式的 response_format。当这一轮里模型既调用了内部用于结构化输出的 json_tool_call 工具,又调用了用户定义的工具(例如 get_weather),流式返回的最后一个 chunk 的 finish_reason 变成了 "stop" 而不是 "tool_calls"。用户工具调用的内容本身是正常流出的,但依赖 finish_reason == "tool_calls" 判断是否执行工具的 agent 循环(如 OpenAI Agents SDK、LangChain 等)会误认为本轮已结束,从而不执行工具。

报错原文

[Bug]: Anthropic streaming with response_format and tools reports finish_reason "stop" when a user tool is called

Expected: finish_reason="tool_calls" when any user tool call was streamed, and "stop" only when the json_tool_call tool was the only tool, matching the non-streaming result

原因分析

原因定位在 litellm/llms/anthropic/chat/handler.py 中的 ModelResponseIterator._handle_message_delta。每当 converted_response_format_tool 被设置时,它会无条件把 finish_reason 覆盖为 "stop",而没有检查这一轮是否还流出了用户工具调用。该路径用于 response_format 经由 json_tool_call 工具而非原生结构化输出的场景,同一迭代器也被 Bedrock invoke Claude 和 Vertex AI Claude 流式调用复用。非流式路径本来已正确处理:_resolve_json_mode_non_streaming 会保留用户工具调用、把 JSON 合并进 content,并保持 finish_reason="tool_calls",因此问题只出现在流式路径的一致性上。

环境排查

  • 确认 LiteLLM 版本;Issue 复现于 v1.106.0(main at 2b8e53b5ca),若低于包含 PR #46331 的版本则可能受影响。
  • 确认调用方是否为 Anthropic 流式路径;若使用 Bedrock invoke Claude 或 Vertex AI Claude 流式,注意它们复用同一迭代器,可能同样受影响。
  • 确认是否同时使用了 stream=True、response_format(JSON Schema 形式)和 tools 三个条件。
  • 确认 response_format 是否经由 json_tool_call 路径(而非原生 structured outputs);只有前者是本 Issue 描述的场景。
  • Issue 未提供操作系统、Python、CUDA、显卡或依赖版本信息,如需进一步排查请自行记录这些环境项。

解决步骤

  1. 先确认当前触发的报错是否符合本 Issue 特征:流式请求同时带 response_format 和 tools,且最终 finish_reason 为 "stop" 而实际已流出用户工具调用。
  2. 检查你使用的 LiteLLM 版本是否已包含 PR #46331 的修复;Issue 已确认由 #46331 修复并关闭。
  3. 升级到包含该 PR 的 LiteLLM 版本,或让运维确认 PR #46331 已合并进你使用的分支/发行版。
  4. 如无法立即升级,可参考 Issue 正文中的离线复现脚本,用同一组 Anthropic 流事件对比流式与 AnthropicConfig().transform_parsed_response 的非流式结果,确认差异确实来自 _handle_message_delta 对 finish_reason 的覆盖,再评估是否临时打补丁。
  5. 若你走的是 Bedrock invoke Claude 或 Vertex AI Claude 流式路径,升级时同样需要验证对应的复用迭代器行为,因为 Issue 指出它们共用同一代码路径。

验证方法

用与本 Issue 相同的调用方式发起一次流式请求:stream=True + response_format(JSON Schema)+ 同时会触发用户工具的 tools。检查流式返回的最后一个 chunk,确认 finish_reason == "tool_calls" 而不是 "stop";同时确认用户工具调用内容仍正常流出。也可用 Issue 正文中的离线复现脚本,对比流式结果与非流式 transform_parsed_response 的结果是否一致。若依赖该字段的 agent 循环(OpenAI Agents SDK、LangChain 等)能正常执行工具,则说明问题已解决。

参考来源

BerriAI/litellm #45082

Issue 中提及的修复 PR:#46331(Issue 评论区确认 Fixed by #46331,Closing as completed)。

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29130

发表回复

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