tutorial8 分で読める

GPT Image 2 のグローバルミラーとプロキシ:国際チームの低遅延アクセス

国際チームが文書化された ToAPIs オリジン経由で GPT Image 2 API を呼ぶ方法。セッション再利用と非同期画像タスクのポーリングを扱い、未検証の遅延数字には依拠しません。

ToAPIs Engineering & Evaluation Team
TL;DR - 要点まとめ
  • 環境ごとに文書化された ToAPIs オリジンを一つ選ぶ。公式ドキュメントは中国本土の利用者に https://toapis.cn を案内し、本シリーズは https://api.toapis.com を使う。
  • 現行の gpt-image-2 契約では、size は 1:1 や 16:9 などのアスペクト比、resolution は 1k / 2k / 4k であり、1024x1024 のような画素文字列ではない。
  • 画像ジョブは非同期である。タスク id を保存し、GET /v1/images/generations/{id} をポーリングする。クライアントのタイムアウトは失敗の証明ではない。
  • 未検証のハンドシェイク時間、POP 一覧、繰り返しプロンプトが無料のエッジキャッシュになるという約束を予算に使わない。

GPT Image 2 のグローバルミラーとプロキシ:国際チームの低遅延アクセス

対象モデル: gpt-image-2
推論エンドポイント: https://api.toapis.com/v1/images/generations
関連記事: GPT Image 2 API ガイド · GPT Image 2 の料金 · GPT-Image-2.6 API ガイド


1. クイックスタートと性能概要 (TL;DR)

  • 目的: 国際チームのクライアントを、毎回ベンダー起点へ長距離の新規セッションを張るのではなく、一つの ToAPIs 画像ゲートウェイへ向けます。
  • 契約: POST /v1/images/generations でモデル ID gpt-image-2 を使います。現行ドキュメントのフィールドは、prompt(最大 32,000 文字)、アスペクト比としての size(1:1 や 16:9 など。1024x1024 のような画素文字列ではない)、およびティアとしての resolution(1k、2k、4k)です。
  • リージョン: 公式 ToAPIs ドキュメントは、中国本土の利用者にベース URL https://toapis.cn を使うよう案内しています。本シリーズの国際向け例は https://api.toapis.com を使います。パス、モデル ID、Bearer ヘッダーは同じで、変わるのはオリジンだけです。
  • 非同期プロトコル: 画像生成はタスク id を返します。completed または failed になるまで GET /v1/images/generations/{task_id}(または GET /v1/tasks/{task_id})をポーリングします。クライアントの壁時計時間は生成時間そのものではなく、タイムアウトは失敗の証明でもありません。
  • この記事が主張しないこと: 未検証の POP 一覧、ハンドシェイク時間、エンドツーエンド遅延目標は掲載しません。それらは自分の経路で測ってください。パラメータと SKU の比較は API ガイド と 2.6 ガイド にあります。

2. ToAPIs ゲートウェイで国際チームの経路を揃える

ベンダー本拠から遠いチームが感じる遅延は、多くの場合二つに分かれます。接続を張る時間と、モデルが実際に描く時間です。これを「API が遅い」一つの数字にまとめると、最適化対象を間違えます。前者はネットワークの問題で、文書化されたより近い ToAPIs オリジンを使い、温まった HTTP セッションを再利用することで対処できます。後者は生成時間であり、タスクが受け付けられたあとに観察します。

ToAPIs は統一された画像生成パスを提供します。公式ドキュメントが現在示すのは https://toapis.com で、中国本土の利用者には https://toapis.cn へ置き換えるよう案内しています。本シリーズの GPT Image 2 API ガイド を含む記事は、同じパスを https://api.toapis.com へ送ります。環境ごとにベース URL を一つ選び、設定として持ち、同じサービスでオリジンを混在させないでください。

地域クラスタが中央の ToAPIs ゲートウェイを経由して画像生成パスへ入る抽象図

図 1: クライアントを文書化された一つの ToAPIs オリジンに置き、セッションを再利用し、画像生成を長距離の同期往復ではなく非同期タスクとして扱います。

未公開の遅延数字に依存しない、実務的なルーティング習慣です。

  • 環境ごとにオリジンは一つ。 シンガポールとフランクフルトのサービスは、同じモデル ID とペイロードを共有できます。各自でベンダー URL を発明しないでください。
  • 接続を再利用する。 HTTP keep-alive(クライアントが HTTP/2 に対応していればそれも)を有効にし、投入やポーリングのたびに TLS をやり直さない。
  • 投入と待機を分ける。 タスク id をすぐに永続化します。上限付き間隔でポーリングするか、タスク Webhook を優先し、ポーリングは予備にします。
  • 「同じプロンプトはエッジキャッシュ」を課金回避に使わない。 繰り返しプロンプトがエッジキャッシュから無料で返る、という ToAPIs の文書化された保証はありません。アカウント条件に別段の定めがなければ、投入したジョブは 2 件分として計画してください。

リクエスト契約も古くなりやすいです。古いスニペットは size を 1024x1024 とし、quality: "standard" を付けることがあります。現行の gpt-image-2 API リファレンスと ToAPIs フロントエンド契約では、size はアスペクト比(1:1、3:2、2:3、4:3、3:4、5:4、4:5、16:9、9:16、2:1、1:2、21:9、9:21、または auto)、resolution はティア(1k、2k、4k)です。現行 Playground 契約では、正確な gpt-image-2 に quality フィールドはなく、quality は gpt-image-2-vip などの ID に現れます。実際に呼ぶ ID を確認してください。

参照画像は reference_images に入れます(公開 URL のみ、最大 14 枚)。image_urls は後方互換の別名で、reference_images に正規化されます。base64 は送らず、先にアップロードしてください。カスタム比、追加の品質オプション、公式 SKU の挙動は API ガイド と モデルガイド を見てください。


3. 本番実装: cURL と Python

ステップ 1: cURL で投入

bash
curl -X POST "https://api.toapis.com/v1/images/generations" \
  -H "Authorization: Bearer $TOAPIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "Minimalist product still of a matte ceramic pour-over kettle on slate, soft side light, no typography",
    "size": "1:1",
    "resolution": "1k",
    "n": 1,
    "response_format": "url"
  }'

ステップ 2: Python の投入とポーリング

フィールド名とレスポンスの形は、アカウントの API リファレンスに合わせてください。例は文書化された画像ステータスパスと completed / failed を使います。中国本土向けオリジンが必要な環境でのみ、BASE を https://toapis.cn に切り替えてください。

python
import os
import time
import requests

API_KEY = os.environ["TOAPIS_API_KEY"]
BASE = "https://api.toapis.com"
ENDPOINT = f"{BASE}/v1/images/generations"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


def dispatch_image(
    prompt: str,
    size: str = "1:1",
    resolution: str = "1k",
    model: str = "gpt-image-2",
    reference_images: list[str] | None = None,
) -> str:
    payload = {
        "model": model,
        "prompt": prompt,
        "size": size,
        "resolution": resolution,
        "n": 1,
        "response_format": "url",
    }
    if reference_images:
        payload["reference_images"] = reference_images
    res = requests.post(ENDPOINT, headers=HEADERS, json=payload, timeout=30)
    res.raise_for_status()
    data = res.json()
    task_id = data.get("id") or data.get("task_id")
    if not task_id:
        raise RuntimeError(f"Unexpected submission envelope: {data}")
    return task_id


def poll_image_task(task_id: str, deadline_s: int = 180) -> str:
    poll_url = f"{BASE}/v1/images/generations/{task_id}"
    interval = 2.0
    start = time.time()
    while time.time() - start < deadline_s:
        time.sleep(interval)
        poll = requests.get(poll_url, headers=HEADERS, timeout=15)
        if poll.status_code == 429:
            retry_after = poll.headers.get("Retry-After")
            time.sleep(float(retry_after) if retry_after else min(interval * 2, 20))
            continue
        poll.raise_for_status()
        data = poll.json()
        status = data.get("status")
        if status == "completed":
            return data["result"]["data"][0]["url"]
        if status == "failed":
            raise RuntimeError(f"Generation failed: {data.get('error')}")
        interval = min(interval * 1.5, 8.0)
    raise TimeoutError(f"Task {task_id} exceeded {deadline_s}s; check status before retrying")


if __name__ == "__main__":
    task_id = dispatch_image(
        "Minimalist product still of a matte ceramic pour-over kettle on slate, soft side light, no typography"
    )
    print("Task:", task_id)
    print("Image:", poll_image_task(task_id))

ベース URL、モデル ID、size、resolution をタスク記録と一緒に残してください。あとでクライアントを gpt-image-2 から gpt-image-2-vip や 2.6 の SKU に移すときは、一度に一つの変数だけ変え、対応するガイドを読み直してください。課金単位は自動的には同じになりません。


4. エラー処理とステータスマトリクス

次の分類は切り分けの出発点であり、ToAPIs の正確なエラーコードを保証するものではありません。HTTP 照会が成功しても、タスクの status は必ず読んでください。

HTTP ステータスよくある分類推奨アクション
400不正なフィールド、または非対応の組み合わせモデル ID、size が文書化された比であること、resolution が 1k / 2k / 4k であること、参照画像が base64 ではなく URL であることを確認
401API キーの欠落または無効ToAPIs ダッシュボードでキーをローテーションし、Authorization ヘッダーを確認
429レートまたは同時実行の制限Retry-After があれば従い、ジッター付きでバックオフし、安全なときだけ再試行
5xx またはネットワークタイムアウトゲートウェイまたは上流の一時障害再投入の前にタスク状態を確認し、上限付きの再試行方針を使う

WaitTime=min⁡(MaxWait,BaseInterval×2attempt)+Uniform(0,1)\text{WaitTime} = \min(\text{MaxWait}, \text{BaseInterval} \times 2^{\text{attempt}}) + \text{Uniform}(0, 1)


5. 料金と FinOps ROI

Estimated cost=successful billable images×current account rate for that model, size, and resolution\text{Estimated cost} = \text{successful billable images} \times \text{current account rate for that model, size, and resolution}

  • 企画ドラフトや古い記事の単価を再利用しないでください。 カタログ料金、解像度倍率、失敗タスクの扱いは SKU とアカウントで変わります。一部の GPT Image 2.x ID は枚数課金です。2.6 ガイド は、その世代がトークン課金であることを説明しています。実際に呼ぶモデル ID の料金を確認してください。
  • 経路を変えること自体は、モデル単価を自動では変えません。 api.toapis.com と toapis.cn はベース URL の選択であり、文書化された割引ではありません。FinOps 上の効果は、クライアントタイムアウト後の二重投入を避け、1k で下書きし、適切な SKU を選ぶところから来ます。
  • 公式ベンダー契約 には地域ごとの請求制約、コミット、前払い下限が付くことがあります。ToAPIs の課金は通常従量制です。有効な条件はアカウントで確認してください。
  • 料金の詳細な議論は GPT Image 2 の料金記事 を背景にして構いませんが、予測に入れる前に、ライブカタログで数字を一つずつ確かめてください。

6. よくある質問

構造化 FAQ は frontmatter を参照してください。要約: ToAPIs のオリジンを変えてもモデル ID や文書化されたリクエスト形は変わりません。中国本土の利用者は公式ドキュメントの toapis.cn の注記に従ってください。画像ジョブは非同期です。size はアスペクト比、resolution はティアです。繰り返しプロンプトが無料のエッジキャッシュになるという文書化された保証はありません。


7. アクションチェックリスト

  • ToAPIs 開発者ポータル でキーを作成する。
  • 環境ごとにベース URL を一つ決め(https://api.toapis.com、必要な場合は https://toapis.cn)、gpt-image-2、size: "1:1"、resolution: "1k" で上記の cURL をスモークテストする。
  • タスク id を永続化し、GET /v1/images/generations/{id} を期限付きでポーリングし、429 では Retry-After に従う。
  • 次に: パラメータは GPT Image 2 API ガイド、SKU を移すなら 2.6 ガイド、新規アカウントは 無料クレジット案内。

記事内で紹介されたモデルとAPI

OpenAIIMAGE

GPT-Image-2

現在のレート:3 credits /request
OpenAIIMAGE

GPT-Image-2 VIP

現在のレート:3.38 credits /request

関連記事