Claude API modelsのcapabilitiesを判定する方法
GET /v1/modelsのcapabilitiesオブジェクトから、effort・thinking・context_managementの対応状況をプログラムで判定する実装パターン。
capabilitiesオブジェクトで何が分かるか
Claude APIの GET /v1/models は、利用可能なモデルの一覧だけでなく、各モデルが effort=xhigh に対応しているか、思考モード(thinking)のどの type を受け付けるか、コンテキスト管理のどの戦略が使えるかまで、capabilities オブジェクトとして返します。モデル一覧ページの比較表を目でコピーする代わりに、この記事ではAPIレスポンスから機能対応を判定する実装を組みます。
前提として必要なのはAPIキーだけです。エンドポイントはGETのみで、リクエストボディは不要です。SDKを使わず生のHTTPリクエストで完結するので、CI上の起動前チェックやシェルスクリプトからも呼び出せます。
このエンドポイントが解決する問題は、モデルの世代交代のたびに発生します。新しいモデルが追加されるとeffortの対応レベルやthinkingのtype対応が変わることがあり、それをコード側のif文やswitch文にハードコードしていると、モデル追加のたびにデプロイが必要になります。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まで指定できます。1回のリクエストで全モデルを取り切りたい場合は limit=1000 を指定すれば、大半の運用ではページングなしで済みます。
各モデルの 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 はモデルによって null になり得るため、実装では未対応モデルとしてフォールバックする分岐が必要です。ドキュメントの型定義は ModelCapabilities or null と明記されており、capabilities.effort.xhigh.supported のようにネストしたプロパティへ無条件でアクセスするコードは、capabilities が 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": 1000000,
"max_tokens": 128000,
"type": "model"
}created_at はRFC 3339形式の日時文字列で、モデルの公開日時を表します。公開日が不明な古いモデルではエポック値(1970-01-01T00:00:00Z)が入ることがあるため、created_at を新しさの判定にそのまま使う実装では、エポック値を「最古のモデル」として扱ってしまわないようフィルタが要ります。実務では created_at を並べ替えに使うより、レスポンス順(新しいモデルが先頭)をそのまま使う方が確実です。
ステップ2: capabilitiesから対応表を作る
一覧取得したレスポンスから、effort=xhigh に対応するモデルIDだけを抽出する処理は次のようになります。
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戦略が使えるモデルの一覧が作れます。ハードコードした「このモデルはxhighに対応している」というif文の羅列を、APIレスポンス駆動の判定に置き換えられるのがこのエンドポイントの本質的な価値です。
複数の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
);「xhighのeffortでコード実行とPDF入力を両方使えるモデルだけを候補にする」といった複合条件は、実装のたびに手で書き直す代わりに、このフィルタ関数を1箇所に置いてモデル選定ロジックの入口にすれば済みます。
ステップ3: モデルIDとエイリアスを解決する
GET /v1/models/{model_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より前の世代では、エイリアスは日付付きのスナップショットIDへのポインタとして機能し、レスポンスの 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 も受け付けます。将来的にcapabilities判定ロジック自体をベータ機能で拡張する場合の書式はClaude APIでanthropic-betaヘッダーを使う方法を参照してください。
よくあるつまずき
capabilities がフラットな真偽値ではなくネストしたオブジェクトである点を見落とす。 effort フィールドは単純な boolean ではなく、supported(effort自体への対応)と low / medium / high / max / xhigh それぞれの CapabilitySupport オブジェクトを持つ入れ子構造です。「effortに対応しているか」を見るつもりで capabilities.effort.supported だけ確認し、実際には xhigh だけ非対応というモデルを見落とすケースが起きます。特定のeffortレベルを送る前は、必ず該当レベルのキーまで降りて確認します。
context_management の個別戦略キーが CapabilitySupport or null である点。 clear_thinking_20251015 や compact_20260112 のような個別戦略は、モデルが context_management 自体に対応していても、特定の戦略キーが存在しない(null)ことがあります。context_management.supported が true だからといって、全戦略が使えるとは限りません。
Batch API経由のリクエストでは反映のタイミングが変わる。 Claude Batch APIの使い方のように非同期でリクエストを処理する構成では、送信時点の capabilities と実際の処理時点でのモデル対応状況がずれる可能性はゼロではありません。長時間キューに滞留するバッチジョブでは、送信直前に一覧を再取得してから投入する方が安全です。
エフォート切り替えを動的に行う構成での参照タイミング。 mid-conversation effortの切り替えでオーケストレーションモードを作るのように会話の途中でeffortを変える実装では、切り替え先のモデルが対象effortレベルに対応しているかを、切り替えロジックの中で capabilities.effort を都度参照するのが安全です。モデルを固定して運用している間は問題にならず、モデルの切り替えを実装に組み込んだタイミングで初めて表面化する不具合です。
静的な比較表とAPIレスポンス、どちらを参照すべきか
モデル一覧ページの比較表(Fable 5.1 / Opus 5 / Sonnet 5 / Haiku 4.5を横並びにした表)は人間が一読するには最適ですが、実装のソースオブトゥルースとしては向きません。新しいモデルが追加されたりeffortレベルの対応が変わったりしたとき、ドキュメントページの更新とAPIレスポンスの更新に時差が生じる可能性は常にあります。effort=xhigh を送る前に capabilities.effort.xhigh.supported を確認するコードを書いておけば、対応表を目視で追いかけて実装を書き換える運用から抜けられます。
ここで効くのは、リクエスト前の事前チェックだけではありません。未対応のeffortレベルを送ってしまった場合の400エラーをリトライループで握りつぶすより、GET /v1/models の結果をアプリケーション起動時に1回キャッシュし、非対応の組み合わせをリクエスト前に弾く方が、レイテンシとエラー処理の複雑さの両方を削れます。マルチモデル対応のアプリケーションを運用しているチームほど、このキャッシュの効果は大きくなります。単一モデル固定の小規模な実装では、起動時チェックのコストが見合わないこともあります。
デプロイパイプラインへの組み込み方
起動時チェックとして組み込む場合、GET /v1/models の呼び出しをアプリケーション起動処理の先頭に置き、結果をプロセス内メモリにキャッシュする構成が扱いやすい形です。デプロイのたびにモデルの対応状況が変わっていないか確認したいなら、CIのデプロイ前ステップで同じエンドポイントを叩き、想定するcapability(たとえば「本番で使う全モデルが effort.high に対応しているか」)をアサーションとして書いておく方法もあります。モデルIDをコード側で固定運用しているチームでは、このアサーションが「デプロイ対象のモデルが廃止されていないか」の検知も兼ねます。
キャッシュの有効期限も設計しておく価値があります。capabilities はモデルのライフサイクルに紐づく情報なので、頻繁に変わるものではありません。とはいえ新モデルの追加やcapabilityの変更はドキュメントの更新と同時に起きるとは限らないため、プロセスを再起動しない長時間稼働のサーバーでは、1時間から1日程度の間隔で再取得するポーリングを組み込んでおくと、キャッシュが古いまま新モデルを見逃す事態を避けられます。ページネーションの limit=1000 を使えば、この定期ポーリングも1リクエストで完結します。
キャッシュを持たずリクエストごとに GET /v1/models/{model_id} を直接呼ぶ構成も選択肢に入ります。レイテンシは1リクエスト分増えますが、実装がシンプルで、モデルの世代交代や廃止に対して常に最新の状態を参照できます。リクエスト数が少ない管理系のバッチ処理やCLIツールでは、キャッシュを持たないこちらの構成のほうがコードの見通しがよくなることもあります。トラフィック量とレイテンシ要件を見て、どちらの構成にするかを最初に決めておくと、後から混在した実装が積み上がるのを防げます。
まとめ
GET /v1/models の capabilities オブジェクトは、effort の対応レベル・thinking のtype・context_management の戦略まで、モデルごとの対応状況をプログラムから直接読み取れる情報源です。capabilities が null になり得る前提でコードを書き、GET /v1/models/{model_id} でエイリアス解決とログ記録を組み合わせれば、モデルの世代交代のたびにハードコードした対応表を書き換える作業を減らせます。マルチモデル対応の実装では、起動時に一覧を取得してキャッシュし、リクエスト前に対応可否をチェックする構成が現実的な落としどころです。