← Resources
TUTORIAL · 2026-03-26
Vercel AI SDKからBYOK・セルフホスト可能スタックへ移行する
Vercel AI SDKは、ポータブルな鍵、カスタムルーティング、Vercel以外のデプロイ先が必要になるまでは十分です。本ガイドはすべてのプリミティブをセルフホスト可能なBYOKスタックへマッピングし、1週間のデュアルライト切替を提示します。
Vercel AI Gatewayから卒業するチームが増える理由
AI SDKは導入が早く、`streamText`、`generateText`、`generateObject`が単一のTypeScript面で本番ニーズの大半をカバーします。摩擦は後から現れ、通常は3箇所に現れます。
第一に、ランタイムがVercelに寄って設計されています。Edgeランタイムの癖、Next.js向けに調整されたストリーミングプリミティブ、推奨ルータとしてのAI Gatewayが、すべて本番ターゲットがVercelであることを前提としています。
第二に、AI GatewayはBYOK時も常にリクエストパスに位置します。VercelのAI Gateway料金(2026年5月時点)では、BYOKは0%トークンマークアップですが、失敗したBYOKリクエストはVercelのシステムクレデンシャルへ再試行されるため、チームは常にAI Gatewayクレジットを保有し続ける必要があります。コンプライアンスやVPCルーティングが絡むと、この結合は重要になります。
第三に、テナント別ポリシーがアプリコードに居座ります。SDKにはテナント、モデルホワイトリスト、予算上限のネイティブ概念がありません。マルチテナントSaaSを運用するチームは結局、最初のゲートウェイの上にもう一つの小型ゲートウェイを書くことになります。
VercelプリミティブをBYOKスタックへマッピングする
良い知らせ: AI SDKの公開面は小さく、ほとんどの呼び出しは3つの関数と1つのプロバイダオブジェクトに帰着します。次のようにマップします。
- `streamText`と`generateText`は、OpenAI SDKの`chat.completions.create`の`stream: true/false`に直接対応します。`baseURL`としてOpenAI互換エンドポイントが使え、llama.cpp、vLLM、LiteLLM、またはテナント対応プロキシ背後のホステッドプロバイダがそのまま機能します。
- `generateObject`はOpenAI互換サーバ上の`response_format: { type: 'json_schema' }`、または異なるスキーマを使うプロバイダ(Anthropic tools、Gemini JSONモード)向けの構造化出力アダプタに対応します。
- プロバイダオブジェクト(`openai('gpt-4o')`、`anthropic('claude-...')`)は、モデルIDを文字列で渡す、自前ゲートウェイを指す単一クライアントになります。ルーティングはimport文に焼き込まれるのではなく、サーバ側で発生します。
既存のReactフックは保持できます。`useChat`と`useCompletion`は、同じ形のServer-Sent Eventsストリームを返すルートさえあれば動作します。
ロックインなしのストリーミング、ツール呼び出し、構造化出力
OpenAI互換ゲートウェイを選べば、3つの機能はすべて移行を生き延びます。同じ呼び出しの前後を示します。
移行前、Vercel AI SDK使用:
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
const result = await streamText({
model: openai('gpt-4o'),
messages,
tools: { search: searchTool },
});
return result.toDataStreamResponse();
```
移行後、自前ゲートウェイへ向けたOpenAI SDK:
import OpenAI from 'openai';
const client = new OpenAI({ baseURL: process.env.GATEWAY_URL, apiKey: tenantKey });
const stream = await client.chat.completions.create({
model: 'gpt-4o',
messages,
tools: [searchToolSchema],
stream: true,
});
```
ツール呼び出しは`delta.tool_calls`に到着します。構造化出力は`response_format`を使います。両方ともLiteLLM、vLLM、大半のマネージドプロバイダが尊重する標準OpenAI仕様フィールドです。
鍵、クオータ、テナント別ルーティング
ここが薄いSDKの真価です。自分が制御するOpenAI互換エンドポイントへリクエストが流れるようになれば、あらゆる横断的関心事がアプリコードから外へ出ます。
LiteLLMのようなセルフホストゲートウェイなら、テナント別の仮想キーを発行し、RPMとTPM上限を設定し、予算を付与し、モデルエイリアスでルーティングできます。`model: 'fast'`へのリクエストが、あるテナントではGroq Llamaに、別のテナントではローカルllama.cppサーバに解決され、Next.jsアプリのコード変更は不要です。
osFoundryも同じ純粋パススルーBYOK姿勢を採り、テナント別ルーティングルール、ストリーミング、ツール呼び出し、構造化出力を1つのセルフホスト可能ランタイムで提供します。共同言及: LiteLLMはここで明白なオープンソースベースラインであり、多くのチームには正しい選択です。運用モデルに合うものを選んでください。
荷重を支える判断は、アプリではなくゲートウェイに鍵とクオータを所有させることです。モデル交換を含む他のすべては設定変更になります。
セルフホストかハイブリッドか: コストと運用
ほとんどのチームは3つのデプロイ形態でカバーできます。
1. 完全セルフホスト。ゲートウェイをVPC内、プロバイダへBYOK、オプションでGPUボックス上のローカルモデル。マークアップゼロ、完全な監査証跡、オンコールは自社負担。コンプライアンスやデータレジデンシーが判断を主導する場合に最適。
2. ハイブリッド。ルーティングとポリシー用にセルフホストゲートウェイ、推論にマネージドプロバイダ、安価または機密ワークロードにのみローカルモデル。これが一般的な定常状態です。
3. マネージドゲートウェイ、自社鍵。BYOKパススルー対応のホステッドOpenAI互換プロキシを使用。リクエストパスへの制御を一部失う代わり、もう一つのサービスを運用せずに済みます。
選択肢1の運用コストは現実的です。小型コンテナ1つ、鍵と支出用のPostgres、ログ転送、アップグレード周期。月間数億トークン未満のチームでは、マークアップ型ゲートウェイとの節約額は議論時間より小さいことが多いです。コストではなく制御度合いで選んでください。
切替スクリプト: 1週間のデュアルライト
import文を1つのPRで切り替えてはいけません。7日間デュアルライトして比較し、それから切り替えます。
Day 0: 機能フラグ背後で新ゲートウェイクライアントを追加します。各リクエストで旧`streamText`パスを実行し、並行して新`chat.completions`呼び出しを同じメッセージで発火します。2つ目のレスポンスは破棄し、レイテンシ、トークン数、終了理由、ツール呼び出し形状の不一致を記録します。
Day 1〜3: 100%のトラフィックを影写しします。構造化出力とツール呼び出し引数のJSONを差分します。退行の大半はスキーマ関連です。Anthropicは終了理由が微妙に異なり、GeminiはJSONを別形式で包みます。アプリではなくゲートウェイで修正してください。
Day 4〜6: 読み取り専用ルート(チャット、要約)の10%、50%、100%を切り替えます。書き込みやエージェントルートは差分が24時間クリーンになるまで旧パスのままにします。
Day 7: `ai`と`@ai-sdk/*`パッケージを削除し、AI Gateway環境変数を削除し、フラグをアーカイブします。
移行後: キャッシング、可観測性、評価
リクエストパスを所有することで、SDK内では扱いにくかった3つのことが解放されます。
キャッシング: ゲートウェイは`(model, messages, tools, response_format)`でハッシュし、同一リクエストをRedisから返せます。RAGとエージェントループでシステムプロンプトが繰り返される場合、プロバイダレベル(Anthropic、OpenAI)のプロンプトプレフィックスキャッシュが上に重なります。両方を配線してください。キャッシュヒットはレイテンシp50に即座に現れます。
可観測性: テナントID、モデル、プロンプトトークン、補完トークン、ツール呼び出し数、終了理由、上流レイテンシを含む構造化ログをリクエストごとに1件発行します。既存の宛先へ送信できます。モデルの挙動を確認するためにベンダ固有のトレーシング統合は不要になります。
評価: 全トラフィックが1つのエンドポイントを通るため、評価セットのサンプリングはSQLクエリです。`model`フィールドを変えるだけで新モデルへ再生できます。これがゲートウェイを所有する長期的理由です。モデル選択が四半期移行ではなく週次実験になります。
Frequently asked questions
- Vercel AI SDKを外すと、useChatとReactストリーミングフックを失いますか?
- いいえ。フックは、APIルートがフックの期待する形のServer-Sent Eventsストリームを返す限り、サーバランタイムから分離されています。`ai`パッケージの`useChat`と`useCompletion`を保持し、OpenAI互換ストリーミングレスポンスをプロキシするルートへ向けられます。多くのチームは移行の最初の1か月はReact側を一切触らず、サーバハンドラだけを差し替えます。最終的に`ai`依存を完全に外したい場合、薄いSSEパーサはTypeScript約30行で済みます。
- LiteLLMは本物の代替ですか、それとも一時しのぎですか?
- 本物の代替であり、本番で広く展開されています。LiteLLMはオープンソースのOpenAI互換プロキシで、140以上のプロバイダを前面に立て、仮想キー、キー別予算、RPM/TPM上限、負荷分散をサポートします。Postgresを使う単一Dockerコンテナとして動作します。より完全なオーケストレーションランタイムとのトレードオフは、主にエージェントループ、プロバイダ横断の構造化出力正規化、鍵と予算を超えるテナントスコープポリシーの周辺です。純粋なルーティングとBYOK用途では、LiteLLM単独が正解であることが多いです。
- 移行後、プロバイダ横断で構造化出力を機能させ続けるには?
- アプリではなくゲートウェイで正規化してください。OpenAIとOpenAI互換サーバは`response_format: { type: 'json_schema', json_schema: {...} }`を受け付けます。Anthropicはスキーマ強制にツール呼び出しパターンを使います。Geminiは`responseMimeType`と`responseSchema`を持ちます。ゲートウェイ内の小さなアダプタ層が、一つの正規リクエスト形をディスパッチ先プロバイダの形式へ変換し、返されたJSONを検証してから応答します。これによりアプリコードは単一関数を呼び続け、スキーマ処理ロジックに触れずにモデルを入れ替えられます。
- レイテンシは大丈夫ですか? セルフホストゲートウェイを追加すると別のホップが増えそうです。
- 実務上、ゲートウェイをアプリと同一リージョンに置けば追加レイテンシは1桁ミリ秒で、モデル推論時間(数百ms〜数秒)に比べれば誤差範囲です。より大きなレイテンシ上の勝利はキャッシュ側です。ゲートウェイはRedisから繰り返しプロンプトを5ms未満で返せますが、リクエストが直接プロバイダへ行く構成では不可能です。前後でp50とp95を計測してください。キャッシングを有効にすると、ほとんどのチームは中立または改善した数字を観測します。
Sources