升级Sonnet 5.5后API报400?思考模式、工具调用和历史消息怎么改

逐项排查 Sonnet 5.5 升级后的400错误:disabled思考、强制工具调用、对话历史和computer use兼容性,附最小请求示例。

钥匙的艺术线稿,配有 Sonnet 5.5 API Migration 标题。

只换模型ID,可能就会让原本正常的 Sonnet 5 接入报错。Sonnet 5.5 改变了支持的思考设置、强制工具选择、思考历史处理以及部分工具兼容性。升级后出现 HTTP 400,应先看错误正文和实际发出的请求,再决定是否修改认证或重试。

本文依据 Anthropic 的 Sonnet 5.5迁移指南与变化说明,核对日期为 2026 年 9 月 29 日。示例是按文档整理的请求格式,不代表 Ofox 在真实 API 上复现了每种错误。401、429 或供应商特有的 404 需要分别排查。

先找出不兼容的字段

旧配置Sonnet 5.5的变化第一步处理
thinking.type: disabled被拒绝改用between_tools,effort不高于high
手动enabled搭配budget_tokens被拒绝改用支持的adaptive thinking或between_tools
tool_choice.type: any或tool被拒绝改用auto,由应用检查工具选择
编辑历史后重放思考块可能违反对话绑定规则保持只追加历史,或按文档处理应丢弃的块
Claude API/Google Cloud上的computer_20251124被拒绝迁移到受支持的computer工具集,并更新循环
较旧的advisor模型搭配部分组合被拒绝查看支持的advisor列表

computer use 这一行不能推广到所有供应商。同一官方页面说明 Amazon Bedrock 仍接受旧的 computer_20251124 工具。平台范围也是修复方案的一部分。

谨慎替换disabled思考

下面是依据文档整理的最小纯文本请求,不带工具,适用于原生 Claude API 的 POST /v1/messages:

{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "thinking": {"type": "between_tools"},
  "output_config": {"effort": "high"},
  "messages": [{"role": "user", "content": "Return a one-sentence summary of this task: verify a CSV total."}]
}

这只是请求体,不是完整 HTTP 客户端。还需要按 Messages API要求提供认证和 API 版本请求头。凭据放在自己的环境中,不要写进复制的示例或日志。

between_tools 关闭的是开始执行前的思考,并不承诺所有工具流程都没有思考块。工具之间的进度说明仍可能使用这种块。该模式接受 low、medium、high,不接受 xhigh、max,也不接受 display、budget_tokens 等额外字段。要使用 xhigh 或 max,应使用 adaptive thinking。组合不兼容时,重复请求不会解决参数校验错误。

替换强制工具调用后,仍要检查行为

把 tool_choice 改成 auto 会改变行为:模型可以决定是否调用工具。在支持的工具定义里加入 strict: true,验证的是工具输入结构,并不会强制选中该工具。应用仍要检查预期调用是否实际发生。这些 schema 功能也依赖平台:迁移指南指出,Amazon Bedrock 上的 Sonnet 5.5 不支持结构化输出,包括 strict tool use。

如果做数据提取,先判断是否真的需要工具调用。结果只是数据、不是动作时,结构化输出可能更合适。应测试合法输出、缺少必填信息、拒绝响应和意外的自然语言回答。请求不再报 400,并不等于迁移完成。

保持对话历史的一致性

Sonnet 5.5 的思考块与模型及对话绑定。修改早先的系统提示词、工具定义或消息,同时重放后面的思考块,可能触发绑定错误。官方默认强制规则适用于指定平台上在 2026 年 8 月 31 日 00:00 UTC 或之后创建的账户;较早账户和显式启用设置要另行核对。

最简单的设计是只追加历史。保持返回块原样,用文档规定的方法处理对话中途变更。如果确实要编辑历史,应按迁移指南处理受影响的块及 beta 控制。不要把“每次都删除全部思考块”当作通用修法,它会改变对话,也可能丢失有用上下文。

切换模型还有单独规则。目标模型无法读取的块可能被丢弃,这与编辑前缀导致的绑定失败不同。应记录具体错误或转换元数据,不要把所有问题统称为“invalid signature”。较早场景可参考思考块签名排错指南。

HTTP成功的响应也要检查

有些回归不会返回 HTTP 错误。工具调用之间较长的进度说明可能放在思考块中,而 adaptive 默认显示行为会省略这些块的文本。只渲染 text 块的界面可能看似没有动静,实际上请求有效。应核对 adaptive 模式的 thinking.display 文档,或受支持的 between_tools 模式。

还要区分拒绝响应与传输失败。文档描述了 HTTP 200 搭配 stop_reason: refusal 及附加详情的情况。HTTP 成功状态不能证明任务完成。应明确处理返回结果,不要反复提交相同的被拒绝任务。

脱离 Agent 循环,单独复现一个失败请求

修改生产集成前,先保存去掉密钥和私人输入的失败请求,记录 endpoint 主机、模型 ID、SDK 版本、HTTP 状态、错误中的 type、message,以及存在时的 request ID。原始响应保留在本地;只复制“400 Bad Request”,就丢失了区分 thinking 不兼容与消息顺序错误的关键线索。单独诊断时关闭应用的自动重试。同一份无效请求通常需要修正配置,重复发送十次不会解决字段错误。

把上面的最小 JSON 保存为 request.json,从新会话开始。下面的命令调用 Anthropic 原生接口,执行会产生 API 用量;前提是已有获批账户,并在环境中设置了 ANTHROPIC_API_KEY。不要把密钥直接写进命令,也不要公开保存的响应。这是诊断操作示例,不是我们成功运行模型的记录。

curl --silent --show-error \
  --dump-header response.headers \
  --output response.json \
  --write-out 'HTTP %{http_code}\n' \
  https://api.anthropic.com/v1/messages \
  --header "x-api-key: $ANTHROPIC_API_KEY" \
  --header 'anthropic-version: 2023-06-01' \
  --header 'content-type: application/json' \
  --data-binary @request.json

分别检查终端打印的 HTTP 状态和 JSON 正文。curl 退出码为零只表示传输过程完成;未设置 HTTP 失败选项时,不代表 API 接受了请求。最小请求成功后,逐组加回原来的 system prompt、工具和历史消息。哪一组首次触发失败,就优先检查那一组,比同时更换模型、SDK 和工具定义更容易定位。

如果最小请求仍返回 400,比较实际序列化的 JSON 与示例。应用层删掉了 thinking.type: disabled、手动 token budget 或强制工具选择,不代表 SDK 包装层不会重新插入它们。应检查最终发出的请求体,而不只是内存中的配置对象。经过网关时,还要核对它的原生 API 兼容说明,不能默认所有字段都原样转发。

同时修请求和响应解析

有效的前后对照既包括 JSON 合法性,也包括行为变化:

修改前修改后额外验收条件
thinking: {"type":"disabled"}thinking: {"type":"between_tools"}thinking 内无不支持字段;effort 为 low、medium 或 high
tool_choice: {"type":"tool","name":"record_expense"}tool_choice: {"type":"auto"}应用能区分未调用、一次调用和意外调用
只读取第一个 content block按 block 类型解析正确处理 text、thinking、tool_use,不执行未知工具
HTTP 200 就算成功状态、stop_reason、业务检查同时通过拒绝、截断和未完成不能写成成功业务记录

例如,记账应用不能因为文字里写了“已保存”就插入账目。它应仅接受允许的 tool_use 名称,校验参数,再执行必要的业务授权。返回工具结果时,保留 assistant content,并用对应的 tool-use ID 关联结果。有多个调用时逐一配对,不能把所有结果都归给最后一个调用。

改用 auto 后,模型不调用工具就是必须处理的分支。向用户返回明确的未完成状态,或请求缺失信息;重试时改回 tool_choice: any 只会重新触发不兼容。支持的平台上,strict: true 可以约束参数形状,但不能证明金额、收款人或日期正确。Schema 校验之后仍要做业务校验。

历史记录问题要与新会话分开诊断

假设某会话在 system 指令 A 下成功,随后你把 A 改成 B,又回传 A 后生成的签名 thinking。按文档中的绑定规则,这段 thinking 已不再对应当前会话前缀。提高 max_tokens 无法修复这种关系。可以新建会话,不回放旧块,复现相同任务;若新会话可用,应排查历史改写,而不是继续增加 token 上限。

原始对话应作为不可变记录保留。不要伪造替代签名,也不要从其他账户复制 thinking。确实需要修改历史时,按官方迁移流程处理受影响的块与支持的控制项。不能把“新开会话”的临时诊断方式悄悄变成生产规则,丢弃所有用户上下文。至少分别测试真正只追加消息的会话,以及应用实际执行的历史修改。

模型切换也应单独测试。不兼容的块可能被丢弃后返回 200,而绑定违规可能使请求失败。日志要区分“请求失败”与“请求成功但历史发生变化”。比较续接任务和全新任务时,这一点尤其重要:即便可见用户消息相同,两者上下文也未必一致。

上线前用响应契约验收

对于最小文本示例,验收条件包括 HTTP 成功、消息含可用文本、结束原因合适,以及摘要符合输入。工具流程还要检查工具名、schema、结果配对与最终业务完成情况。max_tokens 结束表示触及上限,不能把写到一半的 JSON 或操作说明默认当成最终结果。拒绝也要单列,不能沿用临时网络故障的自动重试逻辑。

保留六个小回归用例:全新文本请求、有效工具动作、未调用工具的回答、只追加的第二轮、故意修改的历史前缀,以及包含多种 block 的解析器夹具。最后一项可以用合成 JSON 在本地运行,验证的是自己的解析器,不是 Sonnet 的行为。先跑本地夹具,再使用获批输入进行受控在线抽样,按相同输入比较旧版和新版应用结果。

即使 HTTP 错误率下降,只要新集成产生无效业务动作或丢失必要上下文,就应该回滚。验收完成前,分别保留具名的旧请求适配器和新适配器。只有请求和业务结果都满足约定,迁移才算完成;服务器返回 200 只是其中一步。

切换生产流量前的验证

更完整的上线检查见升级决策指南,CLI选模见 Claude Code设置指南。本文讨论原生 API 变化,第三方网关可能增加自己的适配层和错误。

常见问题

可以继续保留disabled吗?
Sonnet 5.5 不支持该字段值。文档替代方式是 between_tools 配 high 或更低档位;更高 effort 使用 adaptive thinking。
strict工具模式会强制调用工具吗?
不会。结构校验和工具选择是两件事。应用必须处理未调用预期工具的响应。
只要400就一定是模型升级的问题吗?
不是。先读精确错误并隔离变化的字段。消息格式错误、供应商适配和其他无效参数也可能返回 400。