◉CLAUDE LABEN
●2.1.302 — fork サブエージェントが claude -p・Agent SDK・デスクトップで既定オンになりました。無効化は CLAUDE_CODE_FORK_SUBAGENT=0(10/16)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り43日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.302 — fork サブエージェントが claude -p・Agent SDK・デスクトップで既定オンになりました。無効化は CLAUDE_CODE_FORK_SUBAGENT=0(10/16)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り43日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/API & SDK
⬡ API & SDK/2026-10-18中級

Sonnet 4.5 の退役まで 43 日 — 呼び出し元は grep ではなく、Usage の CSV から数えました

claude-sonnet-4-5 は 11 月 30 日に退役します。コードの grep は「書かれたもの」しか教えてくれません。Console の Usage CSV と、コード内のモデル ID を 1 本のスクリプトで突き合わせる手順と、実際に走らせた結果をまとめました。

Claude API129Sonnet 4.5モデル廃止3Usage棚卸し

Sonnet 4.5 の退役日を公式の表で確かめたあと、私が最初にしたのは、リポジトリで claude-sonnet-4-5 を grep することでした。

出てきたのは、タグと URL のスラッグと、過去の記事本文でした。API を呼んでいる行は、1 本もありません。それでも安心はできませんでした。個人開発でサイトとアプリを動かしていると、「自分が書いた覚えのない呼び出し」がいちばん怖いのだと、あらためて感じています。コードに書かれていない呼び出し——環境変数、別マシンのスクリプト、ノーコードの連携、もう動かしたことを忘れていた古いキー——は、grep の網には掛からないからです。

退役日は 2026 年 11 月 30 日で、今日は 10 月 18 日。残りは 43 日です。急がなくてもまだ間に合う日数ですが、「どこで使っているか」を文字列検索で探すのをやめ、使われた事実の側から数えることにしました。その手順をお伝えします。

公式が決めている日付と、置き換え先

公式の model deprecations ページ(2026 年 10 月 18 日に確認)で、期限が付いているモデルは次のとおりです。

モデル ID状態退役(見込み)推奨される置き換え先
claude-sonnet-4-5-20250929Deprecated(9/30 告知)2026-11-30claude-sonnet-5-5
claude-opus-4-5-20251101Active11/24 より前にはならない未告知
claude-haiku-4-5-20251001Active10/15 より前にはならない未告知

下の 2 行は、まだ退役の告知ではありません。公式の表が「Tentative retirement date: Not sooner than」としている、最短の日付です。ただ、Sonnet 4.5 も告知から退役まで 61 日でした。公式は公開済みモデルに少なくとも 60 日の予告を約束していますので、この 2 行は「いつ告知が来てもおかしくない行」として棚卸しの対象に入れておくのが私の線引きです。

もう一点、日付は Anthropic が運用するプラットフォーム(Claude API、AWS 上の Claude Platform、Microsoft Foundry)のものです。Amazon Bedrock と Google Cloud は、それぞれの退役スケジュールを持っています。Bedrock 経由で呼んでいる方は、Bedrock 側の表をご覧ください。

grep は「書かれている」ことしか教えてくれません

棚卸しの道具を 2 つに分けました。

  • コード側: 設定ファイルとスクリプトに残ったモデル ID の数(書かれているもの)
  • 利用実績側: Console の Usage ページから書き出した CSV の、キー別・モデル別の量(実際に使われたもの)

公式の手順は単純です。Console の Usage ページを開き、Export を押し、ダウンロードした CSV でモデル別・API キー別の内訳を確認します。コードに書かれているのに 1 トークンも流れていない行は後回しにでき、コードに見当たらないのに流れているキーは、真っ先に持ち主を探すべき対象になります。

最初に私がつまずいたのは、コード側の数え方でした。リポジトリ全体に対して claude- で始まる文字列を拾うと、記事本文のモデル名まで入って、417 件も出たのです。数字が大きいほど「まだ大量に残っている」と錯覚します。いま思えば、数字の大きさに安心も不安も預けていたのは私の側でした。拾った件数ではなく、拾った種類を先に疑う——この線引きを、スクリプトの最初の仕様にしました。

2 つの数え方を 1 本にしたスクリプト

次のスクリプトは、ディレクトリを走査してモデル ID を数え、期限付きの ID には日付と置き換え先を添えます。--code を付けると、コード・設定の拡張子だけを見ます。--csv に Usage の CSV を渡すと、model を含む列でグルーピングして、数値の列をすべて合計します。

列名は固定していません。Console の CSV の見出しは、私の手元では確認できていないからです。公式が示しているのは「API キー別・モデル別の内訳」という点までで、列名は書かれていません。そのため、見出しに model を含む列を探す作りにしました。見つからなければ、見出しの一覧を出して止まります。

#!/usr/bin/env python3
"""model_inventory.py — コード内のモデル ID と、Console の Usage CSV を同じ表で突き合わせる。
使い方: python3 model_inventory.py <ディレクトリ> [--code] [--csv usage.csv]
  --code  設定・コードの拡張子だけを見る(記事本文やタグの文字列を拾わない)
"""
import csv, re, sys, pathlib, collections
 
# 公式 model-deprecations の「Model status」表(2026-10-18 取得)から、期限のあるものだけ
RETIRE = {
    "claude-sonnet-4-5-20250929": ("2026-11-30", "claude-sonnet-5-5"),
    "claude-opus-4-5-20251101":   ("2026-11-24以降(最短)", "claude-opus-5-5"),
    "claude-haiku-4-5-20251001":  ("2026-10-15以降(最短)", "claude-haiku-5-5"),
}
SKIP_DIRS = {".git", "node_modules", ".next", "dist", "build", "__pycache__", "generated"}
CODE_EXT = {".py", ".js", ".mjs", ".ts", ".tsx", ".sh", ".yaml", ".yml", ".toml", ".env", ".cfg", ".ini"}
SKIP_EXT = {".png", ".jpg", ".jpeg", ".gif", ".webp", ".pdf", ".zip", ".lock", ".woff", ".woff2"}
# 数字で終わる ID だけを拾う。slug(claude-opus-4-6-release など)を巻き込まない
ID_RE = re.compile(
    r"claude-(?:(?:sonnet|opus|haiku|fable|mythos)-\d+(?:-\d+)?(?:-\d{8})?"
    r"|3-(?:5-haiku|haiku|7-sonnet)-\d{8})(?![A-Za-z0-9]|-[A-Za-z0-9])"
)
 
def scan(root, code_only=False):
    hits = collections.defaultdict(list)
    for p in pathlib.Path(root).rglob("*"):
        if not p.is_file() or p.suffix.lower() in SKIP_EXT:
            continue
        if any(part in SKIP_DIRS for part in p.parts):
            continue
        if code_only and p.suffix.lower() not in CODE_EXT and p.name != ".env":
            continue
        try:
            text = p.read_text(encoding="utf-8")
        except (UnicodeDecodeError, OSError):
            continue
        for n, line in enumerate(text.splitlines(), 1):
            for m in ID_RE.findall(line):
                hits[m].append(f"{p}:{n}")
    return hits
 
def read_usage(path):
    """model を含む見出しの列でグループ化し、数値列を合計する。列名は固定しない。"""
    with open(path, newline="", encoding="utf-8-sig") as f:
        rows = list(csv.DictReader(f))
    if not rows:
        return {}
    cols = rows[0].keys()
    mcol = next((c for c in cols if "model" in c.lower()), None)
    if mcol is None:
        sys.exit("model を含む列が見つかりません: " + ", ".join(cols))
    numeric = [c for c in cols if c != mcol and all(_num(r[c]) is not None for r in rows if r[c] != "")]
    out = collections.defaultdict(lambda: collections.Counter())
    for r in rows:
        for c in numeric:
            v = _num(r[c])
            if v is not None:
                out[r[mcol]][c] += v
    return out
 
def _num(s):
    try:
        return float(str(s).replace(",", ""))
    except ValueError:
        return None
 
def main():
    args = sys.argv[1:]
    root = args[0] if args else "."
    csv_path = args[args.index("--csv") + 1] if "--csv" in args else None
    hits = scan(root, code_only="--code" in args)
    print(f"== コード内のモデル ID({root})")
    for mid in sorted(hits, key=lambda k: (k not in RETIRE, k)):
        note = ""
        if mid in RETIRE:
            d, to = RETIRE[mid]
            note = f"  ← 期限 {d} / 置き換え先 {to}"
        print(f"{len(hits[mid]):4d}  {mid}{note}")
        if mid in RETIRE:
            for loc in hits[mid][:5]:
                print(f"        {loc}")
    if csv_path:
        print(f"\n== Usage CSV({csv_path})")
        for model, cnt in read_usage(csv_path).items():
            flag = "  ← 期限あり" if model in RETIRE else ""
            print(model + flag)
            for c, v in cnt.items():
                print(f"    {c}: {v:,.0f}")
 
if __name__ == "__main__":
    main()

モデル ID の正規表現には、癖があります。claude-sonnet-4-6-vs-... のような URL スラッグを巻き込まないよう、「ID の直後に英数字かハイフン+英数字が続くものは拾わない」と先読みで制限しました。最初の版ではここが緩く、claude-sonnet-4 が単独で 4 件も出てしまい、バックトラックで先頭だけが一致していたのが原因でした。

動かした結果

まず、このサイトのリポジトリ(Next.js)でコードと設定だけを走査しました。

python3 model_inventory.py ~/repos/claudelab.net --code

結果は、見出しの行が 1 本出ただけで、中身は空でした。Claude API を呼ぶコードは、このリポジトリには 1 行もありません。--code なしで走らせると 400 件を超える一致が出ますが、すべて記事本文・タグ・URL スラッグです。数が多いことと、移行が必要なことは別の話でした。

次に、期待どおり動くかを確かめるため、動作確認用の小さな CSV を手で作りました(実際の Console の書き出しではなく、列名も私が仮に決めたものです)。

date,api_key,model,input_tokens,output_tokens
2026-10-01,key_wallpaper_batch,claude-sonnet-4-5-20250929,1200000,210000
2026-10-01,key_wallpaper_batch,claude-sonnet-5-5,300000,52000
2026-10-01,key_translate,claude-haiku-4-5-20251001,880000,140000
2026-10-02,key_translate,claude-haiku-4-5-20251001,910000,150000
2026-10-02,key_wallpaper_batch,claude-sonnet-4-5-20250929,1100000,190000
python3 model_inventory.py ~/repos/claudelab.net --code --csv usage_sample.csv
== Usage CSV(usage_sample.csv)
claude-sonnet-4-5-20250929  ← 期限あり
    input_tokens: 2,300,000
    output_tokens: 400,000
claude-sonnet-5-5
    input_tokens: 300,000
    output_tokens: 52,000
claude-haiku-4-5-20251001  ← 期限あり
    input_tokens: 1,790,000
    output_tokens: 290,000

このサンプルの数字は架空です。見ていただきたいのは、期限付きのモデルに旗が立ち、移行が済んだ分(claude-sonnet-5-5)と未了の分が同じ画面で並ぶという形です。本物の CSV で列名が違った場合は、read_usage の中の 1 行("model" in c.lower())だけを直せば足ります。

見つかった行のあと、手を付ける順番

文字列の置き換えだけで終わらせず、次の順に進めるつもりです。

  1. Usage の CSV で、claude-sonnet-4-5-20250929 を実際に流しているキーを特定します(持ち主と用途を書き出します)
  2. そのキーの呼び出し元を探します。コード側のスキャンで見つからなければ、環境変数・CI の変数・ノーコード連携の設定画面を順に開きます
  3. モデル ID を置き換える前に、移行ガイドの引数の差分を確認します(budget_tokens・prefill・tool_choice など。400 になる項目は「Sonnet 4.5 の退役前に、コードに残った「400 になる引数」を一本のスクリプトで拾いました」で一覧にしています)
  4. 置き換えた 1 週間後にもう一度 CSV を書き出し、旧 ID の行が増えていないことを確かめます

4 番目を入れたのは、置き換えが「済んだつもり」で終わりやすいからです。古い設定のコピーが別のマシンに残っていれば、旧 ID はまた流れ始めます。書き出しをもう一度見るだけで防げる種類の取りこぼしですので、手間を惜しまないことにしました。

次のアクション

今週のうちに、Console の Usage から CSV を 1 回だけ書き出してみてください。モデルの列でソートして、claude-sonnet-4-5-20250929 の行があるかどうかを見るだけで十分です。ある場合は、API キーの名前から、持ち主と用途を紙に書き出すところまでを今日の仕事にします。

探すのは文字列ではなく、流れたトークンの持ち主です。 残り 43 日のうち、最初の 1 日をそこに使うことにしました。

シェア

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

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

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

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

関連記事

⬡ API & SDK2026-10-08
Sonnet 4.5 の退役前に、コードに残った「400 になる引数」を一本のスクリプトで拾いました
claude-sonnet-4-5 は 11 月 30 日に退役します。モデル ID を書き換えるだけでは、budget_tokens・prefill・tool_choice などで 400 が返ります。公式の移行ガイドの該当箇所を正規表現にしたスキャナと、実行結果、直し方の順番をまとめました。
⬡ API & SDK2026-10-16
Make から Claude API に 40 行流すと 14 行目で止まる — 429 を待ち時間の計算で避ける
表計算の行を1件ずつ Claude API に渡すノーコード自動化が、途中で 429 になる理由と直し方です。模擬バケットで7通りの間隔を比べ、Sleep の秒数を 60÷上限−応答時間 で決める式と、失敗行を落とさない設定を示します。
⬡ API & SDK2026-10-13
Haiku 5.5 は単価が下がるのに、4.5 換算で約 7.7 万トークンを超えると請求が跳ねます
Haiku 4.5 から 5.5 へ移すと、価格表だけ見れば約 1/10 です。ただし同じ文章が約 30% 多いトークンになり、入力が 10 万を超えた時点で単価が 5 倍になります。境目を 4.5 換算で計算し、実際に動かした出力と、移行時に直す 400 の項目を並べました。