教程Claude Code系列第 10 / 21 篇

把代码升级到 Claude 5.5 这一代要改什么:四个模型的不兼容改动和一份检查清单

把模型名换成 Opus 5.5、Sonnet 5.5、Haiku 5.5 或 Fable 5.1,有几处老写法会直接报 400:强制调用工具、关掉思考、预填回答。还有几处不报错但结果变了:回答的第一块可能是空的 thinking,max_tokens 可能被思考用光。本文按官方迁移指南整理,能试的都通过中转站实测过。

发布 · 约 12 分钟读完 · 经人工审核()· 本站的内容怎么来的

本站已实测,测试日期:2026-10-13。

本页目录(10 节)
  1. 先看结论:三类改动
  2. 一、会报错的几处
  3. 二、回答的第一块不一定是答案
  4. 三、max_tokens 可能被思考用光
  5. 四、工具调用之间的话去哪了
  6. 五、thinking 块要原样传回去
  7. 六、其余要重新量一遍的
  8. 一份可以照着过的清单
  9. 通过中转站测到的和文档的出入
  10. 这次实测没有覆盖到的

这篇教程解决一个问题:自己的程序里调着 Claude,现在想把模型换成 5.5 这一代(Opus 5.5、Sonnet 5.5、Haiku 5.5、Fable 5.1),除了改模型名,还有什么会坏?

只用 Claude Code、不自己调接口的读者不需要做这些,Claude Code 自己处理了。但第二节和第三节讲的现象(回答前面多一块思考、输出额度被思考占用)在 Agent SDK 和各种客户端里也看得到。

实测环境
日期 2026-10-13
方式 用 Python 直接发 HTTP 请求
模型 Opus 5.5、Sonnet 5.5,对照 Opus 5、Sonnet 5、Opus 4.6
连接方式 通过酷站AI 中转站,不是直连官方

本站没有官方的 key。下面“实测”的结果都是通过中转站看到的,和官方文档不一致的地方会单独指出。

先看结论:三类改动

类别 改动 不改会怎样
会报错 强制调用工具(tool_choice 为 any 或指定工具) 400
会报错 关掉思考(thinking 设成 disabled),或手动给思考预算 400
会报错 预填回答(最后一条消息是 assistant) 400
会报错 旧版的 computer use 工具 400
会报错 采样参数(temperature、top_p、top_k)用了非默认值 400
不报错,结果变了 回答的第一块可能是 thinking,而且文字是空的 按位置取第一块的代码拿不到答案
不报错,结果变了 max_tokens 把思考也算在内 回答被截断,甚至一个字都没有
不报错,结果变了 工具调用之间的那些话进了 thinking 块 界面在两次工具调用之间没有任何显示
不报错,结果变了 同一段文字的 token 数变多 花费和 max_tokens 的估算偏了
不报错,结果变了 默认 effort 变了,同一档的思考量也变了 花费和速度和以前不一样
要新处理的 拒答(stop_reason 为 refusal) 拿到空内容不知道为什么
要新处理的 对话历史要只增不改 改过前面的轮次再带着 thinking 块发回去,可能 400

官方提供了一个自动迁移的办法:在 Claude Code 里运行自带的 skill。

/claude-api migrate this project to claude-opus-5-5

它会先问你迁移的范围,然后改模型 ID 和那些不兼容的参数,最后给一份要人工核对的清单。本站没有试这个 skill。

一、会报错的几处

强制调用工具

tool_choice 有四种取值。Opus 5.5、Sonnet 5.5 和 Fable 5.1 不再支持其中两种(Haiku 5.5 的迁移指南没有列这一条):

tool_choice 意思 Opus 5.5、Sonnet 5.5、Fable 5.1
auto(默认) 模型自己决定调不调 支持
none 不许调 支持
any 必须调一个 400
指定某个工具 必须调这一个 400

实测:

--- tool_choice: any
    claude-sonnet-5-5  HTTP 400 "claude-sonnet-5-5 不支持强制调用工具:tool_choice 为 any/tool … 会被拒绝。请改用 tool_choice auto …"
    claude-opus-5-5    HTTP 400 (同上)
    claude-sonnet-5    HTTP 200 stop_reason=tool_use 内容块=[tool_use(get_weather {"city": "上海"})]
    claude-opus-5      HTTP 200 stop_reason=tool_use
    claude-opus-4-6    HTTP 200 stop_reason=tool_use

上一代照常工作,这两个 5.5 的模型拒绝。指定某个工具的写法结果一样。报错的文字是中转站自己写的中文,官方的原文是 tool_choice: type "tool" and "any" are not supported for this model.。

怎么改:

  • 保持 auto,在提示词里写明什么情况下要调哪个工具。
  • 以前强制调用是为了拿到结构固定的参数的话,给工具加 strict: true,或者改用结构化输出。

实测里用 auto 问“上海现在天气怎么样”,五个模型都自己调了工具。

关掉思考

模型 thinking 能设成什么 不带 thinking 字段时
Opus 5.5、Fable 5.1 只有 adaptive。思考一直开着 思考
Sonnet 5.5 adaptive、between_tools 思考
Haiku 5.5 adaptive、disabled 思考
Sonnet 5、Opus 5 adaptive、disabled 思考
Sonnet 4.6 adaptive、disabled、enabled(已弃用) 不思考
Sonnet 4.5、Haiku 4.5 disabled、enabled 不思考

几条规则:

  • 手动的思考预算(enabled 加 budget_tokens)在这一代全部报 400。 改用 adaptive,用 effort 控制想多深。
  • Opus 5.5 关不掉思考。 想让它少想,降 effort。
  • Sonnet 5.5 的最低档叫 between_tools:不做开头的那段思考,只在工具调用之间写简短的进度说明。它只能配 low、medium、high 三档 effort,配 xhigh 或 max 会 400。
  • 从 4.6 及更早的模型升上来要特别留意:以前不带 thinking 字段是“不思考”,现在是“思考”。

实测 thinking 设成 disabled:

    claude-opus-5-5    HTTP 400 "claude-opus-5-5 始终开启自适应思考,不支持 thinking.type 为 disabled 或 enabled …"
    claude-sonnet-5-5  HTTP 200 正常回答
    claude-sonnet-5    HTTP 200 正常回答
    claude-opus-5      HTTP 200 正常回答

Opus 5.5 那一条和文档一致。Sonnet 5.5 那一条和文档不一致:文档说它应当返回 400 并提示改用 between_tools,通过中转站却是 200。反过来,between_tools 这个官方推荐的写法,这家中转站目前不支持(见《报错、限流和停止原因》第七节)。所以这一处在中转站上测出来的结果不能代表官方接口。

预填回答

以前有一种常用的写法:在 messages 的最后放一条 assistant 消息,写上回答的开头(比如一个 {),让模型接着写。Claude 4.6 及之后的模型不再支持,返回 400。

怎么改: messages 以用户消息结尾。要固定输出格式,用结构化输出,或者在系统提示里说明。

通过中转站,预填没有被拒绝(那一篇里测过),这同样不代表官方接口。

旧版的 computer use 工具

在 Claude API 和 Google Cloud 上,Opus 5.5 和 Sonnet 5.5 只接受 computer_toolset_20260801 这个工具集,声明旧的 computer_20251124 会 400。Amazon Bedrock 上仍然用旧的。本站没有试。

采样参数

temperature、top_p、top_k 这三个参数,文档写得很明确:Opus 4.7 及之后的模型(包括 5.5 这一代的全部四个),只要带了非默认的值,每个请求都返回 400,和开没开思考无关。这些模型上 top_p 的默认值是 0.99,所以连 top_p: 1 也会被拒。迁移时把这三个参数从请求里删掉。

实测带上 temperature: 0.2 或 top_p: 0.9,五个模型都返回了 200。这是又一处和文档不一致的地方:按文档,其中四个模型应当返回 400。它们在中转站上是被采纳了还是被忽略了,本站看不出来。另外,这次用的 Python SDK 1.13.0 的 messages.create() 已经没有 temperature 这个参数了,传了会在本地直接报 TypeError。

二、回答的第一块不一定是答案

这是最容易悄悄弄坏老代码的一处。很多代码是这样取答案的:

answer = message.content[0].text      # 假定第一块就是文字

这一代模型默认在思考,回答的开头可能是一个 thinking 块。实测问一道要动点脑筋的题:

--- claude-opus-5-5,不带 thinking 字段
    内容块=[thinking(文字 0 字符, 签名有), text('**答案:不存在这样的三位数。**…')]  output=243(思考 130)
--- claude-sonnet-5-5,不带 thinking 字段
    内容块=[thinking(文字 0 字符, 签名有), text('**不存在这样的三位数。**…')]  output=307(思考 222)
--- claude-opus-4-6,不带 thinking 字段
    内容块=[text('设个位为 a,则百位为 a+3…')]  output=756(思考 0)

三件事:

  • 第一块是 thinking,上面那行代码会出错。 要按类型取:
answer = "".join(b.text for b in message.content if b.type == "text")
  • thinking 块的文字是空的。 默认的显示方式是 omitted:块还在,带着一个签名,但里面没有可读的内容。思考用掉的 token 照样算在输出里收费,上面 Opus 5.5 的 243 个输出 token 里有 130 个是思考。
  • 不是每次都有。 问一句“你好”时 Sonnet 5.5 就没有产生 thinking 块。所以不能假定它一定在,也不能假定它一定不在。

想看到思考的内容,把显示方式设成 summarized:

"thinking": {"type": "adaptive", "display": "summarized"}
--- claude-opus-5-5,display: summarized
    内容块=[thinking(文字 172 字符, 签名有), text(…)]
    思考摘要开头:Setting up the equations from the conditions, I find b=5, a+c=10, and …

拿到的是一段摘要,不是原始的思考过程。这次题目是中文的,摘要是英文的。

顺带一提:这道题本身无解(按条件算出来百位是 6.5),两个 5.5 的模型都直接指出了这一点;Opus 4.6 没有思考,用了两三倍的篇幅在回答里一步步推。

三、max_tokens 可能被思考用光

max_tokens 限制的是思考加回答的总输出。以前不思考的请求,换到这一代之后同样的上限就紧了。

实测把上限压到 60:

--- claude-opus-5-5,max_tokens 只给 60
    stop_reason=max_tokens  内容块=[thinking(文字 0 字符, 签名有)]  output=60(思考 60)

60 个 token 全花在了思考上,回答一个字都没有,而你照样要为这 60 个输出 token 付钱。

所以:

  • 以前关着思考的代码,升级后把 max_tokens 调大。文档的建议是在 xhigh 或 max 这两档上至少从 64000 起步。
  • 每次都检查 stop_reason。是 max_tokens 就说明没写完。

四、工具调用之间的话去哪了

做智能体界面的人会碰到这个。以前,模型在两次工具调用之间说的“我先看一下这个文件”之类的话,是普通的文字块,界面可以直接显示。这一代里,稍长一点的这类话改成放在 thinking 块里返回,默认又是不显示文字的。

结果是:界面在工具调用之间突然安静了,没有任何报错。

实测一轮工具调用的第一步:

--- claude-opus-5-5 第一步
    内容块=[thinking(文字 0 字符, 签名有), text('要判断能不能跑步,得看实时的气温、降水、风力…'), tool_use(get_weather {"city": "上海"})]

这一次短短的一句还是以文字块出现的,和文档说的“一两句以内的话仍然是文字”一致。更长的进度说明会进到 thinking 块里,这次没有碰到。

要显示它们,把显示方式设成 summarized,或者测试版的 updates,然后把非空的 thinking 块渲染出来。

五、thinking 块要原样传回去

带工具的对话里,你要把助手的整条回复(包括 thinking 块,包括空的)原样放回 messages,再附上工具结果。文档的要求很严:改了、删了、调了顺序,都会 400。

这一代还加了两条新的约束:

  • thinking 块认模型。 每个块记着是哪个模型产生的,别的模型不一定读得了。比如 Sonnet 5.5 读得了 Sonnet 5 的块,读不了 Opus 5.5 的。中途换模型时,目标模型读不了的块会被悄悄丢掉,请求照样成功,只是那几轮的推理没了。
  • thinking 块认上下文。 它前面的东西(系统提示、工具定义、更早的消息)如果在它产生之后被改过,带着它再发回去可能 400。2026 年 8 月 31 日之后创建的账号默认就执行这项检查。

所以文档反复说一句话:对话历史只增不改。 要中途改指令或换工具,用对话中间的 system 消息,不要回头去编辑前面的内容。

实测把 thinking 块删掉、或者把它的签名改掉再传回去:

--- claude-opus-5-5
    第二步(原样传回):HTTP 200 stop_reason=end_turn
    第二步(删掉 thinking 块再传回):HTTP 200 stop_reason=end_turn
    第二步(把 thinking 块的签名改掉):HTTP 200 stop_reason=end_turn

三种都成功了。这又是一处和文档不一致的地方,按文档后两种应当被拒绝。在中转站上能跑通,不说明你的代码处理对了。

六、其余要重新量一遍的

  • token 数。 从 4.6 及更早的模型升上来,同一段文字的 token 数会变多,文档说大约三成。本站实测中文几乎不变、英文多近四成,见《Claude 现在有哪些模型、各多少钱、怎么选》第四节。5 升到 5.5 分词器没变。
  • effort。 Opus 5.5 的默认档从 high 改成了 medium;Sonnet 5.5 的各档思考量重新校准过。以前调好的档位不要直接搬,重新试一遍。
  • 缓存的门槛降了。 Opus 5.5、Sonnet 5.5、Haiku 5.5 上 512 个 token 的提示就能进缓存(Sonnet 5 是 1024,Haiku 4.5 是 4096)。以前因为太短进不了缓存的提示,现在会产生写缓存的费用,也会开始命中。
  • 图片更费 token。 从 4.6 及更早的模型升上来,高分辨率图片的 token 数最多是原来的三倍左右。不需要那么清晰的话,发之前先缩小。
  • 拒答。 这一代都带着安全分类器,要处理 stop_reason 为 refusal 的情况,见《报错、限流和停止原因》。
  • 价格。 Opus 5.5 比 Opus 5 便宜;Sonnet 5.5 和 Sonnet 5 同价,读缓存便宜一半;Haiku 5.5 的单价比 Haiku 4.5 低,但超过 10 万 token 的提示按另一档算。

一份可以照着过的清单

不管从哪个模型升:

  1. 改模型 ID。
  2. 按类型读内容块,不按位置。
  3. 工具循环里把 thinking 块原样传回去,包括空的。
  4. 把 tool_choice 的 any 和指定工具改成 auto,需要时加 strict: true。
  5. 删掉 thinking 的 disabled 和 enabled。Sonnet 5.5 上要关掉开头的思考,用 between_tools。
  6. 调大 max_tokens,给思考留出余量。
  7. 界面要显示工具调用之间的话的,设置 display。
  8. 处理 refusal。
  9. 对话历史只增不改。
  10. 重新试 effort,重新估算花费和延迟。

从 4.6 或更早的模型升,再加上:

  1. 删掉 temperature、top_p、top_k。
  2. 把思考预算换成 effort。
  3. 重新数 token,重新估图片的 token。

从 4.5 或更早的模型升,再加上:

  1. 去掉预填。
  2. 工具调用的参数用标准的 JSON 解析器解析。
  3. 删掉不再需要的 beta 头(interleaved-thinking、fine-grained-tool-streaming、上下文窗口的那几个)。
  4. output_format 挪到 output_config.format。

各个模型的完整清单在来源里的四份迁移指南里,比这里细。

通过中转站测到的和文档的出入

项目 文档 实测
Opus 5.5、Sonnet 5.5 强制调用工具 400 400,一致
Opus 5.5 关掉思考 400 400,一致
Sonnet 5.5 把 thinking 设成 disabled 400 200
预填 400 200
删掉或改动 thinking 块再传回 400 200
采样参数用非默认值 400 200,不知道有没有生效
默认不显示思考文字 是 一致
display 设成 summarized 能拿到摘要 是 一致
max_tokens 包含思考 是 一致

这带来一个实际的问题:在中转站上测试通过,不等于迁移做对了。 中转站放过去的那几种写法,换到官方接口上会被拒绝。迁移时以文档的清单为准,逐条对照代码,不要只看请求有没有成功。

这次实测没有覆盖到的

  • 官方接口没有测。
  • Haiku 5.5 和 Fable 5.1 没有单独测这些改动,它们的部分是按文档整理的。测试用的 key 没有开通 Haiku 5.5。
  • computer use、advisor 的配对、thinking 块跨模型和跨账号、对话中间的 system 消息、按需压缩,都没有试。
  • /claude-api migrate 这个 skill 没有试。
  • 每种情况只发了一次请求。

来源

通过 API 中转站使用这些模型?到 Veridrop 免费检测中转站给你的是不是它声称的模型,或者看看中转站排行榜前 100 名。

相关文章

  • 两周把 claude.ai 提速 3 倍:和 Claude 一起做性能优化的方法教程 · Claude Code · 约 11 分钟

    根据 Anthropic 工程师的文章整理:他们在一个 Slack 频道里和 Claude 协作,两周合并三千多个改动,把 claude.ai 的核心体验提速约 3 倍,没有出过事故。讲清“先找到能数的指标”的思路、每个线程的循环、护栏和人的分工。

  • 给 Claude 5.5 这一代写提示词:按现象查该改什么,哪些老写法该删教程 · Claude Code · 约 8 分钟

    老提示词在 Opus 5.5、Sonnet 5.5、Haiku 5.5、Fable 5.1 上基本能直接用,但每个模型有几处行为变了。本文把官方四份指南整理成一张“看到什么现象,改什么”的表,列出该删掉的老写法。实测一道要 JSON 答案的推理题:不思考时模型把推理写进回答里,答案是对的,但整段不再是合法的 JSON。

  • Claude 的思考和 effort 怎么调:五档各是什么、什么时候该调高、钱花在哪教程 · Claude Code · 约 11 分钟

    effort 控制 Claude 在一个回答上下多大功夫,思考只是其中一部分。本文整理五档的含义、各模型的默认值、思考怎么计费、怎么让它多想或少想,以及任务预算和快速模式。实测一道排期题:Sonnet 5.5 在 low 和 medium 上十次全错,调到 high 五次全对;再调到 max 要花三倍多的钱,答案一样。

  • Claude 现在有哪些模型、各多少钱、怎么选:价格表、模型 ID、下线时间和省钱的顺序教程 · Claude Code · 约 14 分钟

    Fable 5.1、Opus 5.5、Sonnet 5.5、Haiku 5.5 各管什么、官方价是多少、模型 ID 为什么不带日期、哪些老模型快下线了。本文按官方文档整理,并通过中转站实测了几件事:同一个任务在三个模型上差四倍多的钱;同一段中文在新旧模型上 token 数几乎一样,英文却多出近四成。