OpenCode をカスタム OpenAI 互換 API に接続:Provider 設定、モデル制限、ゲートウェイのフォールバック

OpenCode カスタム プロバイダー構成チュートリアル: チャット完了と応答 API を区別し、baseURL、モデル コンテキスト、ゲートウェイ ルーティング、資格情報、およびトラブルシューティングを設定します。

OpenCode は、「AI コーディング」、「バイブ コーディング」、「オープン ソース AI」、「コーディング エージェント」に関する検索の増加にも現れています。

最も一般的なアクセス エラーは、API キーではなく、プロトコル、プロバイダー ID、モデル名の不一致です。

まず、アップストリームがどのプロトコルを使用しているかを確認します

/v1/chat/completions 通常は @ai-sdk/openai-compatible を使用します。

/v1/responses @ai-sdk/openai を使用します。

「OpenAI 互換」とは、両方のエンドポイントが実装されていることを意味するものではありません。

まず、アップストリームのドキュメントと最小限のcurlリクエストを確認してください。

1
2
curl -sS https://gateway.example.com/v1/models \
  -H "Authorization: Bearer $API_KEY"

キーをシェル履歴に直接書き込まないでください。

認証情報は設定とは別のもの

OpenCode で /connect を実行し、Other を選択します。

一意のプロバイダー ID (corp-gateway など) を入力します。

この ID は opencode.json とまったく同じである必要があります。

/connect を実行するだけでは資格情報が保存されるだけで、完全なプロバイダー構成は自動的に生成されません。

最小限の構成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "corp-gateway": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Corporate Gateway",
      "options": {
        "baseURL": "https://gateway.example.com/v1"
      },
      "models": {
        "coding-model": {
          "name": "Coding Model"
        }
      }
    }
  }
}

モデル キーは、ゲートウェイが実際に受け入れるモデル ID である必要があります。

表示名はカスタマイズできますが、実際の ID は置き換えられません。

未知のモデルにコンテキスト制約を追加する

1
2
3
4
"limit": {
  "context": 200000,
  "output": 32768
}

OpenCode はこれらの値を使用して残りのコンテキストを推定します。

サプライヤーによって通知された合計トークンを入力と出力の両方に直接入力しないでください。

出力上限を超えると、上流側でリクエストが拒否される可能性があります。

ヘッダーの境界をカスタマイズします

テナントまたはゲートウェイのルーティングには追加のヘッダーが必要になる場合があります。

静的な非機密値を構成に配置できます。

キーは環境変数を参照する必要があります。

ユーザー ID ヘッダーをエージェントに自由に変更させないでください。

ゲートウェイは、クライアントの自己報告を信頼するのではなく、信頼できる認証情報からテナントを導出する必要があります。

Vercel AI ゲートウェイのルーティング

公式の例では、orderonlyzeroDataRetention などのオプションがサポートされています。

order はサプライヤーの試行シーケンスを表します。

only 利用可能なサプライヤーを制限します。

zeroDataRetention は、データ保持要件を満たすルートをフィルタリングするために使用されます。

ロールバックでは、HTTP ステータス コードだけを確認することはできません。

認証の失敗、残高不足、およびコンテンツ ポリシーの拒否は、通常、やみくもにプロバイダーを変更して再試行するべきではありません。

承認には 3 つのリクエストを使用します

最初にプレーンテキストの Q&A を送信します。

次に、ツール呼び出しが必要なタスクを送信します。

最後に、コンテキスト制限に近い長い入力を送信します。

モデル名、リクエスト ID、最初のトークン遅延、および合計トークンを記録します。

ゲートウェイがモデル名を書き換えた場合、リクエスト値と実際のルート値の両方がログに保持される必要があります。

よくある間違い

401: 資格情報が保存されていないか、環境変数が現在のプロセスに入力されていないか、ヘッダー名が正しくありません。

404: BaseURL に多かれ少なかれ /v1 を記述しないと、間違ったプロトコルを選択する可能性があります。

400 unknown model: 構成キーが上流モデル ID と一致しません。

ツールが機能しない: アップストリームはテキスト形式とのみ互換性があり、ツール呼び出しを完全には実装していません。

コンテキストの早期オーバーフロー: limit.context は実際のモデルと一致しません。

トラブルシューティング コマンド

1
opencode auth list

資格情報エントリが存在することを確認しますが、実際のキーは出力しないでください。

次に、/models を使用してモデルが表示されるかどうかを確認します。

同じリクエストは、ゲートウェイを直接呼び出すことによって 1 回実行され、OpenCode を通じて 1 回実行されます。

直接リクエストは成功したが、OpenCode が失敗した場合は、構成と SDK プロトコルの確認に重点を置きます。

両方の側で障害が発生した場合は、最初にゲートウェイとアカウントを確認してください。

複数の環境構成

開発ゲートウェイ、テストゲートウェイ、実稼働ゲートウェイは異なるプロバイダー ID を使用します。

たとえば、corp-devcorp-prod などです。

デフォルトでは、製品 ID は個人開発構成には表示されません。

CI は短期間の認証情報を使用し、開発者のローカル トークンを再利用しません。

環境を切り替えた後、最初に読み取り専用タスクを実行して、本番への接続に誤りがないことを確認します。

安全性とコスト管理

ゲートウェイ側で各キーのバジェットとレートを設定します。

プロバイダー、モデル、倉庫、ユーザーごとに料金を記録します。

プロンプト内の認証と資格情報のマスキングをログに記録します。

エージェントがアクセスできるファイルとコマンドを制限します。

API ルーティングが成功しても、ローカル ツールの実行が安全であるとは限りません。

受け入れチェックリスト

  • チャットの完了または応答プロトコルを確認します。

  • /connect ID は構成とまったく同じです。

  • baseURL には /v1 が 1 回だけ含まれています。

  • モデル ID はゲートウェイと一致しています。

  • コンテキスト/出力制約は実際のドキュメントから得られます。

  • フォールバック ポリシーは、再試行可能なエラーと再試行不可能なエラーを区別します。

  • 認証情報は JSON と Git にありません。

  • 3 種類のリクエストはすべて、リクエスト ID と実際のルートを保存します。

プロバイダー構成文書

まず別のスクリプトを使用してゲートウェイ プロトコルを検証します

OpenCode に接続する前に、ゲートウェイの認証、モデル名、および最小限のリクエストでの応答形式を確認します。チャット完了エンドポイントの例を次に示します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$headers = @{
  Authorization = "Bearer $env:AI_GATEWAY_KEY"
  "Content-Type" = "application/json"
}
$body = @{
  model = "coding-model"
  messages = @(
    @{ role = "user"; content = "Reply with OK" }
  )
  max_tokens = 16
} | ConvertTo-Json -Depth 5
Invoke-RestMethod `
  -Uri "https://gateway.example.com/v1/chat/completions" `
  -Method Post `
  -Headers $headers `
  -Body $body

このリクエストが失敗した場合は、まずゲートウェイの問題を解決してください。プロバイダー構成と AI SDK パッケージをチェックする前に、これは成功しますが、OpenCode は失敗します。

Responses API は単に URL を置き換えることはできません

Responses API の入力、ツール定義、ストリーミング イベントは、チャット完了と同一ではありません。アップストリームが /v1/responses のみを提供する場合は、プロバイダーの npm パッケージを @ai-sdk/openai に置き換えて、ゲートウェイがプロトコルを透過的に送信するかどうかを確認します。

2 つのリクエスト本文をリバース プロキシ内の同じハンドラーに直接転送しないでください。一見単純なテキスト リクエストは成功するかもしれませんが、ツール呼び出しやマルチモーダル リクエストは実行中に破損します。

環境変数を使用して API キーを参照する

プロジェクト構成を Git に送信する前に、実際の認証情報が含まれているかどうかを検索します。

1
git grep -n -E "sk-[A-Za-z0-9]|Bearer [A-Za-z0-9]"

ローカル環境変数の名前は、CORP_GATEWAY_KEY のようにその目的を反映する必要があり、あいまいな API_KEY を再利用しないでください。 CI、PC、VPS はそれぞれ異なるキーを使用します。

ストリーミング出力を確認する

通常の応答が成功したら、より長い応答とツール呼び出しをテストします。最初のイベント、増分テキスト、終了理由、および最終的な使用法が完了しているかどうかを確認します。

プロキシ サーバーは、不要な応答バッファリングをオフにし、読み取りタイムアウトをモデル タスクのタイムアウトよりも長く設定する必要があります。そうしないと、OpenCode はモデルの実行中に切断を表示します。

コンテキストの上限が誤って書かれた場合はどうなりますか?

設定値が実際の上限よりも高い場合、OpenCode はまだスペースがあると考えますが、アップストリームはコンテキストが長すぎることを返します。構成値が低すぎる場合、クライアントは有用なコンテンツを途中で圧縮または破棄します。

固定トークン サンプルを使用して入力を段階的に増やし、ゲートウェイの実際の拒否ポイントを記録します。ユーザー ファイルだけでなく、システム プロンプト、ツール定義、予約された出力も差し引かれます。

モデルのエイリアスにはバージョン管理が必要です

ゲートウェイは多くの場合、coding-model を継続的に更新されるバックエンドにポイントします。これにより切り替えが容易になりますが、同じ構成でも異なる結果が生じます。

実稼働ワークフローでは、coding-model-2026-07 などのバージョン管理されたエイリアスを使用します。アップグレード時に新しいエイリアスを作成し、テスト ウェアハウスを実行して返した後、デフォルト ルートに切り替えます。

ロールバック中に機能の互換性を維持する

メイン モデルはツール呼び出しと長いコンテキストをサポートし、フォールバック モデルもタスクの最小限の機能を満たす必要があります。フォールバック モデルがテキストのみをサポートする場合、明示的に失敗し、ツール JSON を通常のテキストとしてエージェントに返さない必要があります。

各ルートの supports_toolssupports_vision、コンテキスト、出力、およびデータ保持ポリシーを記録します。戻ることを選択する場合は、能力でフィルターし、順番に試してください。

エージェント ログの感度解除ルール

リクエストID、テナント、モデル、ステータスコード、トークン、経過時間を保持します。承認を削除すると、プロンプト テキストはデフォルトで一元化されたログに含まれなくなります。

デバッグ中にテキストをサンプリングする必要がある場合は、専用のテスト アカウント、短い保持期間、制限されたストレージを使用してください。デバッグ後はサンプリングを終了し、一時データを削除してください。

接続を閉じて戦略を再試行する

接続タイムアウトは、限られた方法で再試行できます。認証の失敗、パラメータ エラー、およびコンテンツ ポリシーの拒否は再試行されません。 429 Retry-After と予算に基づいて待つかどうかを決定します。

書き込みツールがすでに実行中で、モデルの応答が中断された場合、タスク全体は再実行されません。繰り返しの変更を避けるために、対話を復元するか、最初に作業ツリーを確認してください。

構成変更後の 5 分間の発煙テスト

/models、短いテキストの質問と回答、読み取り専用ファイル タスク、およびツール呼び出しを順番に必要とする小さなタスクを実行します。インターフェイスに表示されたモデルがゲートウェイ ログ内の実際のモデルと一致していることを確認します。

そして、わざと存在しないモデル名を入力します。システムは、高価なデフォルト モデルにサイレントにルーティングするのではなく、明示的な構成エラーを返す必要があります。

最後に、新しいターミナルを開いて再テストし、現在のセッションの一時的な環境変数によって引き起こされる誤った成功を排除します。テスト結果は構成の差分とともに保存され、簡単にロールバックできます。

スモーク テストが失敗した場合は、以前の opencode.json およびロックされたモデル エイリアスを復元し、障害状態での構成変更の重ね合わせを続けないでください。