bedrock-runtime 1.35 的 Converse 接口,工具执行完回填 toolResult,返回 400,原文 The content field in toolResult must be a list of content blocks,我按 Claude 原生格式传了一个字符串。

一开始怀疑是「一个 toolResult 只能对应一个 toolUse,多个要拆成多块」,查了一圈,方向不对。

这类报错背后常见的原因有几处,逐个排除就行。Converse 要求 content 是 [{text: ...}] 数组。也可能是toolUseId 必须与上一轮返回的完全一致。

另外,字段名大小写敏感,写成 ToolResult 会被忽略。

第一件事是把上一轮的 toolUse 原样打印出来取 id

python -c "import json;print(json.load(open('resp.json'))['output']['message']['content'])"

接着按规范构造 content 数组

python -c "import json;print(json.dumps({'toolResult':{'toolUseId':'tu_1','content':[{'text':'{\"rows\":3}'}]}}))"

再往下用 curl 发一次最小回填请求

curl https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20241022-v2:0/converse -H "Content-Type: application/json" -d @toolresult.json

多个工具结果分块提交,逐个核对 id

python split_toolresults.py --in results.json --out blocks.json

同事提醒我看一下最近一次发布,时间点确实对得上。

命令输出我都留了记录,免得改完记不清原来的值。

别只看报错消失,验证要多做一步。返回 200,模型在 message 里正确引用工具结果,不再出现 content 结构错误。

提醒一点。Converse 的封装比原生 Claude 严,结构照文档抄一遍最省时间,别拿别的供应商的格式试。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189