Claude Media
Claude API modelsのcapabilitiesを判定する方法

Claude API modelsのcapabilitiesを判定する方法

GET /v1/modelsのcapabilitiesオブジェクトから、effort・thinking・context_managementの対応状況をプログラムで判定する実装パターン。

capabilitiesオブジェクトで何が分かるか

Claude APIの GET /v1/models は、利用可能なモデルの一覧を返します。各モデルには capabilities オブジェクトが付き、effort=xhigh への対応、思考モード(thinking)で受け付ける type、使えるコンテキスト管理の戦略まで分かります。モデル一覧ページの比較表を目でコピーする代わりに、APIレスポンスから機能対応を判定する実装を組みます。

前提として必要なのはAPIキーだけです。エンドポイントはGETのみで、リクエストボディは不要です。SDKを使わず生のHTTPリクエストで完結するので、CI上の起動前チェックやシェルスクリプトからも呼び出せます。

モデルの世代交代のたびに困るのは、対応表のハードコードです。effortの対応レベルやthinkingのtype対応をコード側のif文に書いていると、モデルが増えるたびに書き換えとデプロイが要ります。capabilities を起動時に1回取得して判定に使えば、その更新作業をAPI呼び出し1本に置き換えられます。

ステップ1: モデル一覧を取得する

まず GET /v1/models を叩いて、利用できる全モデルの ModelInfo 配列を取得します。

curl https://api.anthropic.com/v1/models \
    -H "anthropic-version: 2023-06-01" \
    -H "x-api-key: $ANTHROPIC_API_KEY"

レスポンスは新しく公開されたモデルほど先頭に並びます。ページネーションは after_id / before_id / limit のクエリパラメーターで行い、limit はデフォルト20、最大1000です。レスポンスには has_more と last_id も入るので、has_more が false になるまで after_id=<last_id> で続きを取れば、モデル数が増えても取りこぼしません。

複数のWorkspaceを操作できる認証情報を使う場合は、anthropic-workspace-id ヘッダーでWorkspaceを選びます。特定のWorkspaceに属する認証情報なら省略でき、送るなら一致している必要があります。

各モデルの capabilities フィールドには、次の項目が入ります。

フィールド内容
batch内容Batch APIに対応するか
citations内容引用生成に対応するか
code_execution内容コード実行ツールに対応するか
context_management内容コンテキスト管理の対応可否と、clear_thinking_20251015 / clear_tool_uses_20250919 / compact_20260112 各戦略の対応状況
effort内容low / medium / high / max / xhigh 各レベルの対応状況
image_input / pdf_input内容画像・PDF入力への対応
structured_outputs内容構造化出力(JSONモード・厳格なツールスキーマ)への対応
thinking内容thinking対応可否と、adaptive / enabled 各typeの対応状況

型定義では capabilities 自体が ModelCapabilities or null で、null のモデルがあり得ます。capabilities がオブジェクトのときは、既知の機能のキーが必ず揃っています。

ただし例外があります。effort.xhigh と、context_management の個別戦略3つは CapabilitySupport or null です。capabilities.effort.xhigh.supported のように無条件で降りるコードは、どこかが null のモデルに当たった時点で例外になります。

レスポンスの例は次の形です(claude-opus-5)。

{
  "id": "claude-opus-5",
  "capabilities": {
    "batch": { "supported": true },
    "citations": { "supported": true },
    "code_execution": { "supported": true },
    "context_management": {
      "clear_thinking_20251015": { "supported": true },
      "clear_tool_uses_20250919": { "supported": true },
      "compact_20260112": { "supported": true },
      "supported": true
    },
    "effort": {
      "high": { "supported": true },
      "low": { "supported": true },
      "max": { "supported": true },
      "medium": { "supported": true },
      "supported": true,
      "xhigh": { "supported": true }
    },
    "image_input": { "supported": true },
    "pdf_input": { "supported": true },
    "structured_outputs": { "supported": true },
    "thinking": {
      "supported": true,
      "types": {
        "adaptive": { "supported": true },
        "enabled": { "supported": true }
      }
    }
  },
  "created_at": "2026-07-24T00:00:00Z",
  "display_name": "Claude Opus 5",
  "max_input_tokens": 0,
  "max_tokens": 0,
  "type": "model"
}

リファレンスの例では、max_input_tokens と max_tokens が 0 のプレースホルダです。型は number or null なので、0 や null を上限値として扱わない分岐を入れておきます。

created_at はRFC 3339形式で、リリース日時が不明なモデルにはエポック値が入ることがあります。新しさで並べ替えるとエポック値が「最古」に落ちるので、順序はレスポンスの並び(新しいモデルが先頭)をそのまま使うのが手堅い選択です。

ステップ2: capabilitiesから対応表を作る

一覧取得したレスポンスから、effort=xhigh に対応するモデルIDだけを抽出する処理は次のようになります。?. と === true の組み合わせが、null のキーをすべて「非対応」として扱う書き方です。

const res = await fetch("https://api.anthropic.com/v1/models?limit=1000", {
  headers: {
    "anthropic-version": "2023-06-01",
    "x-api-key": process.env.ANTHROPIC_API_KEY!,
  },
});
const { data } = await res.json();
 
const xhighModels = data
  .filter((m: any) => m.capabilities?.effort?.xhigh?.supported === true)
  .map((m: any) => m.id);

同じ形で thinking.types.adaptive.supported を見れば、アダプティブ思考(モデルが思考量を決め、effortで方向づける方式)に対応するモデルだけを絞り込めます。context_management.compact_20260112.supported を見れば、compaction戦略が使えるモデルの一覧になります。

複数のcapabilityを同時に満たすモデルを選ぶ処理も、フィルタを重ねるだけです。

const eligible = data.filter((m: any) =>
  m.capabilities?.effort?.xhigh?.supported === true &&
  m.capabilities?.code_execution?.supported === true &&
  m.capabilities?.pdf_input?.supported === true
);

この条件式を1箇所の関数にまとめ、モデル選定ロジックの入口にしておくと、条件の追加が1行で済みます。

ドキュメントの記述とレスポンスの例が合わないとき

公式ページ同士で、同じ事柄の書き方が揃っていない箇所があります。モデル一覧のリファレンスにある claude-opus-5 のレスポンス例では、thinking.types.enabled.supported が true です。一方、モデル概要ページには、手動の thinking.type: "enabled" と budget_tokens による拡張思考は「Claude Opus 4.6とSonnet 4.6で非推奨、以降のモデルでは受け付けない」と書かれています。

リファレンスの例は説明用のサンプルなので、どちらが実機の返り値と一致するかは、読む側では決められません。だからこそ、enabled を送る前にはサンプルや比較表でなく、自分のキーで取得した capabilities を見る意味があります。

もう1つは xhigh です。effortのページには、max に対応していても xhigh に対応しないモデルがある、と明記されています。max の対応リストにはOpus 4.6、Sonnet 4.6、Mythos Previewが入る一方、xhigh のリストにはこの3つが入っていません。effort.max.supported が true でも、xhigh の可否はその場で別に判定します。

既定値もモデルで揃っていません。effort を省略したときの既定は、Opus 5.5が medium、effortに対応するほかのモデルは high です。capabilities は「どのレベルを送れるか」を教えますが、省略時にどのレベルで動くかまでは返さないため、既定値はeffortのページの表で押さえます。

ステップ3: モデルIDとエイリアスを解決する

GET /v1/models/{model_id} は単体のモデル情報を返すエンドポイントで、モデルエイリアスをモデルIDに解決する用途にも使えます。パスパラメーターは「モデルIDまたはエイリアス」です。

curl https://api.anthropic.com/v1/models/claude-opus-5 \
    -H "anthropic-version: 2023-06-01" \
    -H "x-api-key: $ANTHROPIC_API_KEY"

4.6世代以降は、claude-opus-5 のような日付なしIDがそのまま固定されたスナップショットで、エイリアスではありません。4.6より前の世代では、claude-sonnet-4-5 のような日付なしの名前が、その時点で最新の日付付きスナップショットを指すポインタです。

エイリアスでデプロイしている場合は、起動時に GET /v1/models/{model_id} を呼び、返ってきた id をログに残しておきます。どのスナップショットで動いていたかを後から追えます。

GET /v1/models と GET /v1/models/{model_id} は、id / capabilities / created_at / display_name / max_input_tokens / max_tokens / type を持つ同じ ModelInfo 型を返します。1モデルだけ知りたいときに、一覧全体を取ってクライアント側で絞る必要はありません。

ベータ側のモデル一覧で増える項目

両エンドポイントの anthropic-beta ヘッダーは、非推奨として扱われています。リファレンスには「このメソッドからいずれ削除する。ベータ機能を使うときはベータ版のモデルAPI(SDKでは client.beta.models)を呼ぶこと」と書かれています。ヘッダーの書式そのものはClaude APIでanthropic-betaヘッダーを使う方法にまとめています。

ベータ側のレスポンス型には、通常版にない項目が2つあります。

  • allowed_fallback_models: そのモデルをプライマリにしたとき、Messages APIの fallbacks[i].model に指定できるモデルIDの配列です。空配列は、そのモデルをプライマリとする fallbacks に対応しないことを表します
  • capabilities.compaction: サーバー側compaction(トップレベルの compaction パラメーター)への対応と、受け付ける compaction.type です。現状の型には summarize があります

通常版の capabilities.context_management.compact_20260112 と、ベータ側の capabilities.compaction は別の項目です。どちらを見るかは、使うcompactionのAPIで決まります。フォールバックの組み方はサーバー側フォールバックの実装、compactionの閾値はcompactionのトークン閾値の決め方で扱っています。

フォールバック先の候補をコードで選ぶなら、次の形です。

const canBePrimary = data.filter(
  (m: any) => (m.allowed_fallback_models ?? []).length > 0
);

よくあるつまずき

capabilities はネストしたオブジェクトで、フラットな真偽値ではありません。effort は supported(effort自体への対応)と、low / medium / high / max / xhigh それぞれの CapabilitySupport を持ちます。capabilities.effort.supported だけ見て、実際には xhigh だけ非対応のモデルを見落とす例が典型です。特定のレベルを送る前に、そのレベルのキーまで降りて確認します。

context_management の個別戦略キーは null になり得ます。clear_thinking_20251015 や compact_20260112 は CapabilitySupport or null です。context_management.supported が true でも、全戦略が使えるとは限りません。

Batch APIに投げる前に batch を見ていない構成も、つまずきの元です。Batch APIにモデルを渡す構成では、capabilities.batch.supported が使えます。Claude Batch APIの使い方のように非同期で処理する構成は、キューに入ってから失敗に気づくより、投入前に弾く方が手戻りが小さくなります。

会話の途中でeffortを切り替える構成では、切り替え先のモデルを見ていないことがつまずきになります。mid-conversation effortの切り替えでオーケストレーションモードを作るのような実装では、切り替え先のモデルが対象レベルに対応しているかを、切り替えロジックの中で参照します。モデルを固定している間は表に出ず、モデルの切り替えを組み込んだときに初めて表面化します。

対応しているのに400になる組み合わせがあります。capabilities が教えるのは各機能の対応可否で、組み合わせの制約までは表しません。effortのページには、Opus 5で xhigh か max のときに thinking: {"type": "disabled"} を送ると400になる、という記述があります。Sonnet 5.5で thinking: {"type": "between_tools"} を xhigh か max と併用した場合も、同じく400です。

静的な比較表とAPIレスポンスの使い分け

くらべる

どちらを見るか

人が選ぶとき

比較表(公式ページ)

Fable 5.1 / Opus 5.5 / Sonnet 5.5 / Haiku 4.5を横並びにして、価格・コンテキストウィンドウ・退役時期まで一目で比べられます。どのモデルを使うかを決める場面向きです。

コードが判定するとき

capabilities(API)

リクエストを送る直前に、対象モデルが effort.xhigh や thinking.types.adaptive を受け付けるかを返します。判定をif文に埋め込まずに済みます。

モデル概要ページの比較表では、Haiku 4.5のコンテキストウィンドウは200K tokens、最大出力は64K tokensです。ほかの3モデルは1M tokensと128K tokensなので、max_input_tokens と max_tokens の値でモデルを使い分けるコードは、この差を前提にできます。

GET /v1/models の結果を起動時に1回キャッシュする方法は、複数のモデルを切り替えて使うアプリケーションほど効果が大きくなります。単一モデル固定の小さな実装では、起動時チェックのコストが見合わないこともあります。

起動時チェックと再取得の組み込み方

手順

起動時チェックの流れ

  1. 1

    起動処理の先頭で一覧を取得する

    limit=1000 で GET /v1/models を呼び、has_more が false であることを確かめて、結果をプロセス内メモリに置きます。

  2. 2

    リクエスト前に対応可否で弾く

    送ろうとしているeffortレベルやthinkingのtypeが、キャッシュしたモデルのcapabilitiesに入っているかを見ます。入っていなければ、APIを呼ばずにエラーを返すか、別モデルへ切り替えます。

  3. 3

    CIのデプロイ前に同じ問い合わせをする

    本番で使う全モデルが effort.high に対応しているか、といった想定をアサーションに書きます。コード側でモデルIDを固定しているチームでは、モデルが一覧から消えていないかの検知も兼ねます。

キャッシュの有効期限は、プロセスを再起動しない長時間稼働のサーバーで設計しておく価値があります。新モデルの追加は、再起動なしには反映されないためです。再取得のポーリングを組み込めば、新モデルを見逃し続けることを避けられます。1時間から1日程度という間隔は目安で、新モデルをどれだけ早く拾いたいかで決めます。

キャッシュを持たず、リクエストごとに GET /v1/models/{model_id} を呼ぶ構成も選べます。レイテンシは1リクエスト分増えますが、実装が単純で、常に最新の状態を参照できます。リクエスト数の少ない管理系のバッチ処理やCLIツールでは、こちらのほうがコードの見通しがよくなります。

まとめ

つまずきの多くは、モデルを1つに固定している間は表に出ず、切り替えを組み込んだときに現れます。モデルが固定なら、CIのアサーションだけで足ります。複数のモデルを切り替える構成になった段階で、起動時キャッシュまで入れるかを考えます。

この記事を共有:XはてブLinkedIn