◉CLAUDE LABEN
●2.1.293 — v2.1.293 で Claude Haiku 5.5 が既定の Haiku モデルに(1M コンテキスト)●SONNET 4.5 — Claude API での提供終了は 11/30、残り53日。移行先は Sonnet 5.5●API CACHE — Sonnet 5.5 のキャッシュ読み取りが $0.10/Mtok に値下げ(10/07)●Q&A — 毎回読み込む指示ファイルが肥大化したとき、何から削るかという問いが出ています●HAIKU 5.5 — Haiku 4.5 向けコードは budget_tokens が 400 エラーになる点に注意●NEW — Pro を払ったのに無料のまま。買った場所で見る画面が変わります●2.1.293 — v2.1.293 で Claude Haiku 5.5 が既定の Haiku モデルに(1M コンテキスト)●SONNET 4.5 — Claude API での提供終了は 11/30、残り53日。移行先は Sonnet 5.5●API CACHE — Sonnet 5.5 のキャッシュ読み取りが $0.10/Mtok に値下げ(10/07)●Q&A — 毎回読み込む指示ファイルが肥大化したとき、何から削るかという問いが出ています●HAIKU 5.5 — Haiku 4.5 向けコードは budget_tokens が 400 エラーになる点に注意●NEW — Pro を払ったのに無料のまま。買った場所で見る画面が変わります
記事一覧/API & SDK
⬡ API & SDK/2026-10-08中級

Sonnet 4.5 の退役前に、コードに残った「400 になる引数」を一本のスクリプトで拾いました

claude-sonnet-4-5 は 11 月 30 日に退役します。モデル ID を書き換えるだけでは、budget_tokens・prefill・tool_choice などで 400 が返ります。公式の移行ガイドの該当箇所を正規表現にしたスキャナと、実行結果、直し方の順番をまとめました。

Claude API126Sonnet 5.5モデル廃止移行9スクリプト

退役の通知を受け取ってから、モデル ID の文字列を claude-sonnet-5-5 に置き換える作業を、私はずっと「一行の変更」だと思っておりました。

公式の移行ガイドを上から順に読んだのは、そのあとです。thinking の指定、sampling の引数、prefill、tool_choice、beta ヘッダ——モデル ID の外側に、同じリクエストを 400 にする記述がいくつも並んでいました。一行どころか、リクエストの組み立て方そのものに手が入ります。

最初にお伝えしたいのは、文字列を置換する前に、400 になる記述を機械的に拾っておくということです。そのためのスキャナを書き、手元の小さなサンプルで動かした結果を残しておきます。個人開発で小さなスクリプトから API を呼ぶ身としては、置換ひとつで済むと思い込んでいた自分が、少し恥ずかしくなりました。

退役の日付と、置き換え先

公式の廃止予定ページ(2026 年 10 月 8 日に確認)では、claude-sonnet-4-5-20250929 は 2026 年 9 月 30 日に Deprecated となり、退役予定日は 2026 年 11 月 30 日、推奨の置き換え先は claude-sonnet-5-5 です。退役後はリクエストが失敗します。

同じページに、この日付が当てはまる範囲も書かれています。Claude API、Claude Platform on AWS、Microsoft Foundry が対象で、Amazon Bedrock と Google Cloud は独自のスケジュールです。経由先によって日付が違う可能性がありますので、ご自身の呼び出し経路は別に確かめてください。

単価やトークナイザの差は、別の記事で扱っております。ここでは費用ではなく、「そもそもリクエストが通るか」だけに絞ります。

公式の移行ガイドから、400 や黙った誤動作になる項目を抜き出す

Sonnet 5.5 の移行ガイドのうち、Sonnet 4.5 から移るときに手を入れる必要があるものを、コードの上で見つけやすい順に並べました。

項目4.5 での書き方5.5 での扱い
samplingtemperature / top_p / top_k非既定値は 400。削除する
thinking の予算{"type": "enabled", "budget_tokens": N}エラー。adaptive と output_config.effort を使う
thinking を切る{"type": "disabled"}400。between_tools を使う
prefill末尾に assistant メッセージエラー。会話は user メッセージで終える
tool_choice"tool" / "any"エラー。auto と strict: true に置き換える
構造化出力output_format非推奨。output_config.format へ
beta ヘッダinterleaved-thinking-2025-05-14 など外す、または eager_input_streaming に置き換える
応答の読み方content[0].text先頭に thinking ブロックが来うる。type で探す

見落としやすいのは最後の行です。リクエストは通るのに、content[0] が thinking ブロックになって .text が取れない——エラーメッセージのない壊れ方は、本番で気づくのが遅れます。

また、リクエストに thinking を書いていない場合も、5.5 では adaptive thinking が既定で動きます。4.5 では動いていなかったものですので、max_tokens が thinking の分も含むことは頭に入れておく必要があります。

表をそのまま正規表現にしたスキャナ

上の表の「4.5 での書き方」を、一行ずつ正規表現にしました。完璧な構文解析ではなく、「人の目で確認する候補を出す」ことを割り切った道具です。

#!/usr/bin/env python3
"""Sonnet 4.5 -> 5.5 で 400 になりうる記述を拾う簡易スキャナ。
使い方: python3 sonnet55_scan.py <dir>   該当があれば exit 1"""
import re, sys, pathlib
 
RULES = [
    ("model-id",  r"claude-sonnet-4-5(?:-\d{8})?",            "モデルIDを claude-sonnet-5-5 へ"),
    ("sampling",  r"\b(temperature|top_p|top_k)\s*=",          "非既定値は 400。削除"),
    ("budget",    r"budget_tokens",                            "adaptive + output_config.effort へ"),
    ("think-off", r"""["']type["']\s*:\s*["']disabled["']""",  "disabled は 400。between_tools へ"),
    ("prefill",   r"""["']role["']\s*:\s*["']assistant["']""", "末尾が assistant なら prefill。要確認"),
    ("tool-choice", r"""["']type["']\s*:\s*["'](?:tool|any)["']""", "tool/any は 400。auto + strict へ"),
    ("output-fmt", r"\boutput_format\b",                       "output_config.format へ"),
    ("beta-hdr",  r"interleaved-thinking-2025-05-14|fine-grained-tool-streaming-2025-05-14", "ヘッダを外す/置き換える"),
    ("content0",  r"content\[0\]\.text",                       "thinking ブロックが先頭に来うる。type で探す"),
]
EXTS = {".py", ".ts", ".js", ".mjs", ".json", ".yaml", ".yml", ".env", ".md"}
 
def scan(root):
    hits = []
    for p in sorted(pathlib.Path(root).rglob("*")):
        if p.suffix not in EXTS or not p.is_file() or "node_modules" in p.parts:
            continue
        for n, line in enumerate(p.read_text(errors="ignore").splitlines(), 1):
            for tag, pat, hint in RULES:
                if re.search(pat, line):
                    hits.append((str(p), n, tag, hint, line.strip()))
    return hits
 
if __name__ == "__main__":
    hits = scan(sys.argv[1] if len(sys.argv) > 1 else ".")
    for f, n, tag, hint, src in hits:
        print(f"{f}:{n} [{tag}] {hint}\n    {src}")
    files = len({h[0] for h in hits})
    print(f"\n{len(hits)} 件 / {files} ファイル")
    sys.exit(1 if hits else 0)

prefill の規則は、"role": "assistant" を含む行をすべて拾います。過去の会話履歴を渡しているだけの正当な使い方も混ざりますので、ここは「会話の最後がその行になっていないか」を人が見る前提です。

動かした結果

4.5 向けの書き方を意図的に詰め込んだ 2 ファイルを用意し、実際に走らせました。1 つ目は temperature・budget_tokens・prefill・content[0].text を含む要約関数、2 つ目は beta ヘッダ・tool_choice・output_format を含む抽出処理です。

app/extract.py:4 [model-id] モデルIDを claude-sonnet-5-5 へ
    model="claude-sonnet-4-5",
app/extract.py:6 [beta-hdr] ヘッダを外す/置き換える
    betas=["interleaved-thinking-2025-05-14"],
app/extract.py:8 [tool-choice] tool/any は 400。auto + strict へ
    tool_choice={"type": "tool", "name": "pick"},
app/extract.py:9 [output-fmt] output_config.format へ
    output_format={"type": "json_schema", "schema": {}},
app/summarize.py:6 [model-id] モデルIDを claude-sonnet-5-5 へ
    model="claude-sonnet-4-5-20250929",
app/summarize.py:8 [sampling] 非既定値は 400。削除
    temperature=0.3,
app/summarize.py:9 [budget] adaptive + output_config.effort へ
    thinking={"type": "enabled", "budget_tokens": 2000},
app/summarize.py:12 [prefill] 末尾が assistant なら prefill。要確認
    {"role": "assistant", "content": "{"},
app/summarize.py:14 [content0] thinking ブロックが先頭に来うる。type で探す
    ).content[0].text
 
9 件 / 2 ファイル

終了コードは 1 でした。モデル ID の行は 2 件だけで、残りの 7 件は ID を置換しても残る記述です。置換だけで済ませていたら、7 箇所がそのまま 400 か誤動作に化けたことになります。

なお、これはスキャナの動作確認です。置き換えたコードを実際の API に投げて通ることまでは、この記事のために確かめておりません。直し方は公式の移行ガイドの記述に沿ったものですので、ご自身の環境で一度は通してください。

直す順番

ヒットを前にすると、上から順に直したくなります。私自身は次の順番が安全なのかもしれないと考えております。

  1. まず temperature などの sampling 引数と、budget_tokens・disabled を消します。どれも 400 で即座に気づけるものです。
  2. 次に prefill を外します。JSON を { から始めさせていた場合は、構造化出力(output_config.format)へ移すのが公式の案内です。
  3. tool_choice を auto にし、ツールに strict: true を付けます。strict ツールは、各オブジェクトに additionalProperties: false が要ります。
  4. 最後に content[0].text を、type を見て text ブロックを探す書き方に変えます。これだけはエラーが出ませんので、スキャナの出力から漏らさないことが大切です。

直したあとの要約関数は、たとえば次のようになります。

resp = client.messages.create(
    model="claude-sonnet-5-5",          # 日付サフィックスなし
    max_tokens=8000,                    # thinking の分も含めて見直す
    thinking={"type": "adaptive"},
    output_config={"effort": "medium"}, # 明示しておく
    messages=[{"role": "user", "content": text}],
)
# 先頭が thinking ブロックでも壊れない読み方
answer = next(b.text for b in resp.content if b.type == "text")

effort は 4.5 に無かった引数で、5.5 は五段階、API の既定は high です。既定に任せず明示しておくと、あとで挙動が変わったときに見比べられます。

次のアクション

今日は、ご自身のリポジトリでこのスキャナを一度だけ走らせてみてください。件数が 0 なら、退役日までの余裕は十分です。件数が出たなら、その数がそのまま、11 月 30 日までの作業量の見積もりになります。

期限が決まっているときほど、置換の前に「何が残るか」を数える——この原則だけは、次のモデル退役でも守るようにしております。

Sources: Model deprecations、Claude Sonnet 5.5 migration guide

シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

◉ Claude.ai2026-10-04
11月30日に止まる claude-sonnet-4-5、置き換え先が安いと決める前に請求の差分を確かめました
claude-sonnet-4-5-20250929 は 2026 年 11 月 30 日に退役します。推奨の claude-sonnet-5-5 は単価が下がる一方でトークナイザが変わり、temperature を付けたままだと 400 が返ります。読後に、自分の呼び出し箇所を棚卸しして置き換えの順番を決められます。
⬡ API & SDK2026-08-30
モデルIDを一括置換する前に、手元の CLI が抱えるカタログを引きます
新しい世代が出ると、前の世代のモデルIDが急に古く見えます。インストール済みの実行ファイルに埋め込まれたカタログを引き、一致・日付不一致・書式破損の三段に仕分けてから直す手順を、実測値とスクリプトつきでまとめました。
⬡ API & SDK2026-08-14
Workbench が止まる8月17日までに、prompt tools API を手元のスクリプトへ移す
旧 Workbench と3つの実験的プロンプトエンドポイントが2026年8月17日に終了します。依存箇所の数え方と、templatize_prompt・improve_prompt を手元のスクリプトへ移す実装を、実際の出力つきでまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます