Claude CodeのLLMゲートウェイ互換性 — 対応製品とサブスクの関係
Claude Codeとゲートウェイ製品の互換性はAPI形式で決まります。対応形式・Claude apps gatewayとの違い・サブスクリプションとの関係をまとめます。
Claude Codeがどのゲートウェイ製品と動くかは、製品名ではなく対応するAPI形式で決まります。Anthropic Messages形式を話せるゲートウェイなら製品を問わず接続でき、Anthropicは特定の製品を推奨・保守・監査しておらず、ゲートウェイ経由でClaude以外のモデルへルーティングすることもサポートしていません。製品の選び方やサブスクリプションとの関係はClaude CodeのLLMゲートウェイにあります。この記事では、接続がうまくいかないときに効く互換性の中身(API形式・中継の条件・症状別の原因)を扱います。
Claude Codeがゲートウェイに話しかける3つのAPI形式
Claude Codeはゲートウェイに対して3つのAPI形式のどれかで話しかけます。どれを使うかはClaude Code側の環境変数で決まり、ゲートウェイがその形式を実装していれば製品は問いません。
| 形式 | 選択する変数 | 主なエンドポイント |
|---|---|---|
| Anthropic Messages | 選択する変数ANTHROPIC_BASE_URL | 主なエンドポイント/v1/messages |
| Amazon Bedrock InvokeModel | 選択する変数ANTHROPIC_BEDROCK_BASE_URL + CLAUDE_CODE_USE_BEDROCK=1 | 主なエンドポイント/model/{model}/invoke系 |
| Google Cloud's Agent Platform rawPredict | 選択する変数ANTHROPIC_VERTEX_BASE_URL + CLAUDE_CODE_USE_VERTEX=1 | 主なエンドポイント:rawPredict系 |
Microsoft FoundryとClaude Platform on AWSもAnthropic Messages形式です。ただしClaude CodeからはANTHROPIC_FOUNDRY_BASE_URL・ANTHROPIC_AWS_BASE_URLという別の変数で振り分けます。Claude Platform on AWSを前段に置くゲートウェイは、anthropic-workspace-idヘッダーの転送も必要です。
トークン数を数えるcount_tokens系のエンドポイントは省略できます。無い場合、Claude Codeは文字数ベースの概算にフォールバックします。起動時には、拒否しても問題ないベストエフォートの通信も届きます。Messages形式のゲートウェイにはHEAD /api/helloの接続ウォームアップが、Bedrock形式にはGET /inference-profiles?type=SYSTEM_DEFINEDが来ます。HTTPプロキシかクライアント証明書を設定している場合、Claude Codeはこのウォームアップを省略します。
どの形式で話すかで、Claude Codeが送る内容が変わる
同じゲートウェイでも、開発者がどの変数で接続するかによって、届くリクエストの中身が違います。3つの接続方法で、モデルIDとbeta値の扱いが分かれます。
ゲートウェイが受け取るリクエストの違い
Messages形式
Anthropic形式のモデルID(claude-opus-4-8など)で、anthropic-betaの値をフルで送ります。ゲートウェイの先がBedrockやVertexでもClaude Codeは区別できないので、両者が受け付けない項目まで届きます。
Bedrock・Vertex形式
プロバイダー形式のモデルID(Bedrockならus.anthropic.claude-opus-4-8)で、その2社が受け付ける部分集合だけを送ります。
Claude apps gatewayのサインイン
Messages形式で話しつつ、ルーティング先が何でも通るように、BedrockとVertexが受け付けるbeta値の範囲に絞って送ります。
つまずきやすいのは、Messages形式を受けてBedrockやVertexへ中継する構成です。両者のスキーマ差を橋渡しする責任がゲートウェイにあり、噛み合わないとコンテキスト管理のような新しめの機能が400で拒否されます。思考ヘッダー・effort・想定ウィンドウのずれは、症状別の環境変数で合わせられます。
上流がBedrockやVertexなら、そのプロバイダーの形式のまま公開すれば橋渡しは要りません。代わりにクライアント設定がそのプロバイダーに固定されます。
ストリーミングの中継で応答が途中で切れる理由
ゲートウェイに求められる条件のうち、運用で最初に問題になるのがストリーミングの中継です。応答を最後までためてから返すと、Claude Codeの表示が固まります。
Claude Codeは、一定時間バイトが届かないストリームを打ち切るタイマーを持っています。長い思考の間は、上流が送るSSEのpingだけが唯一のバイトになることがあります。pingを剥がす、あるいはためてから流すゲートウェイを挟むと、思考の途中で応答が切れます。
バイト監視のタイマーが走る接続は限られます。
| 接続 | バイト監視(既定300秒) | 5分のアイドルタイムアウト |
|---|---|---|
ANTHROPIC_BASE_URL・ANTHROPIC_AWS_BASE_URL | バイト監視(既定300秒)走る | 5分のアイドルタイムアウトバイト監視が担う |
| Amazon Bedrock | バイト監視(既定300秒)既定では走らない(CLAUDE_ENABLE_BYTE_WATCHDOG_BEDROCK=1で有効化) | 5分のアイドルタイムアウト効く(有効化するとバイト監視に置き換わる) |
| Google Cloud's Agent Platform・Microsoft Foundry | バイト監視(既定300秒)走らない | 5分のアイドルタイムアウト効く |
Bedrockのバイナリ形式のようにpingを一切送らない上流から変換する場合は、ゲートウェイ自身が無音の間にpingを出す必要があります。Bedrock形式でクライアントと話すときは、Content-Type: application/vnd.amazon.eventstreamをそのまま返し、SSEに変換しません。
終わり方にも条件があります。message_deltaとmessage_stopまで中継してから本文を閉じます。コンテンツブロックの開始後にそれより早く閉じると、接続が落ちたのと同じ扱いで再試行の対象になります。
無改変で転送しないと、次のリリースで壊れる
もう一つの条件は、ヘッダーとリクエストボディを許可リストにせず、そのまま転送することです。Claude Codeはリリースごとに新しいanthropic-beta値やボディフィールドを足します。見えている項目だけを通す作りだと、新機能が次のリリースで取り残されます。
壊れ方には型があります。betaヘッダーと対応するボディフィールドは、対で届く前提です。
- ヘッダーだけ剥がしてボディを通す:
400で拒否される - 両方とも欠ける: 機能が静かに無効になる
- 内容検査のためにボディを書き換える: ヘッダーを剥がしたときと同じ壊れ方をする
システムプロンプトの先頭には、バージョンと会話から作った指紋を含む短い帰属ブロックが付きます。api.anthropic.comは、system配列がそのまま届いたときだけこれを取り除きます。配列の順序を変える、先頭にブロックを足す、単一の文字列に変換するといった加工をすると、ブロックがモデルとキャッシュキーに入り込みます。
どうしても加工が要るなら、開発者側でCLAUDE_CODE_ATTRIBUTION_HEADER=0を設定してブロック自体を送らない方法があります。v2.1.181以降は、カスタムベースURL経由ならブロックが会話中は変わらないので、ボディ全体をキーにしたゲートウェイ側のキャッシュも動きます。
症状から原因をたどる
ゲートウェイを挟んだ不具合は、エラーの出方で原因が絞れます。400が返るケースは次の4つです。
| 症状 | 主な原因 | 対処 |
|---|---|---|
thinkingまたはadaptiveに触れる400 | 主な原因上流のモデルがアダプティブ推論を受け付けない | 対処上流を更新する。Opus 4.6・Sonnet 4.6ならCLAUDE_CODE_DISABLE_ADAPTIVE_THINKING=1 |
Extra inputs are not permitted(context_management) | 主な原因Messages形式を受けてBedrockへ中継している | 対処ヘッダーとボディを両方転送する |
未知のツールフィールド名を挙げる400 | 主な原因ツール系betaヘッダーを外してボディだけ通した | 対処両方転送する |
output_configに触れる400 | 主な原因BedrockやVertexの上流が受け付けない | 対処フィールドとヘッダーを対で転送する |
一方、エラーが出ないまま機能が落ちる型もあります。気づきにくいので、利用量や挙動の変化から疑うことになります。
エラーが出ずに起きる機能低下
拡張コンテキスト・インターリーブ思考
betaヘッダーだけで成立する機能です。ヘッダーを剥がすと、上流は要求自体を受け取らず、機能が使えないままになります。
プロンプトキャッシュ
cache_controlを剥がす、あるいはブロック形式のsystemを単純な文字列に変換すると、毎ターンが未キャッシュの入力として課金されます。usageのinput_tokensが大きく、キャッシュの読み取りがほぼ無い状態が目印です。トークン数の取得
count_tokensが無いと概算に落ち、/contextの表示が近似値になります。
Claude Codeは一部の拒否に自分で対処します。上流がthinkingやoutput_config.effortを拒否すると、その機能を外して再試行し、以後の会話でも送りません。一方、コンテキスト管理とツールスキーマの拒否は再試行されず、400が開発者にそのまま見えます。
再試行の判定は、上流のエラー文言との照合で行います。ゲートウェイが上流のエラーを独自の封筒で包むと、ステータスコードを保っても回復の道筋が切れます。包む場合は、capability_rejected:で始まる安定したトークンをメッセージに入れる必要があります。
thinkingの署名は、会話に結び付いています。ゲートウェイがsystem・tools・過去のmessagesを書き換えると、別の会話に結び付いているとして400になります。Claude Codeは過去のthinkingブロックを外して再試行し、以後のリクエストにも含めません。
原因が切り分けられないときの順序
転送の両方を直せない事情があるときは、順に狭めていく手があります。
400が出るときの絞り込み
- 1
エラー文言のフィールド名を読む
context_management、output_config、ツールのスキーマ項目など、拒否されたフィールドが上の表のどれに当たるかを見ます。 - 2
開発者側でプレリリース機能を止める
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1を設定します。コンテキスト管理、ベータのツール項目、output_config.format(v2.1.287以降)、output_config.task_budget、MCPツール検索が送られなくなります。ただしMCPツール検索は、v2.1.227以降なら管理設定でこの変数の下でも維持できます。維持した場合、直接接続とANTHROPIC_BASE_URL経由ではツール検索のbeta値が送られ続けますが、クラウドプロバイダーとClaude apps gatewayでは効果がありません。output_config.formatだけを外したいときは、CLAUDE_CODE_DISABLE_STRUCTURED_OUTPUTS=1(v2.1.288以降)も使えます。止まる範囲とEXPERIMENTAL_BETASとの違いは専用の解説にあります。 - 3
止まらないものを見分ける
拡張コンテキスト・インターリーブ思考・effort用のbeta値、
output_config.effortフィールド、アダプティブ推論のthinkingフィールド、サブスクリプション認証のOAuth値は残ります。開発者がANTHROPIC_BETASやCLAUDE_CODE_EXTRA_BODYで足した値も同様です。残ったものが原因なら、ゲートウェイ側の修正に戻ります。
CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 claudeこれは機能が減る代わりに通るようになる緊急回避の設定です。根本的な直し方は、ヘッダーとボディの両方を転送することです。
ゲートウェイで使える識別ヘッダー
Claude Codeは、利用量の集計に使える識別用のヘッダーを付けます。ゲートウェイは読んでも構いませんが、転送する義務はありません。
| ヘッダー | 内容 |
|---|---|
x-claude-code-session-id | 内容セッションごとの一意なID。ボディを読まずにセッション単位で集計できる |
x-claude-code-agent-id | 内容リクエストを出したサブエージェントのID。親エージェントはx-claude-code-parent-agent-id |
サブエージェントのIDは起動のたびに新しく作られます。エージェントチームのメンバーは、名前に基づく固定のIDを再接続後も使います。どちらもエージェントの識別子で、人や端末の識別子としては使えません。
v2.1.273以降は、ルーティング用のヒントヘッダー(x-claude-code-request-classなど)も付けられます。カスタムベースURLでは既定で送られません。未知のヘッダーを拒否するプロキシでリクエストが失敗するのを避けるためです。受け取るにはCLAUDE_CODE_GATEWAY_HINT_HEADERS=1を開発者に配ります。
管理端末の接続先をゲートウェイだけに固定する
管理者がゲートウェイ以外への接続を禁じたいときは、管理設定のallowedProvidersにcustomEndpointを指定します。同じファイルのenvブロックにANTHROPIC_BASE_URLを置くと、その値以外は受け付けず、Anthropicへの直接接続や開発者個人のプロキシも拒否されます。v2.1.285以降の機能です。
{
"allowedProviders": ["customEndpoint"],
"env": {
"ANTHROPIC_BASE_URL": "https://gateway.example.com"
}
}ANTHROPIC_BEDROCK_BASE_URLのようにプロバイダー専用の変数で接続するゲートウェイでは、allowedProvidersの値でどの変数を固定するかを指定します。
サブスクリプションの扱いは変数の組み合わせで決まる
ゲートウェイを挟んだとき、開発者のclaude.aiサブスクリプションがどうなるかは、設定する変数の組み合わせで決まります。
認証情報変数(ANTHROPIC_AUTH_TOKEN・ANTHROPIC_API_KEY)またはapiKeyHelperが有効な間は、サブスクリプションログインは使われません。保存済みのログインは端末に残りますが、リクエストには付きません。トークン単位の課金先は、ゲートウェイが転送する認証情報の持ち主(AnthropicのConsoleアカウント、あるいはBedrock・Vertex・Foundryのアカウント)に移ります。
ANTHROPIC_BASE_URLだけを設定し、認証情報変数を設定しない場合は、保存済みのclaude.aiログインが有効なまま残ります。その場合はサブスクリプションの利用上限と課金が適用されます。このときゲートウェイは、anthropic-betaのOAuth能力値を転送しなければなりません。剥がすと401で失敗します。
どちらの構成を選ぶかの判断材料はClaude CodeのLLMゲートウェイに、開発者が接続する手順はClaude CodeをLLMゲートウェイに接続する方法にあります。
Claude apps gatewayを選ぶときに変わること
claudeバイナリには、Anthropic純正のClaude apps gatewayが同梱されています。リリースがCLIと一緒に出るため、転送ルールを手で追従させる必要がありません。他社製品では、ヘッダーとボディを許可リストにせず無改変で転送する作りになっているかが、リリースごとの追従に効きます。
互換性の面で押さえておく制約は、サインインが社内IdPでのブラウザSSOだけという点です。サービストークンの方式がないので、承認する開発者がその場にいないCIパイプラインは認証できません。そうした自動化は、プロバイダーへ直接つなぐ構成にします。
また、直接接続と全く同じ挙動ではありません。ゲートウェイセッションでの主な違いは次のとおりです。
| 機能 | 状態 | 理由 |
|---|---|---|
| サーバーサイドのWeb検索 | 状態使えない | 理由どのプロバイダーに届いているか分からず、対応を検証できない |
| Remote Control | 状態使えない | 理由ゲートウェイの名前を挙げたエラーが出る |
/design-sync・/design-login | 状態使えない | 理由claude.aiに接続しないため、コマンド自体が表示されない |
| 1時間のキャッシュTTL | 状態使えない | 理由全プロバイダーが1時間TTLに対応するとは限らず、5分TTLで動く |
| グローバルキャッシュスコープなどの最適化 | 状態使えない | 理由ファーストパーティ専用の最適化として有効化されない |
| 標準のプロンプトキャッシュ | 状態使える | 理由cache_controlを全上流に転送する |
| Auto mode | 状態使える | 理由サードパーティプロバイダーで使えるモデルに限る |
まとめ
互換性はAPI形式で決まり、実際に壊れるのはストリーミングの中継、ヘッダーとボディの片落ち、形式の食い違いの3か所です。症状が400ならフィールド名から表を引き、エラーが出ないのに機能が落ちているなら、cache_controlやanthropic-betaが剥がれていないかを疑います。