Amazon Bedrockは、OpenAI互換のResponses APIとChat Completions APIを提供している。OpenAI SDKのBase URLや認証を変更し、Bedrock上の対応モデルを呼び出せる構成が可能になった。
これは移植コストを下げるが、「同じAPI形式なら同じ挙動」という意味ではない。モデル、Tool、状態、ストリーミング、認証、リージョン、Usage、エラー、データ処理条件にはProvider差分が残る。
何が変わったか
BedrockのResponses APIは、会話状態、Tool Use、ストリーミング、非同期処理などをOpenAI Responses APIに近い形式で扱う。既存のOpenAI SDKや開発者の知識を再利用しやすい。
従来はBedrock固有SDKやConverse APIなどへコードを適応する必要があった。互換エンドポイントにより、共通クライアント層を作りやすくなった。
変更前後の差
| 項目 | Bedrock固有API | OpenAI互換Responses API |
|---|---|---|
| SDK | AWS SDK中心 | OpenAI SDKを利用可能 |
| リクエスト形式 | Bedrock仕様 | Responses形式に近い |
| 認証 | AWS認証 | Bedrock用認証方式を設定 |
| モデルID | Bedrock ID | Bedrock側の対応ID |
| 移植 | Adapterが必要 | 表面的差分を縮小 |
| 意味差 | 明示的 | 隠れやすい |
互換性には、JSONやSDKが近い構文互換と、同じ入力で同じ機能・品質・エラー・状態を得られる意味互換がある。本番で重要なのは後者である。
誰に影響するか
- OpenAI SDKを標準クライアントとしている
- AWS IAMやVPC、Region統制を使いたい
- 複数モデルProviderを切り替えたい
- 調達・可用性の理由で単一Provider依存を減らしたい
- OpenAI APIとBedrockを同じアプリで使う
- 既存Responses APIアプリをAWSへ移行したい
- 災害時の代替経路を設計したい
単一モデルの簡単なテキスト生成は移しやすいが、高度なToolや状態管理ほど差が増える。
必要な対応
Provider Contractを作る。アプリが必要とする機能を抽象名で定義し、各Providerでの対応可否と差分を記録する。
capabilities:
streaming: required
stateful_conversation: required
function_calling: required
parallel_tool_calls: optional
structured_output: required
background_jobs: optional
image_input: required
moderation: external
「APIが200を返す」だけで互換と判定しない。
実装・移行手順
1. クライアント層を分離する
アプリケーションから直接SDKを呼ばず、Provider Adapterを介す。Provider名、モデル、Endpoint、認証、Timeout、Retryを設定で切り替える。
2. 認証を分ける
OpenAI APIキーとAWS認証を同じSecret形式へ押し込めない。AWS側はIAM、短期Credential、Region、Roleを使い、権限を最小化する。
3. モデル能力をマッピングする
モデル名の置換表だけでなく、Context Window、Tool Use、画像、JSON、ストリーム、価格、地域、データ処理条件を記録する。
4. 状態管理を明示する
Conversation IDやPrevious Response参照など、Providerが保持する状態とアプリ側状態を区別する。切替可能性を高めるなら、重要な会話状態を自社側へも保存する。
5. Tool schemaを検証する
同じJSON Schemaでも、引数生成、並列実行、Tool結果の渡し方、停止理由が異なる可能性がある。ToolごとのGolden Testを作る。
6. エラーを正規化する
認証、Quota、Rate Limit、Safety、Validation、Timeout、Provider障害を共通エラーへ変換する。ただし生のProvider Request IDと詳細は保持する。
7. 影運用する
同じ入力を両Providerへ送り、回答だけでなくTool、Usage、レイテンシ、費用、安全性を比較する。機密データの二重送信が許可されるか確認する。
失敗しやすい点
- Base URL変更だけで移行完了とする
- 出力テキストだけを比較する
- RetryをProvider差分なしで共通化する
- Provider固有機能を共通層へ漏らす
- Region、保持、契約などデータ統制を同一視する
Providerごとに再試行可能エラーと課金・重複実行の意味が違う。書き込みToolを含む場合は冪等性が必要である。
評価方法
- Golden Promptの成功率
- JSON Schema適合率
- Tool選択・引数一致率
- ストリームイベント順序の互換率
- 会話状態継続率
- P50・P95レイテンシ
- タスク当たり費用
- Rate Limit時の回復時間
- Provider切替に必要な時間
- エラー分類の正規化率
- 品質評価の差
- 安全・データ要件の適合率
切替試験は計画停止だけでなく、片方の5xx、Quota枯渇、認証失効、Region障害を含める。
ロールバック
Bedrock経路で問題が起きた場合は、Provider RoutingをOpenAI経路へ戻す。書き込みToolや外部副作用がある処理では、同じRequestを再送する前に完了状況を確認する。
- 新規トラフィックを安定Providerへ切り替える
- 進行中ResponseとTool Callを追跡する
- 冪等性キーで重複を防ぐ
- 会話状態を変換または新規開始する
- Provider固有エラーとRequest IDを保存する
- 問題シナリオをGolden Testへ追加する
ロールバック先も同じ障害要因へ依存していないか確認する。共通インターネットGateway、共通Secret、共通Queueが単一障害点になり得る。
編集部分析
OpenAI互換Endpointの価値は、完全互換ではなく、移植コストの高い部分を減らすことにある。HTTP形式やSDK利用を共通化できれば、評価、ルーティング、調達の選択肢が増える。
しかし、Provider抽象化を目的化すると、各モデルの強みを使えず、最小公倍数の機能だけになる。共通能力とProvider拡張を分け、基本経路は移植可能、高度機能は明示的にロックインを受け入れる設計が現実的である。
「いつでも切り替えられる」という主張は、定期的な本番相当切替試験を行って初めて成立する。コードがコンパイルできることではなく、状態、Tool、監査、費用を含めて切り替えられることが条件である。
実務チェックリスト
- [ ] 構文互換と意味互換を分けて評価した
- [ ] Provider Adapterをアプリ本体から分離した
- [ ] AWS認証とOpenAI認証を別管理した
- [ ] モデル能力・地域・価格・データ条件を表にした
- [ ] Toolと構造化出力のGolden Testを作った
- [ ] Provider固有FieldをExtensionへ隔離した
- [ ] エラーとRequest IDを正規化・保存した
- [ ] 状態をProvider外へ退避できる
- [ ] 副作用Toolに冪等性キーを設定した
- [ ] 障害時の実切替試験を行った