fix: json_tool_call response not unwrapped for Vertex AI Claude (parameter envelope)

当你在 LiteLLM 中用 vertex_ai/claude-* 模型并设置 response_format 为 json_schema 时,返回的 message.content 可能被包了一层 {"parameter": ...} ,导致下游解析拿不到 schema 里的字段。优先确认你用的

快速结论:当你在 LiteLLM 中用 vertex_ai/claude-* 模型并设置 response_format 为 json_schema 时,返回的 message.content 可能被包了一层 {"parameter": ...},导致下游解析拿不到 schema 里的字段。优先确认你用的 LiteLLM 版本是否已包含 parameter 解包修复。

适用环境:Issue 中确认:LiteLLM 1.88.1(最新 main 也可复现);模型 vertex_ai/claude-opus-4-6;认证为 GCP Application Default Credentials;行为 100% 稳定复现,非偶发。

最快修复方案:升级到包含修复 #45871 的 LiteLLM 版本,该修复会解包 Vertex AI Claude json_schema 回答中的 parameter 包装键,并覆盖流式与非流式场景。暂无其他已确认的一步替代方案。

注意事项:修复针对的是 parameter 包装键;如果你的环境里出现的是其他包装键,需确认对应版本是否也覆盖。若无法立即升级,可在下游解析 message.content 时额外兼容 {"parameter": {...}} 结构,但这属于规避而非修复。

问题场景

在使用 LiteLLM 调用 vertex_ai/claude-* 模型时,传入 response_format: {"type": "json_schema", ...},期望模型按 schema 返回结构化 JSON。实际得到的 message.content 多了一层 {"parameter": {...}} 外壳,例如期望 {"facts": [...]} 却拿到 {"parameter": {"facts": [...]}}。该问题最早由 Hindsight #3028 暴露:Hindsight 的事实提取在 LiteLLM + vertex_ai/claude-* 下静默返回 0 条事实。

报错原文

fix: json_tool_call response not unwrapped for Vertex AI Claude (parameter envelope)

# response message.content contains:
{"parameter": {"facts": [...]}}

# expected:
{"facts": [...]}

# print(content.keys())
dict_keys(['parameter'])  -- should be dict_keys(['facts'])

原因分析

LiteLLM 会把 Anthropic 模型的 json_schema response_format 转换为一个 json_tool_call 工具,Claude 以 tool_use 内容块返回。_convert_tool_response_to_message() 已经处理了 {"values": ...} 包装(anthropic/chat/transformation.py 第 2494 行附近),但没有处理 Vertex AI Anthropic 返回的 {"parameter": ...} 包装。Bedrock 侧有一个类似的解包函数 _unwrap_bedrock_properties 处理 {"properties": ...},但两者都不处理 "parameter"。因此下游按 schema 结构解析时找不到 "facts" 等键。

环境排查

  • 确认 LiteLLM 版本:Issue 中为 1.88.1,main 分支也可复现;升级时确认版本已包含 #45871 修复。
  • 确认模型标识:vertex_ai/claude-*,Issue 中用 vertex_ai/claude-opus-4-6。
  • 确认认证方式:GCP Application Default Credentials(Issue 中的环境)。
  • 确认 response_format 使用的是 json_schema 类型,并且 schema 中包含 $defs / $ref 等复杂结构,这类 schema 更容易触发该包装行为。
  • 确认调用方式:非流式或流式都可能受影响,修复覆盖两者。

解决步骤

  1. 记录当前复现结果:用 Issue 中的最小复现脚本调用 vertex_ai/claude-*,打印 json.loads(response.choices[0].message.content).keys(),确认是否出现 dict_keys(['parameter'])。
  2. 检查当前 LiteLLM 版本,确认是否已包含 #45871 修复。
  3. 升级 LiteLLM 到包含 #45871 的版本。
  4. 升级后重新运行同一复现脚本,确认 message.content 不再带 parameter 外壳。
  5. 如果升级后仍有问题,回到 LiteLLM issue 反馈,并附上 LiteLLM 版本、模型标识、完整 schema、是否流式以及实际 message.content 输出。

验证方法

运行 Issue 中的复现脚本,检查 json.loads(response.choices[0].message.content).keys()。修复前为 dict_keys(['parameter']);修复后应直接返回 schema 定义的键,例如 dict_keys(['facts'])。如果下游是 Hindsight 之类的解析器,同时确认事实提取不再静默返回 0 条。

参考来源

BerriAI/litellm #35790

BerriAI/litellm PR #35792(fix + tests)

BerriAI/litellm #45871(最终修复,解包 parameter 及其他包装键,覆盖流式与非流式)

vectorize-io/hindsight #3028

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 29032

发表回复

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