あるプロバイダー構成から別の構成へテキストから動画へのプロダクトを移行する際に、認証ヘルパー、環境変数、リトライルール、可観測性フックをすべて書き換える必要はありません。より安全なパターンは、統合の中で安定したままにできる部分と、動画生成に特有の部分を分離することです。
すでに OpenAI 風のクライアントを使っているチームにとって、Flatkey は実用的な出発点になります。API キーを 1 つ作成し、クライアントのベース URL を https://router.flatkey.ai/v1 に設定し、小さな互換リクエストを実行して、Usage Logs でそのリクエストを確認します。これにより、Seedance 固有の非同期動画ワークフローを接続する前に、共有の接続レイヤーを検証できます。
このガイドでは、その移行を制御可能にし、元に戻しやすく、確認しやすくする方法を示します。
簡潔な答え
安定した OpenAI 互換ベース URL は、AI 統合の共有部分に関する移行作業を減らせます。
- API キーの注入
- 環境設定
- クライアント初期化
- リクエストの相関付け
- リトライとタイムアウトのポリシー
- 利用状況とコストの監視
ただし、すべてのテキストから動画へのプロバイダーが同じリクエスト本文や同じエンドポイントを使うという意味ではありません。動画生成では通常、別の非同期フローが必要になります。ジョブを作成し、ジョブ ID を保存し、ポーリングまたは Webhook を受け取り、最終成果物を取得します。
したがって、実装目標は「Seedance を chat-completions 形式に無理やり当てはめる」ことではありません。「ゲートウェイ接続を安定させ、その後に動画固有のジョブアダプターを小さなインターフェースの背後に分離する」ことです。
テキストから動画へのプロダクトでベース URL の安定性が重要な理由
プロバイダー移行が失敗するのは、通常モデル呼び出しの接点部分であり、モデル名を指定するたった 1 行ではありません。本番アプリケーションには、シークレットマネージャー内の API キー、複数サービスにまたがる HTTP クライアント、キューワーカー、Webhook ハンドラー、監査ログ、支出アラート、ロールバック設定が存在することがあります。
各プロバイダーがそれらのレイヤーすべてに直接配線されていると、新しい動画モデルを追加することは大規模なインフラ変更になります。安定したゲートウェイ境界は、影響範囲を限定します。
| レイヤー | 安定させるもの | 必要な場合のみ変更するもの |
|---|---|---|
| 認証情報 | シークレット名と注入パターン | キー値とローテーション記録 |
| クライアント | 共有 HTTP または OpenAI スタイルのクライアント初期化 | 選択したルートで使用する動画アダプター |
| ベース URL | 環境で制御される単一のゲートウェイ URL | 意図的なゲートウェイのロールバック時のみ |
| 可観測性 | 相関 ID、ログ、レイテンシ、コストレビュー | プロバイダー固有のジョブステータスフィールド |
| 信頼性 | タイムアウト予算、リトライの責任範囲、サーキットブレーカーポリシー | ポーリング間隔と最終的な動画状態 |
| 製品ロジック | ユーザー要求、権限、クォータ、アセットのライフサイクル | Seedance のプロンプトと動画パラメータ |
その結果、移行対象の範囲は小さくなります。製品コードは安定した内部インターフェースに依存し続け、アダプターが動画 API の差異を処理します。
最も安全な移行手順
1 回のリクエストで動画パス全体を検証しようとするのではなく、2 つの分離したチェックを使用します。
- 接続スモークテスト: 認証、OpenAI 互換のベース URL、ネットワークアクセス、Usage Logs を確認します。
- 動画ワークフローテスト: 現在の Seedance ルート、受け入れられるパラメータ、非同期のステータス遷移、アセット配信、課金動作を確認します。
この分離により、障害を分類しやすくなります。スモークテストが失敗する場合、問題は認証情報、ベース URL 設定、ネットワーク、または共通のリクエスト処理にある可能性が高いです。スモークテストは成功するが動画ジョブが失敗する場合は、モデルルートと動画アダプターに注目してください。
Step 1: move the base URL into configuration
アプリケーションロジックにプロバイダーの URL をハードコードしないでください。ゲートウェイ接続は環境変数に入れ、デプロイやロールバックでコード変更が不要になるようにします。
FLATKEY_API_KEY=sk-fk-replace-me
AI_BASE_URL=https://router.flatkey.ai/v1
AI_SMOKE_TEST_MODEL=gpt-4o-mini
VIDEO_PROVIDER=flatkey
VIDEO_MODEL=replace-with-current-seedance-route
動画モデルの値はデプロイ時設定として扱ってください。モデルのエイリアスやサポートされる機能は変更される可能性があるため、古い識別子をブログ記事からコピーするのではなく、ロールアウト前に Flatkey で現在のルートを確認してください。
Step 2: initialize the existing OpenAI-style client once
すでにアプリケーションで OpenAI Python SDK を使用している場合、共通の接続変更は意図的に小さくなっています。
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["FLATKEY_API_KEY"],
base_url=os.getenv("AI_BASE_URL", "https://router.flatkey.ai/v1"),
)
同等の TypeScript 設定でも、同じ境界を維持できます:
import OpenAI from "openai";
export const aiClient = new OpenAI({
apiKey: process.env.FLATKEY_API_KEY,
baseURL: process.env.AI_BASE_URL ?? "https://router.flatkey.ai/v1",
});
重要な設計上の選択は、サービスが個別にプロバイダー固有のクライアントをコードベース全体で組み立てるのではなく、設定済みのクライアントをインポートすることです。
Step 3: run a connection smoke test before touching video jobs
Flatkey のクイックスタートでは、OpenAI 互換の chat-completions リクエストを使い、その呼び出しを Usage Logs で確認するよう案内しています。その小さなテストを使って、共通の統合レイヤーを検証してください。
import os
from app.ai_client import client
def verify_gateway_connection() -> dict:
response = client.chat.completions.create(
model=os.getenv("AI_SMOKE_TEST_MODEL", "gpt-4o-mini"),
messages=[
{"role": "user", "content": "Reply with: gateway connection verified"}
],
max_tokens=20,
)
return {
"request_model": response.model,
"finish_reason": response.choices[0].finish_reason,
"usage": response.usage.model_dump() if response.usage else None,
}
このリクエストは Seedance の動画生成をテストしません。代わりに、両方のワークフローが依存する次の 4 つの前提条件を検証します:
- キーが存在し、受け入れられること
- ベース URL が正しいこと
- アプリケーションがルーターに到達できること
- リクエストが使用データ付きでダッシュボードに表示されること
最初のリクエストの詳細な流れについては、プロダクトチーム向け Seedance API クイックスタートを参照してください。
ステップ 4: Seedance を非同期動画アダプターの背後に置く
テキストから動画への生成は、通常の同期 API リクエストよりも時間がかかります。公開されている Seedance API のフローでは、タスクの作成の後にステータス確認または webhook 配信が続きます。このライフサイクルを明示的にモデル化してください。
export type VideoJobState =
| "queued"
| "running"
| "succeeded"
| "failed"
| "cancelled";
export interface VideoJob {
id: string;
state: VideoJobState;
outputUrl?: string;
errorCode?: string;
}
export interface TextToVideoAdapter {
createJob(input: {
prompt: string;
model: string;
idempotencyKey: string;
}): Promise<VideoJob>;
getJob(jobId: string): Promise<VideoJob>;
}
アダプターは、製品の安定した内部フィールドを、現在の動画エンドポイントが要求するペイロードに変換する必要があります。プロバイダー固有のパラメータは、コントローラー、UI コード、またはキュースキーマに漏らさず、そのアダプター内に閉じ込めてください。
動画エンドポイントが /chat/completions であると決めつけないでください。また、チャット応答が返ったからといって、選択した Seedance のルートが利用可能だと判断しないでください。実装時には、製品ドキュメントまたはダッシュボードで、現在のエンドポイント、モデルエイリアス、パラメータ、ステータス値を確認してください。
ステップ 5: ポーリングを安全かつ制限付きにする
動画ワーカーには、チャットリクエストとは異なる信頼性ルールが必要です。無限にポーリングし続けることは、リトライ戦略ではありません。
import random
import time
TERMINAL_STATES = {"succeeded", "failed", "cancelled"}
def wait_for_video(adapter, job_id: str, deadline_seconds: int = 600):
started_at = time.monotonic()
attempt = 0
while time.monotonic() - started_at < deadline_seconds:
job = adapter.get_job(job_id)
if job.state in TERMINAL_STATES:
return job
attempt += 1
delay = min(30, 2 ** min(attempt, 4))
time.sleep(delay + random.uniform(0, 1))
raise TimeoutError(f"Video job {job_id} exceeded its processing deadline")
本番環境でのポーリングでは、プロバイダーのガイダンスと Retry-After ヘッダーも尊重してください。ワーカーの再起動で重複した動画が作成されないよう、ポーリングの前に外部ジョブ ID を保存してください。
webhook が利用可能な場合は、署名を検証し、迅速に応答し、ハンドラーを冪等にしてください。webhook は複数回配信されたり、ポーリングワーカーがすでにジョブを完了した後に届いたりすることがあります。
ステップ 6: 両方のレイヤーで可観測性を追加する
ゲートウェイのリクエストと、プロダクトレベルの動画ジョブを別々に監視してください。
ゲートウェイのフィールド
- 環境とサービス名
- 内部リクエスト ID
- ルートまたはモデルエイリアス
- HTTP ステータス
- レイテンシー
- リトライ回数
- ダッシュボードに表示される使用量またはコストデータ
動画ジョブのフィールド
- 外部ジョブ ID
- ユーザーまたはワークスペース ID
- プロンプトのバージョン。デフォルトでは機密性の高いプロンプト内容はログに記録しない
- モデルと機能モード
- キュー、開始、完了のタイムスタンプ
- 最終状態と正規化されたエラーコード
- 出力アセットの場所と保持ポリシー
ダッシュボードは共有の運用チェックポイントです。スモークテストと最初の制御された動画ジョブの後、アプリケーションログと Flatkey の使用記録を照合してください。トラフィックを拡大する前に、記録の欠落、重複ジョブ、想定外のモデル名、またはコストの変化を調査します。
Step 7: use a reversible rollout plan
1つのベース URL を変更するのは簡単です。安全に展開するには、やはり制御が必要です。
- 開発環境からスモークテストを実行します。
- 機密性のない Seedance の評価ジョブを1件実行します。
- ジョブ状態の処理、アセット取得、使用状況の可視性を確認します。
- 内部アカウント、またはトラフィックの少量の割合に対してルートを有効にします。
- 成功率、エンドツーエンドのレイテンシー、完了したアセットあたりのコストを比較します。
- エラーバジェットが許容範囲内にある場合にのみ、トラフィックを増やします。
- ロールバック条件が期限切れになるまで、以前のプロバイダ設定を利用可能なままにしておきます。
起動前にロールバックのトリガーを定義します。例としては、認証エラーの繰り返し、失敗ジョブ率の上昇、処理期限を超えて停止したままのジョブ、使用状況記録の欠落、または出力取得の失敗などがあります。
Migration checklist
| Check | Pass condition |
|---|---|
| Key ownership | A named owner can rotate and revoke the Flatkey key |
| Secret handling | The key is server-side and absent from source control and browser bundles |
| Stable base URL | All shared clients read AI_BASE_URL from configuration |
| Connection test | The OpenAI-compatible smoke test succeeds |
| Dashboard verification | The smoke-test request appears in Usage Logs |
| Current Seedance route | The model alias and capability are confirmed at rollout time |
| Async lifecycle | Create, poll or webhook, terminal state, and asset retrieval are tested |
| Idempotency | Retries cannot create unintended duplicate videos |
| Timeout budget | Workers stop and escalate jobs that exceed the deadline |
| Observability | Gateway requests and video jobs share a correlation ID |
| Rollback | The previous configuration and decision owner are documented |
Common migration mistakes
Treating OpenAI compatibility as universal endpoint compatibility
OpenAI 互換クライアントは、認証とサポートされるリクエストファミリーを簡素化できます。だからといって、すべてのマルチモーダル操作や動画操作が同じスキーマを持つことは保証されません。動画アダプタは明示的に保ってください。
Changing the key, base URL, model, and worker logic in one release
それでは障害の切り分けが難しくなります。まずゲートウェイ接続を証明し、その後で動画パスを変更してください。
Retrying job creation without an idempotency strategy
ネットワークタイムアウトは、プロバイダがジョブを受け付けた後に発生することがあります。無差別に別のジョブを作成すると、重複したアセットが生成され、課金される可能性があります。
Using the HTTP request timeout as the video deadline
ジョブ作成リクエストと動画処理のライフサイクルは別々のタイマーです。最初のリクエストは短く保ち、その後は永続的なジョブ状態で非同期の期限を追跡してください。
Skipping dashboard verification
アプリケーションのレスポンスが成功しただけでは、運用上の確認としては不十分です。チームが監視する場所で、使用量、モデル、レイテンシー、コストの情報が表示されていることを確認してください。
FAQ
OpenAI の base URL を変更するだけで Seedance を統合できますか?
base URL の変更により、対応する OpenAI 互換リクエスト向けの共有接続レイヤーを簡素化できます。Seedance の動画生成では、専用の非同期エンドポイントとプロバイダー固有のパラメータが引き続き必要になる場合があります。実装前に現在のルートを確認してください。
移行中に変更しないままにしておくべきものは何ですか?
シークレットの注入、環境名、相関 ID、ロギング、アラート、そしてプロダクト向けの動画インターフェースは安定したままにしてください。プロバイダー固有の変更は、設定と動画アダプターに限定してください。
動画プロダクトでなぜチャットのスモークテストを実行するのですか?
このスモークテストは、ゲートウェイ認証、base URL、ネットワーク、Usage Logs を長い動画ワークフローからすばやく切り分けます。これは接続テストであり、動画機能テストではありません。
動画完了にはポーリングと Webhook のどちらを使うべきですか?
現在の動画 API とインフラストラクチャでサポートされている仕組みを使ってください。ポーリングはより簡単ですが、上限を設けてバックオフを行う必要があります。Webhook はポーリングを減らせますが、署名検証、冪等性、見逃したイベントの整合性回復が必要です。
重複した動画ジョブを防ぐにはどうすればよいですか?
プロダクト要求用の冪等性キーを作成して永続化し、外部ジョブ ID をただちに保存し、可能な限り再試行で既存ジョブを再開するようにしてください。
ロールアウト前にコストはどこで比較すべきですか?
現在のFlatkey の料金ページを確認し、リクエストごとや秒ごとではなく、完了した動画 1 本あたりのコストで比較してください。失敗したジョブと重複したジョブも計算に含めてください。
まず安定した境界を構築する
最も速い移行とは、初日に変更行数が最も少ないものではありません。将来のプロバイダー変更を、制御された設定更新と小さなアダプターにまで縮小できるものです。
まず 1 つの Flatkey キーから始め、共有クライアントを安定した base URL に移し、Usage Logs で接続を確認してから、現在の Seedance ワークフローを非同期ジョブシステムとしてテストしてください。チェックが通ったら、キーを取得し、明示的なメトリクスとロールバックトリガーを設定して展開してください。



