
Anthropic adapter emits spurious empty content blocks and input_json_delta for first tool-call chunk
快速结论:该问题发生在 LiteLLM 的 AnthropicStreamWrapper 将 OpenAI 兼容格式的流式 Tool Call 转换为 Anthropic SSE 事件序列时。当第一个流式 chunk 来自一个 OpenAI 兼容的提供商(如 Databricks、OpenRouter)且为 Tool Call 时,适配器会发出多余的 content_block_start(类型为 text)和空的 input_json_delta。优先排查你使用的提供商是否在回应中以 tool call 开始而非文本内容。
问题场景
该问题出现在使用 LiteLLM 的 /v1/messages 透传端点时,后端为 Databricks、OpenRouter 或其他 OpenAI 兼容提供商。当这些提供商返回的流式数据第一个 chunk 是一个 Tool Call(而不是文本)时,AnthropicStreamWrapper 会产生不正确的 SSE 事件序列,导致解析错误。
报错原文
AnthropicStreamWrapper produces incorrect SSE event sequences:
1. An empty content_block_start with type "text" is emitted at index 0
2. The first tool-call chunk carries arguments="", but the adapter still emits a content_block_delta with an empty input_json_delta
原因分析
可能原因:AnthropicStreamWrapper 在实现迭代器时,始终假设第一个 chunk 的内容是文本类型,因此预先发出了 content_block_start {type: "text"}。当实际第一个 chunk 是 Tool Call 时,这种假设导致多余的空文本块。同时,对于 Tool Call 的第一个 chunk(只包含函数名称,参数为空字符串),适配器仍然触发 content_block_delta 事件并传递空的 input_json_delta,而真实的 Anthropic API 从不发送空的 input_json_delta 事件。该问题在 LiteLLM v1.90.0 上可复现。
环境排查
- 确认 LiteLLM 版本是否为 v1.90.0 或更早版本(问题可能已在后续版本修复)。
- 确认你使用的后端提供商是否以 Tool Call 作为流式响应中的第一个 chunk。
- 如果你自定义了
AnthropicStreamWrapper或类似适配器,检查其迭代逻辑。
解决步骤
- 查阅关联 Issue #29286,其中包含了复现测试和一个修复 PR。该 Issue 与 #31561 有相同的根本原因。
- 可优先尝试升级 LiteLLM 到最新版本(如果 #29286 的修复已合并)。
- 如果你无法升级,可以手动审查
litellm/llms/anthropic/experimental_pass_through/adapters/streaming_iterator.py中的AnthropicStreamWrapper实现,确保它在处理第一个 chunk 时不会假设类型为 text,并避免在 Tool Call 的第一个 chunk 上发送空input_json_delta。 - 或者,你可以尝试在发送请求时强制请求文本内容的第一个 chunk(某些提供商支持通过参数配置响应顺序),但这可能不是所有场景下都可行。
验证方法
使用一个确保第一个流式 chunk 是 Tool Call 的测试场景(例如调用一个工具型 API)来触发流式响应。观察 SSE 事件序列:如果不再出现空的 content_block_start (type: text) 或空的 input_json_delta,则问题已解决。你也可以运行 Issue 中提供的单元测试来确认。



