日曜の朝、コーヒーを淹れてから公式のモデル一覧表を開きました。11 月は Sonnet 4.5 の退役が控えているので、月初のうちに表を一度読み直しておきたかったのです。
表を上から眺めていて、手が止まった行があります。claude-opus-4-5-20251101 の「退役予定日」の欄に、Not sooner than November 24, 2026 と書かれていました。来月の日付です。一瞬、胃のあたりが冷たくなりました。
けれど落ち着いて隣の列を見ると、状態は Active、Deprecated の欄は N/A です。退役の通知は出ていません。表の「早くとも」と、本当に止まる日は、別のものだったのです。
ここからは、その読み分けを 11 月 1 日時点の表で整理していきます。あわせて、手元のファイルに残っているモデル ID を数えて表と突き合わせる小さなスクリプトも置いておきます。実際に私の作業フォルダで走らせた結果つきです。
表の四つの言葉と、いま自分に関係する行
公式の「Model deprecations」ページは、モデルの状態を四つの言葉で分けています。
| 状態 | 公式の説明(要旨) | あなたの手元でやること |
|---|---|---|
| Active | 完全にサポートされ、利用が推奨される | 何もしない。日付欄は「早くとも」の下限 |
| Legacy | 更新は止まるが、すぐ止まるわけではない | 置き換え先を頭の片隅に置く |
| Deprecated | 動くが非推奨。置き換え先と退役日が決まる | 退役日までに移す。日付が実際の期限 |
| Retired | 利用不可。リクエストは失敗する | 参照が残っていれば今すぐ直す |
この表から、11 月 1 日時点で私に関係する行を三つだけ拾いました。
| モデル ID | 状態 | 日付欄の読み方 |
|---|---|---|
| claude-sonnet-4-5-20250929 | Deprecated | 2026-11-30 に退役(置き換え先 claude-sonnet-5-5)。残り 29 日 |
| claude-opus-4-5-20251101 | Active | 2026-11-24 より早くは退役しない。通知はまだ無い |
| claude-haiku-4-5-20251001 | Active | 2026-10-15 より早くは退役しない。日付は過ぎたが通知は無い |
三行は同じ「日付つきの行」に見えますが、期限として扱ってよいのは一番上だけです。
「早くとも」の日付は、止まる日ではありません
読み分けの根拠は、同じページの Notifications の節にあります。公開済みのモデルについて、Anthropic は退役の少なくとも 60 日前に通知する、という趣旨の記載です。
Sonnet 4.5 の行を見ると、この約束がそのまま当てはまります。通知が出たのは 9 月 30 日、退役日は 11 月 30 日で、間は 61 日。Deprecated になった日に、期限が決まったわけです。
一方、Opus 4.5 は Deprecated の欄が N/A のままです。表の文面どおりに読めば、まだ誰にも通知が出ていないモデルに、11 月 24 日という期限は存在しません。「Not sooner than」は、これより前には止めない、という下限の宣言にすぎないのです。
ここで一つ、私自身の線引きを書き残しておきます。
日付が期限になるのは、状態が Deprecated になった行だけ。 Active の行の日付は、見張り始める合図として受け取ります。
もちろん、下限が近づけば通知が出る可能性は上がります。ですから Opus 4.5 の行は「放置してよい」ではなく、「通知のメールが届いた瞬間に動けるよう、手元の参照だけ先に把握しておく」行です。Haiku 4.5 の行も同じ扱いです。日付を過ぎたのに通知が出ていない状況の見方は、「最短 10 月 15 日」を過ぎた Haiku 4.5 は、止まる日が決まったわけではありませんにまとめました。
もう一点、表の冒頭に小さく書かれていた注意があります。この日付が当てはまるのは、Claude API、AWS 上の Claude Platform、Google Cloud の Anthropic 管理版、Microsoft Foundry といった Anthropic 運営のプラットフォームです。Amazon Bedrock と Google 管理版は、各社が独自の退役スケジュールを持つので、同じモデルでも日付が違いえます。経由先が複数ある方は、表を二枚見る必要があります。
手元のモデル ID を数える 60 行
表が読めたら、次は「自分の手元に、どの ID が何か所残っているか」です。個人開発の作業フォルダには、AI に任せている雑務のスクリプトや設定ファイルがいくつかあり、どこにどのモデル名を書いたのか、私自身がもう覚えていません。
そこで、フォルダ内のテキストファイルからモデル ID を拾い、手で写した退役表と突き合わせるスクリプトを書きました。node_modules などは飛ばし、読めないファイルは件数に入れずに先へ進みます。
#!/usr/bin/env python3
"""フォルダ内のテキストファイルから Claude のモデル ID を拾い、退役表の状態と突き合わせる。"""
import re
import sys
from collections import Counter
from pathlib import Path
# 2026-11-01 時点の公式「Model deprecations」表を手で写したもの。更新日を必ず併記する
STATE = {
"claude-sonnet-4-5-20250929": ("Deprecated", "2026-11-30 退役"),
"claude-opus-4-5-20251101": ("Active", "2026-11-24 より早くは退役しない"),
"claude-haiku-4-5-20251001": ("Active", "2026-10-15 より早くは退役しない(日付は経過)"),
"claude-opus-4-6": ("Active", "2027-02-05 より早くは退役しない"),
"claude-sonnet-4-6": ("Active", "2027-02-17 より早くは退役しない"),
"claude-sonnet-4-20250514": ("Retired", "2026-06-15 退役済み"),
"claude-opus-4-20250514": ("Retired", "2026-06-15 退役済み"),
"claude-opus-4-1-20250805": ("Retired", "2026-08-05 退役済み"),
}
# 日付つきの形(-20250514)を先に試す。順序を逆にすると日付の先頭 1 桁だけ拾って別の ID に化ける
PATTERN = re.compile(r"claude-(?:opus|sonnet|haiku)-\d(?:-\d{8}|-\d(?:-\d{8})?)?")
TEXT_SUFFIX = {".py", ".js", ".ts", ".json", ".yaml", ".yml", ".toml", ".sh", ".md", ".txt", ".env"}
def scan(root: Path) -> Counter:
found = Counter()
for path in root.rglob("*"):
if not path.is_file() or path.suffix not in TEXT_SUFFIX:
continue
if any(part in {"node_modules", ".git", ".next"} for part in path.parts):
continue
try:
text = path.read_text(encoding="utf-8")
except (UnicodeDecodeError, OSError):
continue # 読めないファイルは黙って飛ばす(件数には入らない)
found.update(PATTERN.findall(text))
return found
def main() -> None:
root = Path(sys.argv[1] if len(sys.argv) > 1 else ".")
found = scan(root)
print(f"{'モデル ID':36} {'件数':>4} {'状態':10} 備考")
for model, count in found.most_common():
state, note = STATE.get(model, ("表に無い", "公式の表で確認"))
print(f"{model:36} {count:>4} {state:10} {note}")
if __name__ == "__main__":
main()使い方は、調べたいフォルダを一つ渡すだけです。
python3 model_id_state.py ~/my-scriptsこのコードで先に決めた線引きが二つあります。一つ目は、表に無い ID を黙って捨てず、「表に無い」と明示して出すこと。何も出ない状態と、確認が必要な状態を見分けられなくなるのが、いちばん怖かったからです。二つ目は、状態の対応表に更新日を書き添えること。手で写した表は、写した瞬間から古くなっていきます。
最初の実行で、正規表現が別の ID に化けていました
作業フォルダの二か所に向けて走らせたところ、先に書いた版では、結果に claude-opus-4-2 と claude-sonnet-4-2 という存在しない ID が 4 件ずつ並びました。
原因は正規表現の順序でした。claude-opus-4-20250514 のように日付が付いた ID で、先に「ハイフンと数字 1 桁」の部分が日付の頭の 2 を拾ってしまい、残りの 7 桁はどこにもまとまらず、切り捨てられていたのです。
直し方は、日付つきの形を先に試す順序へ入れ替えるだけでした。
# Before: 日付の先頭 1 桁を拾って別の ID になる
re.compile(r"claude-(?:opus|sonnet|haiku)-\d(?:-\d)?(?:-\d{8})?")
# After: 日付つきの形 -> 世代つきの形、の順に試す
re.compile(r"claude-(?:opus|sonnet|haiku)-\d(?:-\d{8}|-\d(?:-\d{8})?)?")直したあとは、同じ 8 件が claude-sonnet-4-20250514 と claude-opus-4-20250514 に正しく戻り、状態も Retired と判定されました。退役済みの ID が手元に 4 件ずつ残っている、という事実は、直す前の出力では見えていなかったことになります。
数えた結果の読み方 — 件数の多さと危険度は別です
直したスクリプトの結果を、二つのフォルダで並べます。
| 調べたフォルダ | 拾えた ID の傾向 | 読み取れたこと |
|---|---|---|
| 手順書・スクリプトの置き場 | 6 種類、各 1 件。Deprecated・Retired は 0 件 | 期限に当たる呼び出しは見当たらない |
| 調べ物のメモの置き場 | 19 種類。Sonnet 4.5 が 27 件、Retired が計 10 件 | メモ書きの言及であり、呼び出しではない |
メモの置き場では、退役予定の claude-sonnet-4-5-20250929 が 27 件も出ました。最初はどきりとしましたが、中身を開くと、すべて退役を調べて書いたメモの本文でした。リクエストに載る場所ではありません。
件数の多さと危険度は、別のものです。メモが多いフォルダでは、Deprecated の件数がそのまま警報になるわけではありません。私は、実行されるファイル(.py・.js・.sh・設定)と、読み物のファイル(.md・.txt)を分けて数え直すことにしました。
もう一つ気づいたのは、「表に無い」の欄がいちばん長かったことです。claude-opus-4-8 のような新しい世代の ID が、手で写した表に載っていないだけで、危険という意味ではありません。それでも、表に載せていない ID が大半を占める状態では、突き合わせの意味が薄れます。月初に公式の表と見比べて、行を足していく。この手間は省けないのだと思います。
今週のうちにやること
最後に、行動を一つだけ選ぶなら、次の一手です。
実行されるファイルだけを対象に、claude-sonnet-4-5-20250929 を探してください。0 件なら、11 月 30 日の期限は手元には届きません。1 件でも見つかれば、置き換え先の claude-sonnet-5-5 へ差し替える前に、同じ入力で出力を見比べる時間を取っておくと安心です。
Usage ページの CSV から呼び出し元を数える方法は、Sonnet 4.5 の退役まで 43 日 — 呼び出し元は grep ではなく、Usage の CSV から数えましたに残してあります。ファイルの中を探すスクリプトと、実際の利用履歴は、見る場所が違います。両方を重ねて、初めて抜けが減るのだと感じています。
日曜のうちに一度走らせて、結果を月曜の自分に残しておくつもりです。