自分のコード例とメモを見返して、claude-sonnet-4-5 の出てくる行を数えていた夜のことです。
退役表に載っている ID は claude-sonnet-4-5-20250929。日付がついています。ところが私の手元には、日付のない claude-sonnet-4-5 のほうが多く残っていました。数えてみると、日付なしが 69 か所、日付ありが 61 か所です。
日付を書いていないのだから、表の「11 月 30 日」とは別の話ではないか。 そう思いかけて、手が止まりました。この思い込みが正しいのか、公式の記述で確かめた記録をお渡しします。
退役表に載っているのは、日付つきの ID だけです
公式のモデル廃止ページの表には、現時点でこう書かれています。
| API model name | Current state | Deprecated | Tentative retirement date |
|---|---|---|---|
| claude-sonnet-4-5-20250929 | Deprecated | September 30, 2026 | November 30, 2026 |
| claude-sonnet-4-6 | Active | N/A | Not sooner than February 17, 2027 |
推奨の移行先は claude-sonnet-5-5 です。表に claude-sonnet-4-5(日付なし)の行はありません。そのため「載っていない=対象外」と読みたくなります。ここが落とし穴でした。
日付なしの ID は、最新の日付つき ID を指す別名です
別のページ「Model IDs and versioning」に、答えに近い記述がありました。4.6 より前の世代のモデルには、API 上で短い別名が使えます。たとえば claude-sonnet-4-5 は、同じ minor バージョンの最も新しい日付つきスナップショットを指す、と書かれています。
つまり claude-sonnet-4-5 は独立したモデルではなく、claude-sonnet-4-5-20250929 への近道です。同じページには、どの ID にも固有の廃止・退役の予定がある、という一文もあります。
私の読みを整理すると、次のとおりです。
| 書き方 | 公式の説明 | 11 月 30 日との関係 |
|---|---|---|
| claude-sonnet-4-5-20250929 | 日付つきのスナップショット | 表の行そのもの。対象です |
| claude-sonnet-4-5 | 最新の日付つきスナップショットを指す別名 | 指し先が 20250929 なので、同じ日に止まると読むのが自然です |
| claude-sonnet-4-6 | 日付なしだが別名ではなく、スナップショットそのもの | 別の ID。表では 2027 年 2 月 17 日が下限です |
「同じ日に止まる」の部分は、公式が一文で言い切っているわけではありません。別名の仕組みから導いた私の解釈です。ですから、対象外と信じて放置するより、対象として動くほうが安全だと判断しました。
もう一つ、混同しやすい点があります。claude-sonnet-4-6 のように日付のない ID は、4.6 世代以降では別名ではありません。公式は、最新版へ自動で付け替わる「evergreen」ではなく、固定されたスナップショットだと明記しています。日付の有無は、新しさの印にはならないのです。
日付あり・なしの両方を、一度に拾います
別名が混じっていると、日付つきだけを検索しても取りこぼします。拾う正規表現は一つで足ります。
# 日付つき・なしの両方と、Bedrock / Google Cloud 表記もまとめて拾う
grep -rnE --exclude-dir=node_modules --exclude-dir=.git \
'claude-sonnet-4-5(-20250929|@20250929|-v1:0)?' .Amazon Bedrock では anthropic.claude-sonnet-4-5-20250929-v1:0、Google Cloud(Google managed)では claude-sonnet-4-5@20250929 という形で現れます。上の式はこの三つの顔を同時に拾います。ただし、Bedrock や Google managed の側は、退役日を各社が別に決めると公式に書かれています。表の 11 月 30 日は、Anthropic が運営する側の日付です。そこは分けて見てください。
見つかった行は、設定ファイルと、ドキュメント上の説明文に分けます。止まって困るのは、実際にリクエストを送る行だけです。
迷ったら、レスポンスで指し先を確かめます
別名がどれを指しているかは、実際に一度送ってみると分かります。レスポンスの model 欄に、解決後の ID が入っているからです。
import anthropic
client = anthropic.Anthropic() # ANTHROPIC_API_KEY は環境変数から読む
msg = client.messages.create(
model="claude-sonnet-4-5", # 別名で送る
max_tokens=16,
messages=[{"role": "user", "content": "ok と返してください"}],
)
print(msg.model) # 手元で確かめた指し先がここに出る出力が日付つきの ID なら、別名の指し先が分かります。私はこの確認を、置き換えを始める前に一度だけ行うことにしました。
置き換えの前に、一つだけ決めます
見つかった行を機械的に全部書き換える前に、「実際に送っている行か」を分けてください。呼び出し元の洗い出しは、grep だけでは足りない場合もあります。その手順は、Usage の CSV から呼び出し元を数えた記録に書きました。一括置換の前に手元のカタログを引く方法は、モデルIDを一括置換する前に、手元の CLI が抱えるカタログを引くにまとめています。
日付の有無ではなく、どの ID に解決されるかで数えます。 今回の線引きは、この一文だとあとから気づきました。
まずは今日のうちに、上の grep を一度だけ走らせて、日付なしの行が何か所あるかを数えてみていただければと思います。残りは 3 週間ほどです。数が分かれば、あとの段取りは自然に決まってきます。