組み込みの anthropic プロバイダーは shunt のデフォルトの送信先です。一致するルートを持たないモデルは
すべて、そのまま api.anthropic.com へ転送されます(server.default_provider で変更可能)。これは
kind = "anthropic" のプロバイダーです — 上流がすでに Anthropic Messages API を話すため、shunt は
リクエストを変換せずにパススルーし、どの認証情報を上流へ送るかだけを決めます。
リクエストのフィールドのうち、ひとつだけ例外があります。shunt が他のプロバイダー向けに生成した
signature を持つ thinking ブロックは、リクエストを転送する前に取り除かれます(Responses・
Gemini・Cursor の各経路がそれぞれ生成します — ブロックとして成立させるためにこのフィールドが
必要だからです)。それによって中身が空になった assistant ターンも一緒に取り除かれます。Anthropic
はこのフィールドを復号するため、自身が発行していない値は拒否され、そのまま転送するとリクエストが
失敗します。Anthropic が発行した signature は shunt からは不透明なので決して触れません。この除去は
会話履歴を参照しないため、マッピング済みプロバイダーを使ったセッションに限られるわけではありません
— signature がまったく無い thinking ブロックも除去されます。shunt の Responses 経路は上流から
signature を受け取らなかった場合にそうしたブロックを生成し、Anthropic は検証できない signature を
持つ thinking ブロックをいずれにせよ拒否するからです。
サードパーティの Anthropic 系プロバイダー — api.anthropic.com ではなく claude_oauth プールでも
ない kind = "anthropic" の上流(MiniMax、Kimi、Zhipu など)— は、Anthropic が発行していない
signature を thinking ブロックに付けることがあります。shunt はストリーミングかどうかにかかわらず、クライアントへ返す応答で
その signature をプロバイダーの base_url(末尾の / を除く)のダイジェストを持つ独自の envelope で包みます。URL 自体は含まれないため、URL とそこに含まれる認証情報はクライアントに公開されません。ただしダイジェストはソルトのない固定値なので、推測の確認に使えます。よく知られたエンドポイントや、そこに埋め込まれた弱い認証情報のように base_url 全体を推測できるなら、その推測が正しいかをダイジェストと照合して確かめられます。後のターンが同じ
base_url のプロバイダーに戻ると、shunt は envelope を解いて元の signature をバイト単位でそのまま
転送するため、そのプロバイダーの extended thinking の継続は引き続き機能します。Anthropic を含む
それ以外の宛先に送られた場合、envelope は shunt が生成した値として扱われ、上記のとおりブロックが
取り除かれます。そのため、サードパーティの Anthropic 系プロバイダーと Anthropic を切り替えると、
リクエストが失敗する代わりにそのプロバイダーの thinking ブロックが取り除かれ、同じプロバイダーに
戻ると復元されます。api.anthropic.com と claude_oauth プールの応答が包まれることはありません。
| 認証モード | 認証情報 | ユースケース |
|---|---|---|
passthrough(デフォルト) |
呼び出し元自身の x-api-key / Authorization |
透過プロキシ — 各クライアントが自分のキーまたは OAuth トークンを持ち込む |
api_key |
環境変数から取るサーバー側のキー | 運用者所有の API キー 1 本で、すべてのリクエストのキーを差し替える |
claude_oauth |
shunt が管理する 1 つ以上の Claude サブスクリプションアカウント | プーリングとクォータを考慮したローテーションを伴い、Claude サブスクリプションを消費する |
クイックスタート
コーディングエージェントにセットアップを任せることもできます — shunt add は組み込みのセットアップ
ブループリントを出力します(オフラインかつ読み取り専用で、設定を編集するのはエージェントです。この
コマンド自体は編集しません)。
shunt add upstream anthropic --print | claudeまたは、以下の手順に沿って手動で設定してください。
upstream を設定する
anthropic は組み込みです — 設定が一切なくても、shunt はルーティングされないモデルを passthrough として
すでにここへ転送します。(順序付きフェイルオーバーのため、あるいは認証を変えるために)明示的に宣言するには、
kind = "anthropic"、base_url = "https://api.anthropic.com"、auth = "passthrough" を提供するプリセットを
使います。
[[upstreams]]
name = "anthropic"
provider = "anthropic"明示的に指定したフィールドはプリセットのデフォルトを上書きします。従来の [providers.anthropic] テーブル
形式も引き続きサポートされます — ただし [[upstreams]] と [providers.*] を 1 つのファイルで混在させない
でください。
パススルー(デフォルト)
ほかに設定するものはありません。shunt はクライアント自身の x-api-key または Authorization ヘッダーを
転送します。サーバー側のシークレットを設定ファイルに置く必要はありません。クライアントが何を送るべきかは
Claude Code を接続するで扱っています。
サーバー側の API キー
呼び出し元がキーを持ち込むのを信頼する代わりに、運用者所有のキーを注入します。
[[upstreams]]
name = "anthropic"
provider = "anthropic"
auth = { mode = "api_key", env = "ANTHROPIC_API_KEY", header = "x_api_key" }サーバー側の認証情報を注入する場合は、ループバックを越えて公開する前に
[server.auth] でゲートウェイをゲートしてください。
Claude サブスクリプションアカウント(claude_oauth)
リフレッシュ可能な shunt 管理アカウントを一度作成し、upstream をそれにスコープします。
shunt login claude --name primary --mode oauth[[upstreams]]
name = "anthropic"
provider = "anthropic"
auth = { mode = "claude_oauth", account = "primary" }shunt login claude には 3 つのモードがあります。--mode oauth は shunt 自身のリフレッシュ可能な OAuth
フローを実行し(推奨)、--mode import は現在の Claude Code のログインをコピーし、--mode setup-token は
1 年間有効な推論専用トークンを作成します。account(および accounts)を省略すると shunt 管理下の
アカウントストア全体をスキャンします — ストアに複数のアカウントがあれば、セッションスティッキネスと
クォータを考慮したローテーションを備えた負荷分散プールになります。明示的なアカウントエントリ、
アカウント単位のしきい値、[server.pool] のチューニング、フェイルオーバーを含む完全なプーリングの挙動は
Anthropic マルチアカウントに記載されています。
モデルとルーティング
デフォルトプロバイダーであるため、anthropic にルートは不要です — ほかへマッピングしなかったものが
すべてここへ来ます。順序付きフェイルオーバーチェーンの中でモデルを明示的に固定するには:
[[models]]
id = "claude-sonnet-5"
display_name = "Claude Sonnet 5"
[models.upstream_model]
anthropic = "claude-sonnet-5"マップのキーはプリセット id ではなく [[upstreams]].name です。auto_include_builtin_models = true
(デフォルト)の場合、GET /v1/models はまず server.default_provider が Anthropic 種別のときにそこから
ライブのモデル一覧を取得しようとし、それ以外では shunt の組み込み Claude カタログスナップショットへ
フォールバックします — Model Discovery を参照。
オートモードの分類器
Claude Code をオートモードで動かすと、ワークスペースの外に出る操作やネットワークに触れる操作は
すべてパーミッション分類器を通ります — 保留中の操作について安全性の判定をモデルに問う、
独自のシステムプロンプトを持つ別建ての Messages リクエストです。これは、サブスクリプション
OAuth の認証情報に対して api.anthropic.com が探す Claude Code の identity ブロックを欠いており、
CLAUDE_CODE_ATTRIBUTION_HEADER=0 のときの mod の $.model.complete のようなサイドクエリも同様です。
shunt はオートモードの分類器と、受け入れられるマーカーを持たないすべての Claude Code リクエスト
(x-claude-code-session-id、claude-cli/ の user agent、または x-app: cli で識別)に identity を復元します。
この復元は送信する bearer がサブスクリプション OAuth トークンのときだけ適用され、アップストリームが
確認しない count_tokens には適用されず、空の x-claude-code-session-id は Claude Code とみなしません。
他のクライアントと API キーのリクエストにはこの復元を適用しません。この復元が防ぐ失敗は
429 のトラブルシューティング項目で説明しています。
分類器はデフォルトではセッションのモデルを使いません。Claude Code 2.1.226 で計測したところ、
サーバーからモデルが渡されていればそれを、なければ Sonnet ティアのエイリアスを、それも
なければセッション自身のモデルを使います — ANTHROPIC_DEFAULT_SONNET_MODEL が分類器まで
動かすのはこのためで、実際にワイヤー上で確認しています。これは配布されたクライアントから読み
取った内容なので、契約ではなく計測したバージョンについての説明です。
classifier_model を設定すると、セッション自身のターンが動くモデルはそのままに、ゲートウェイ側で
分類器リクエストだけを特定のモデルに固定できます。
[providers.anthropic]
kind = "anthropic"
base_url = "https://api.anthropic.com"
classifier_model = "claude-sonnet-5"このキーは kind = "anthropic" のプロバイダーでのみ受け付けられ、そのプロバイダー内でのモデルの
差し替えであって、別のプロバイダーへのルートではありません。分類器リクエストは stop_sequences
に依存します。shunt の Responses 変換がこのフィールドを落としていた頃は、Sonnet エイリアス経由で
Codex の上流に向けたところ、分類器は第 1 段階をリトライし、パーミッション確認のたびに 5〜7 秒余計に
かかりました。現在は shunt が Responses 経路で stop_sequences をエミュレート
するため、その失敗はもう当てはまりませんが、このキーは引き続きプロバイダー内での差し替えです。
キーを設定しない場合(デフォルト)は、クライアントが要求したモデルのまま動きます。
ゲートウェイログインのデプロイメントでは、代わりにマネージド設定で エイリアスをクライアントへ配信することもできます。
[server.gateway.policies.cli.env]
ANTHROPIC_DEFAULT_SONNET_MODEL = "claude-sonnet-5"同じように分類器を動かせますが、分類器だけでなくセッション全体で sonnet が指す先が変わります
— さらに availableModels を設定している場合は、その id がリストにも入っている必要があります。
検証
shunt check # -> config ok
shunt run
curl -sS http://127.0.0.1:3001/v1/models続いて最小のリクエストを 1 つ送ります(passthrough では自分の認証情報を含め、claude_oauth では
省きます)。
curl -sS http://127.0.0.1:3001/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H 'anthropic-version: 2023-06-01' \
-H 'content-type: application/json' \
-d '{"model":"claude-sonnet-5","max_tokens":16,"messages":[{"role":"user","content":"Reply with OK."}]}'関連
- Anthropic マルチアカウント — アカウントプール、クォータを考慮した選択、
[server.pool] - 管理とリモートプロビジョニング — ブラウザからアカウントをプロビジョニングする
- Configuration Reference — すべてのアカウントキー