mcpField
S
stability-ai-image

stability-ai-image

github.com/calesthioクリエイティブ・メディア219102 回インストール15 週間前に更新
リポジトリ

stability-ai-image について

stability-ai-imageは、Stability AIのホスト型画像APIまたはセルフホスト型オープンウェイトの選択と利用を支援するスキルです。開発者向けに、生成・編集・制御・アップスケールに適したAPIを案内し、制作内容の記録も支援します。

主な機能

  1. 01ホスト型APIとセルフホストの選択ガイド
  2. 02テキストからの生成と画像から画像への生成
  3. 03画像編集と背景除去
  4. 04スケッチ・構図・スタイルの制御
  5. 05画像のアップスケール

活用シーン

  1. 01画像タスクに適したAPIルートの選択
  2. 02マスクやテキスト指示による画像編集
  3. 03スケッチやスタイル参照による出力制御
  4. 04再解釈の度合いを変えた画像のアップスケール

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/calesthio/generative-media-skills --skill stability-ai-image

インストール後、Claude Code で/stability-ai-imageを入力して読み込まれたか確認します。

同梱ファイルEVAL.md

詳細

Stability AI 画像生成

このスキルは、適切な Stability AI の画像生成機能を選び、スキーマに準拠した呼び出しを行い、生成時の証跡を保持し、ホスト型 API とセルフホスト型の重みを混同しないために使用します。

証拠の凡例と鮮度

  • ドキュメント記載とは、リンク先の Stability AI 公式ソースまたは最新の公式 OpenAPI ドキュメントに記載されていることを意味します。
  • 推論とは、ドキュメント記載の挙動から導いた結論を意味します。影響が大きい場合は検証してください。
  • 本番運用のヒューリスティックとは、運用上の助言であり、プロバイダーによる保証ではありません。
  • このスキルに記載された変動しやすい API 情報は、2026-07-09に確認済みです。費用を確定する前、または長期間運用する連携をリリースする前に、API リファレンス、料金、リリースノートを再確認してください。

プロンプトを書く前にジョブの実行先を決める

  1. ホスト型とセルフホスト型のどちらで実行するかを決めます。
    • Stable Image のマネージドサービス、編集、コントロール、アップスケーラー、モデレーション、プロバイダー署名付きの来歴には、ホスト型 Platform API を使用します。
    • ローカルでのデータ管理、カスタム推論、ファインチューニング、またはデプロイの制御が、モデルの運用とライセンス上の義務を正当化する場合に限り、オープンウェイトを使用します。
    • Stable Image Core や Stable Image のすべてのマイクロサービスがダウンロード可能な重みであるかのように説明しないでください。ダウンロード可能な SD3.5 チェックポイントとホスト型サービスのカタログが重複する範囲は一部に限られます。
  2. すべてのジョブを生成に無理に当てはめず、目的に合った操作を選びます。
  3. 出力サイズ、入力の制約、費用、同期・非同期の動作を確認します。
  4. 元画像をアップロードする前に、権利、同意、プライバシー、最新の Acceptable Use Policy を確認します。
  5. バッチ処理の前に、承認済みの小規模なサンプルを生成します。エンドポイント、パラメーター、API が返したシード、リクエスト ID、入力のハッシュ、出力のハッシュ、費用の見積もり、ポリシーと品質確認の判定を記録します。

現在のホスト型機能

ドキュメント記載、2026-07-09に確認済み: REST v2beta は主要な機能を提供するサーフェスです。Stability によると、REST v1、gRPC、v2alpha は引き続き保守されていますが、新機能やパラメーターは追加されません。同等の v2alpha URL を v2beta に変更することを推奨しています。レガシー API は新規設計の情報源ではなく、保守・移行用のサーフェスとして扱ってください。API リファレンス

生成
サービスエンドポイント用途出力現在の料金
Stable Image UltraPOST /v2beta/stable-image/generate/ultra最上位のマネージド生成。任意の初期画像にも対応1 MP。1:1 では 1024x10248 クレジット
Stable Image CorePOST /v2beta/stable-image/generate/core低コストで高速な、マネージド型テキスト画像生成の反復1.5 MP3 クレジット
SD3.5 suitePOST /v2beta/stable-image/generate/sd3ベースモデルを明示的に選択して cfg_scale を指定。テキスト画像生成または画像から画像への変換1 MP。1:1 では 1024x1024Large 6.5、Large Turbo 4、Medium 3.5、Flash 2.5 クレジット

ドキュメントに記載されている SD3.5 の識別子は sd3.5-large、sd3.5-large-turbo、sd3.5-medium、sd3.5-flash です。デフォルトは Large です。プロバイダーは Turbo と Flash を、4 ステップの蒸留済みバリアントとして説明しています。ドキュメントの不一致: API の説明文と料金一覧には Flash が記載されていますが、確認時点のダウンロード可能な OpenAPI の model 列挙値には sd3.5-flash が含まれていませんでした。Flash が必要な場合は、バッチ処理の前に対象アカウントで低コストの呼び出しを 1 回行って検証し、モデルを暗黙に変更せずに 400 を処理してください。API リファレンス、料金

編集
操作エンドポイント必須フィールド重要なオプションフィールド出力/価格
消去/v2beta/stable-image/edit/eraseimage。マスクファイルまたは画像のアルファチャンネルで領域を指定しますmask、grow_mask 0~20、デフォルトは5、seed、output_format4 MP/5クレジット
インペイント/v2beta/stable-image/edit/inpaintimage、prompt。マスクファイルまたはアルファチャンネルで領域を指定しますmask、negative_prompt、grow_mask 0~100、デフォルトは5、style_preset、seed、output_format4 MP/5クレジット
アウトペイント/v2beta/stable-image/edit/outpaintimage と、ゼロ以外の方向を少なくとも1つleft、right、up、down はそれぞれ0~2000、prompt、creativity 0~1、デフォルトは.5、style_preset、seed、output_format4クレジット
検索と置換/v2beta/stable-image/edit/search-and-replaceimage、置換後の prompt、search_promptnegative_prompt、grow_mask 0~20、デフォルトは3、style_preset、seed、output_format4 MP/5クレジット
検索と色変更/v2beta/stable-image/edit/search-and-recolorimage、色変更用の prompt、select_promptnegative_prompt、grow_mask 0~20、デフォルトは3、style_preset、seed、output_format入力解像度/5クレジット
背景の削除/v2beta/stable-image/edit/remove-backgroundimageoutput_format は png または webp のみ透過対応の出力/5クレジット
背景の置換と照明の再調整/v2beta/stable-image/edit/replace-background-and-relightsubject_image と、background_prompt および/または background_referenceforeground_prompt、negative_prompt、preserve_original_subject 0~1、デフォルトは.6、original_background_depth 0~1、デフォルトは.5、keep_original_background、light_source_direction、light_reference、light_source_strength 0~1、デフォルトは.3、seed、output_format非同期/8クレジット

マスクについて、**ドキュメントに記載されている仕様:**黒は保持、白は最大強度で編集、グレーは部分的な強度を指定します。明示的に指定した mask は、画像のアルファチャンネルより優先されます。明示的なマスクを指定しない場合、透明ピクセルは編集され、不透明ピクセルは保持されます。サイズが異なるマスクは自動的にリサイズされます。それでも、QA で境界を正確に確認できるよう、画像と同じサイズのマスクを使用してください。API リファレンス

**仕様上の欠陥、2026-07-09 に検証済み:**ダウンロード可能な OpenAPI では、宣言されていない prompt が Erase の必須項目として指定されていますが、エンドポイントの説明文と公式サンプルでは image のみが必須で、mask は任意です。説明文とサンプルに従ってください。サービスからスキーマエラーが返された場合は、応答の id を記録し、prompt を独自に追加するのではなく、最新のリファレンスを再確認してください。

コントロール
操作エンドポイントリクエストコントロールの仕様出力/価格
スケッチ/v2beta/stable-image/control/sketch必須:image、prompt;任意:control_strength、ネガティブプロンプト、seed、スタイル、フォーマット輪郭やエッジが結果をガイドします。強度は0~1、デフォルトは.7です入力解像度/5クレジット
構造/v2beta/stable-image/control/structureスケッチと同じスキーマ入力の構図や構造が結果をガイドします。強度は0~1、デフォルトは.7です入力解像度/5クレジット
スタイルガイド/v2beta/stable-image/control/style必須:スタイルのimage、prompt;任意:aspect_ratio、fidelity、ネガティブプロンプト、seed、プリセット、フォーマット参照スタイルをもとに、新しい構図を生成します。忠実度は0~1、デフォルトは.5です1 MP/5クレジット
スタイル転送/v2beta/stable-image/control/style-transfer必須:init_image、style_image;任意:prompt、ネガティブプロンプト、seed、フォーマット構図を維持しながら既存のコンテンツを変換します。style_strengthのデフォルトは1、composition_fidelityのデフォルトは.9、change_strengthのデフォルトは.9ですinitのアスペクト比で1 MP/8クレジット

線やエッジの意図にはスケッチ、レイアウトや幾何形状には構造、参照する美的スタイルで新しいコンテンツを作成するにはスタイルガイド、既存のコンテンツのスタイルを変更するにはスタイル転送を使用してください。人物の同一性、ピクセル単位で正確なレイアウト、ロゴの忠実度、決定論的なスタイルコピーは保証しないでください。要件はそれぞれ目視で確認してください。

アップスケール
操作エンドポイントリクエストと制限動作出力/価格
高速/v2beta/stable-image/upscale/fastimage;幅と高さは32~1536、合計1,024~1,048,576ピクセル軽量な補正を行い、寸法を4倍にしますAPIリファレンスでは最大16 MP/2クレジット
保守的/v2beta/stable-image/upscale/conservativeimage、prompt;画像の各辺は64以上、4,096~9,437,184ピクセル、アスペクト比は1:2.5~2.5:1再解釈よりも元画像の維持を重視します。creativityのドキュメント記載の基本範囲は.2~.5、デフォルトは.35です4 MP/40クレジット
クリエイティブ/v2beta/stable-image/upscale/creativeimage、prompt;入力画像の各辺は64以上、ピクセル数は1,048,576以下1 MP未満の劣化した入力を大幅に再解釈します。creativityは.1~.5、デフォルトは.3です非同期/60クレジット

製品の正確な形状、顔、テキスト、証拠、忠実な復元が重要な場合は、クリエイティブを使用しないでください。**本番環境向けのヒューリスティック:**まず高速を比較し、次に保守的を比較します。再解釈が許容される場合に限り、クリエイティブを使用してください。現在の価格ページとライブOpenAPIはいずれも、クリエイティブの価格を60クレジットとしています。古いインデックス済みの説明には40と記載されている場合があるため、承認時には価格ページを確認してください。

**現在のドキュメントの不一致:**Fast UpscalerのAPIリファレンスでは最大16 MPの出力と説明されていますが、現在の価格ページでは最大4 MPと記載されています。対象アカウントでのテストと現在のサポートガイダンスで確認できるまでは、予算や納品に関する確約は4 MPを保守的な基準としてください。入力寸法を記録し、想定外のサイズの結果は拒否してください。

**ドキュメントの不整合:**Fastエンドポイントのリファレンスでは、最大16 MPまで寸法を4倍にすると説明されていますが、現在の価格説明では最大4 MPと記載されています。マーケティング文言をもとに最大値を契約しないでください。代表的な寸法をライブエンドポイントで事前に確認し、バッチ処理の前に返却されたファイルを検証してください。Creativeは「4K」に達すると説明されていますが、スキーマでは幅と高さの正確な組み合わせは保証されていません。OutpaintとRelightについても、各操作の概要には固定の出力解像度の保証は記載されていません。

正確なトランスポートとレスポンスの仕様

認証とヘッダー

ベース URL https://api.stability.ai を使用します。次を送信します。

Authorization: Bearer <STABILITY_API_KEY>
Accept: image/*

すべての画像 POST リクエストの本文は multipart/form-data です。HTTP ライブラリに Content-Type とその境界を設定させてください。multipart/form-data をハードコードしないでください。任意の診断用ヘッダーは stability-client-id、stability-client-user-id、stability-client-version で、それぞれ最大 256 文字です。エンドユーザー ID は難読化してください。キーはシークレットマネージャーまたは環境変数に保存し、ブラウザーコードに含めないでください。API キーのガイダンス

2026-07-09 に確認した、公開されているアクセス条件と価格の基準: Platform アカウントとキーを作成します。新規アカウントには 25 トライアルクレジットが付与されると案内されており、アカウントで保有できる有効なキーは最大 10 個、現在の価格は 1 クレジットあたり 0.01 ドルです。価格は変更される場合があります。環境ごとに別のキーを使用します。ただし、非同期生成の開始に使用した結果を取得する際は、同じキーを使用してください。承認の直前に、アカウント残高と最新の価格を確認してください。API キーのガイダンス、価格

バイナリデータには Accept: image/* を、base64 JSON には Accept: application/json を使用します。同期処理が成功した場合:

  • バイナリレスポンス:画像データ。content-type、x-request-id、finish-reason、seed ヘッダーを読み取ります。
  • JSON レスポンス:{ "image": "<base64>", "seed": 343940597, "finish_reason": "SUCCESS" }。
  • finish-reason / finish_reason は SUCCESS または CONTENT_FILTERED です。HTTP 200 でも、フィルタリングされた出力は QA 不合格として扱ってください。

一般的なエラーでは、{ "id": "...", "name": "...", "errors": ["..."] } 形式の JSON が返されます。シークレットや機微なソースコンテンツを保存せずに、サポート用としてレスポンスの id を保存してください。

共通フィールドと制約
  • prompt:必要な場合、1~10,000 文字。一部の編集/制御プロンプトでは、重みが 0~1 の (word:weight) 形式が文書化されています。
  • negative_prompt:最大 10,000 文字。
  • seed:0~4,294,967,294。ランダムなシードを使用するには、省略するか 0 を送信します。要求した値だけでなく、返されたシードを保存してください。
  • output_format:png、jpeg、webp のいずれか。ただし、Remove Background でサポートされるのは png または webp のみです。
  • 生成可能なアスペクト比:21:9、16:9、3:2、5:4、1:1、4:5、2:3、9:16、9:21。デフォルトは 1:1 です。
  • スタイルプリセット:enhance、anime、photographic、digital-art、comic-book、fantasy-art、line-art、analog-film、neon-punk、isometric、low-poly、origami、modeling-compound、cinematic、3d-model、pixel-art、tile-texture。プロバイダーによると、このリストは変更される場合があります。
  • アップロード画像の形式は JPEG、PNG、WebP です。ほとんどの編集/制御入力では、各辺が 64 ピクセル以上、総ピクセル数が 4,096~9,437,184 である必要があります。また、多くの場合、アスペクト比は 1:2.5~2.5:1 である必要があります。Remove Background の総ピクセル数の上限は 4,194,304 です。すべてに共通する単一のルールではなく、各エンドポイントのスキーマを適用してください。
  • これらの v2beta 画像呼び出しでは、リクエストペイロードの上限は 10 MiB です。

SD3.5 のテキストから画像への変換では aspect_ratio が有効です。画像から画像への変換では、代わりに mode=image-to-image、image、strength 0~1 を送信します。Strength が 0 の場合は入力が保持され、1 の場合は画像条件付けのない状態に近づきます。cfg_scale は 1~10 です。文書化されているデフォルト値は Large/Medium で 4、Turbo/Flash で 1 です。Stability は Flash の画像から画像への変換で、strength を 0.94~0.97 にすることを推奨しています。Ultra では、SD3.5 の mode フィールドなしで、任意の image と strength を指定できます。公開されているスキーマでは、Core はテキストから画像への変換のみをサポートします。

同期処理と非同期処理

一覧に記載されている呼び出しは、Creative Upscale、Replace Background、Relight を除き、すべて同期 HTTP 200 の画像レスポンスです。

  1. マルチパートリクエストを POST します。
  2. { "id": "<64-character generation id>" } を解析します。
  3. 同じ API キーを使って GET /v2beta/results/{id} をポーリングします。
  4. ポーリングの間隔は 10 秒以上空けてください。202 は処理中、200 は結果の返却、404 は ID が間違っている、別のキーに紐付いている、または期限切れであることを示します。
  5. 結果はすぐにダウンロードしてください。結果は 24 時間保持され、その後削除されます。

ドキュメントでは、非同期処理の開始レスポンスを HTTP 200 と記載していますが、古いクライアントの一部では 202 を想定しています。画像エンドポイントでは、ドキュメントに記載されたステータスを受け入れ、レスポンス本文に id が含まれることを必須としてください。Platform 全般の入力/出力保持期間を 24 時間と見なさないでください。この期間は非同期結果の取得のみに適用されます。

完全に実行可能な例:本番環境を想定した Python クライアント

これは一例であり、必須のアーキテクチャではありません。同期 Core 生成、マスクを使った Inpaint、非同期 Creative Upscale を扱います。API には冪等性キーが記載されていないため、曖昧な有料 POST リクエストの失敗を自動で再試行しないようにしています。

import base64
import hashlib
import json
import os
import sys
import time
from contextlib import ExitStack
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
from pathlib import Path

import requests
from PIL import Image

BASE = "https://api.stability.ai"
KEY = os.environ["STABILITY_API_KEY"]
SESSION = requests.Session()
SESSION.headers.update({
    "authorization": f"Bearer {KEY}",
    "stability-client-id": "image-pipeline",
    "stability-client-version": "1.0.0",
})


class StabilityError(RuntimeError):
    pass


def sha256_file(path: Path) -> str:
    digest = hashlib.sha256()
    with path.open("rb") as stream:
        for chunk in iter(lambda: stream.read(1024 * 1024), b""):
            digest.update(chunk)
    return digest.hexdigest()


def retry_after_seconds(value: str | None) -> float:
    if not value:
        return 60.0
    try:
        return max(60.0, float(value))
    except ValueError:
        try:
            when = parsedate_to_datetime(value)
            if when.tzinfo is None:
                when = when.replace(tzinfo=timezone.utc)
            return max(60.0, (when - datetime.now(timezone.utc)).total_seconds())
        except (TypeError, ValueError, OverflowError):
            return 60.0


def error_payload(response: requests.Response) -> dict:
    try:
        body = response.json()
        return body if isinstance(body, dict) else {"body": body}
    except ValueError:
        return {"body": response.text[:1000]}


def fail(response: requests.Response, context: str) -> None:
    payload = error_payload(response)
    request_id = payload.get("id") or response.headers.get("x-request-id")
    raise StabilityError(
        f"{context}: HTTP {response.status_code}; request_id={request_id}; "
        f"error={json.dumps(payload, ensure_ascii=False)}"
    )


def detect_image_type(raw: bytes) -> str:
    if raw.startswith(b"\x89PNG\r\n\x1a\n"):
        return "image/png"
    if raw.startswith(b"\xff\xd8\xff"):
        return "image/jpeg"
    if len(raw) >= 12 and raw[:4] == b"RIFF" and raw[8:12] == b"WEBP":
        return "image/webp"
    raise StabilityError("Output does not have a recognized PNG, JPEG, or WebP signature")


def write_image(response: requests.Response, output: Path) -> dict:
    transport_type = response.headers.get("content-type", "").split(";", 1)[0].lower()
    if transport_type == "application/json":
        payload = response.json()
        encoded = payload.get("image")
        if not isinstance(encoded, str) or not encoded:
            raise StabilityError("JSON success response is missing image base64")
        try:
            raw = base64.b64decode(encoded, validate=True)
        except Exception as exc:
            raise StabilityError("JSON image field is not valid base64") from exc
        seed = payload.get("seed")
        finish_reason = payload.get("finish_reason")
    elif transport_type.startswith("image/"):
        raw = response.content
        seed = response.headers.get("seed")
        finish_reason = response.headers.get("finish-reason")
    else:
        raise StabilityError(f"Unexpected success content-type: {transport_type}")
    if finish_reason != "SUCCESS":
        raise StabilityError(f"Generation finished as {finish_reason}; do not publish")
    if len(raw) < 100:
        raise StabilityError("Image payload is implausibly small")
    image_type = detect_image_type(raw)
    if transport_type.startswith("image/") and transport_type != image_type:
        raise StabilityError(f"Header says {transport_type}, bytes are {image_type}")
    allowed_suffixes = {
        "image/png": {".png"},
        "image/jpeg": {".jpg", ".jpeg"},
        "image/webp": {".webp"},
    }
    if output.suffix.lower() not in allowed_suffixes[image_type]:
        raise StabilityError(f"Output extension {output.suffix} does not match {image_type}")
    output.parent.mkdir(parents=True, exist_ok=True)
    output.write_bytes(raw)
    return {
        "path": str(output),
        "sha256": hashlib.sha256(raw).hexdigest(),
        "seed": seed,
        "request_id": response.headers.get("x-request-id"),
        "transport_content_type": transport_type,
        "image_content_type": image_type,
    }


def request_manifest(endpoint: str, data: dict, file_paths: dict, context: dict) -> dict:
    return {
        "endpoint": endpoint,
        "service": context["service"],
        "model": context["model"],
        "credit_estimate": context["credits"],
        "request_fields": dict(data),
        "requested_seed": data.get("seed"),
        "input_sha256": {name: sha256_file(path) for name, path in file_paths.items()},
        "policy_qa_disposition": "pending human review",
    }


def multipart_files(stack: ExitStack, file_paths: dict) -> dict:
    if not file_paths:
        return {"none": ("", b"")}  # Force a requests-generated multipart boundary.
    return {
        name: stack.enter_context(path.open("rb"))
        for name, path in file_paths.items()
    }


def sync_post(
    endpoint: str, *, data: dict, file_paths: dict, output: Path, context: dict
) -> dict:
    # A 429 is a documented rate-limit rejection; reopen every stream before retrying.
    manifest = request_manifest(endpoint, data, file_paths, context)
    for attempt in range(2):
        with ExitStack() as stack:
            response = SESSION.post(
                BASE + endpoint,
                data=data,
                files=multipart_files(stack, file_paths),
                headers={"accept": "image/*"},
                timeout=(15, 180),
            )
        if response.status_code == 429 and attempt == 0:
            time.sleep(retry_after_seconds(response.headers.get("retry-after")))
            continue
        if response.status_code != 200:
            fail(response, endpoint)
        metadata = write_image(response, output)
        metadata.update(manifest)
        return metadata
    raise AssertionError("unreachable")


def async_post(
    endpoint: str, *, data: dict, file_paths: dict, output: Path, context: dict
) -> dict:
    manifest = request_manifest(endpoint, data, file_paths, context)
    with ExitStack() as stack:
        start = SESSION.post(
            BASE + endpoint,
            data=data,
            files=multipart_files(stack, file_paths),
            headers={"accept": "application/json"},
            timeout=(15, 180),
        )
    if start.status_code != 200:
        fail(start, endpoint)
    generation_id = start.json().get("id")
    if not isinstance(generation_id, str) or len(generation_id) != 64:
        raise StabilityError(f"Missing/invalid async id: {start.text[:500]}")
    deadline = time.monotonic() + 15 * 60
    while time.monotonic() < deadline:
        time.sleep(10)
        result = SESSION.get(
            f"{BASE}/v2beta/results/{generation_id}",
            headers={"accept": "image/*"},
            timeout=(15, 180),
        )
        if result.status_code == 202:
            continue
        if result.status_code != 200:
            fail(result, f"poll {generation_id}")
        metadata = write_image(result, output)
        metadata["generation_id"] = generation_id
        metadata.update(manifest)
        return metadata
    raise TimeoutError(f"Generation {generation_id} did not finish before local deadline")


def run_core() -> dict:
    return sync_post(
        "/v2beta/stable-image/generate/core",
        file_paths={},
        data={
            "prompt": (
                "Editorial product photograph of a matte cobalt travel mug on pale gray stone, "
                "three-quarter view, soft north-window light, restrained shadow, no text"
            ),
            "negative_prompt": "logo, watermark, extra handles, warped rim",
            "aspect_ratio": "4:5",
            "seed": "18472931",
            "output_format": "webp",
        },
        output=Path("outputs/mug-core.webp"),
        context={"service": "Stable Image Core", "model": "managed-core", "credits": 3},
    )


def run_inpaint() -> dict:
    return sync_post(
        "/v2beta/stable-image/edit/inpaint",
        file_paths={"image": Path("inputs/room.png"), "mask": Path("inputs/mask.png")},
        data={
            "prompt": "a low walnut side table matching the room perspective and warm light",
            "negative_prompt": "people, text, floating furniture",
            "grow_mask": "6",
            "seed": "482019",
            "output_format": "png",
        },
        output=Path("outputs/room-inpaint.png"),
        context={"service": "Stable Image Inpaint", "model": "managed-edit", "credits": 5},
    )


def run_creative_upscale() -> dict:
    source = Path("inputs/degraded-portrait.jpg")
    if source.stat().st_size > 9 * 1024 * 1024:
        raise StabilityError("Creative Upscale input exceeds the conservative 9 MiB file gate")
    with Image.open(source) as image:
        width, height = image.size
        if image.format not in {"JPEG", "PNG", "WEBP"}:
            raise StabilityError(f"Unsupported input format: {image.format}")
    pixels = width * height
    if width < 64 or height < 64 or not 4_096 <= pixels <= 1_048_576:
        raise StabilityError(f"Creative Upscale input is outside documented bounds: {width}x{height}")
    return async_post(
        "/v2beta/stable-image/upscale/creative",
        file_paths={"image": source},
        data={
            "prompt": "natural editorial portrait, realistic skin texture, soft daylight",
            "negative_prompt": "plastic skin, altered identity, text, watermark",
            "creativity": "0.2",
            "seed": "92173",
            "output_format": "png",
        },
        output=Path("outputs/portrait-upscaled.png"),
        context={"service": "Creative Upscale", "model": "managed-upscaler", "credits": 60},
    )


if __name__ == "__main__":
    modes = {"core": run_core, "inpaint": run_inpaint, "creative-upscale": run_creative_upscale}
    if len(sys.argv) != 2 or sys.argv[1] not in modes:
        raise SystemExit(f"usage: {sys.argv[0]} {'|'.join(modes)}")
    print(json.dumps(modes[sys.argv[1]](), indent=2))

実行前に、requests と Pillow をインストールし、STABILITY_API_KEY を設定してください。選択したモードで必要な入力ファイルのみを用意し、現在のクレジット数を確認したうえで、有料生成の承認を得てください。Creative の例では創造性の設定を低くしていますが、それでも人物の同一性が変わる可能性があります。同一性が重要な修復には使用しないでください。

プロンプトと制御の実践

本番環境での経験則: プロンプトは、主題と動作、構図/カメラ、素材と照明、環境、スタイル/仕上げ、必要な場合に限った正確な表示テキストの順で、制作向けの指示として記述します。形容詞を並べるより、具体的な関係性を優先してください。ネガティブプロンプトは短く、欠陥に絞った内容にしてください。ポジティブプロンプト全体をネガティブ欄にコピーしないでください。

シードは、変更点を一つに絞って比較するために使い、永続的な再現性を保証するものとして扱わないでください。ホスト型モデル/サービスの更新、安全システム、文書化されていないバックエンドの変更により、同じリクエストでも出力が変わることがあります。入力、リクエストフィールド、返されたシード、日付、実際の出力を保存してください。

画像内のテキストについては、希望する文字列を正確に引用し、配置とタイポグラフィを指定してください。綴りの正確さが契約上必要な場合は、手動で組版することも想定してください。ブランドや製品については、権利上問題がない場合にのみ編集/制御用の参照画像を使用し、ロゴ、形状、ラベル、法的表示を 100% 表示で確認してください。法的または安全上のポリシーを徹底する手段として、ネガティブプロンプトに頼らないでください。

アウトペイントでは、実用上可能な限り、元画像の寸法を超えない範囲で段階的に拡張してください。プロバイダーは、品質を保つため、方向の値を元画像の寸法以下にするよう明示的に推奨しています。各段階の後に、元画像との境界、遠近法のつながり、繰り返し模様、被写体の重複、照明の変化を確認してください。

障害への対応

ステータス/条件意味対応
200 + SUCCESS利用可能なトランスポート成功コンテンツと技術面の QA は引き続き実施します
200 + CONTENT_FILTERED出力がモデレーションに抵触し、ぼかし処理された却下します。公開したり、セーフガードの回避を試みたりしないでください
400パラメーター/スキーマが無効変更せずに再試行しないでください。エンドポイント固有のフィールドと公式リファレンスを照合します
401キーがない/無効、または認証形式が不正停止します。シークレットの取得元と Bearer の形式を確認し、キーをログに記録しないでください
403モデレーション/ポリシーによるフラグ、または権限エラー停止します。ポリシーと権利を確認し、フィルタリングを回避するために自動的に言い換えないでください
413リクエストが 10 MiB を超過エンドポイントのピクセル数/アスペクト比の制限を守りながら、サイズ変更または再エンコードします
422形式は正しいが拒否された状態。文書化された言語/著名人に関するケースを含みますerrors を読み、適法かつポリシーに準拠する場合に限り、計画を変更します
42910 秒あたり 150 リクエストを超過。文書化された 60 秒のタイムアウトが発生60 秒以上待機し、Retry-After に従い、同時実行数を減らし、ジッターを加えます
500内部エラーレスポンス ID を保持し、承認済みのコスト/冪等性ポリシーの範囲内でのみ再試行します
POST 後のタイムアウト/接続切断結果が不確定な可能性があります有料の POST をむやみに繰り返さないでください。アカウントのテレメトリー/サポートを確認するか、重複課金の可能性について承認を得ます
非同期 202処理中です10 秒以上待ってから再度ポーリングします
非同期 404キー/ID が誤っているか、結果の有効期限が切れています同じキーを使用しているか、有効期限内かを確認します。承認を得た場合に限り、再生成します

公開レート制限は 10 秒あたり 150 リクエストです。これを超過すると 429 が返され、60 秒のタイムアウトが発生します。レート制限とコストは別の制御です。スループットにはトークンバケットを使用し、ジョブごとのクレジット予算は別に設定してください。Stability によると、生成に失敗しても課金されませんが、ネットワークの結果が不確定な場合は、慎重に再試行する必要があります。レート制限のガイダンス

本番環境の QA と受け入れ基準

生成前に受け入れ基準を定め、すべての候補を評価します。

  1. 意図: 被写体の数、動作、構図、必須/禁止要素、正確なテキスト。
  2. 解剖学的特徴と形状: 手、顔、関節、反射、影、遠近法、繰り返し構造、製品のシルエット。
  3. 編集の局所性: 意図した領域が変更され、保護対象の領域は変更されていないこと。ハロー、継ぎ目、色のにじみ、テクスチャの不連続がないこと。
  4. 参照元への忠実度: 選択した制御方法に応じて、構図、スタイル、または被写体を保持します。それぞれの目標を混同しないでください。
  5. 技術面: 寸法、アスペクト比、アルファ、形式、色の見え方、破損、ファイルハッシュ。
  6. 安全性と権利: 同意、パブリシティ権/プライバシー、商標/著作権、未成年者、センシティブ属性、誤解を招く文脈、開示。
  7. 来歴: メタデータを除去する変換の前にプロバイダーの元の出力を保持します。来歴の保持が納品要件の場合は、C2PA 対応バリデーターで認証情報を検証します。

本番環境でのヒューリスティック: モデル、強度、または制御設定を選ぶ際は、シード付きの A/B セットをブラインドレビューします。一度に変更する変数は 1 つだけにします。不採用理由を記録し、採用候補だけを残さないでください。失敗の分布は、バッチ計画に役立ちます。

ホステッド API とオープンウェイトの権利

以下の各制度を混同しないでください。

  • ホステッドプラットフォーム API: Stability の現行の利用規約、許容利用ポリシー、プライバシーポリシー、およびサービス料金が適用されます。ユーザーと Stability の間では、ユーザーが入力に関する権利を保持し、Stability は、該当する権利がある場合、法令およびコンプライアンスを条件として出力に関する権利をユーザーに譲渡します。他者向けに類似した出力が生成される場合があり、合法性と適切性については引き続きユーザーが責任を負います。利用規約では、AI の出力を人間が生成したものとして表示することを禁止しています。利用規約
  • セルフホスト型コアモデル: 各モデルリポジトリの実際のライセンスが適用されます。SD3.5 スイートは Stability AI Community License の下で提供されています。このライセンスでは、研究、非商用、および限定的な商用利用が許可されています。商用ユーザーは登録が必要です。また、ユーザーとその関連会社の年間収益が 100 万米ドルを超えると、無料の商用ライセンスは終了し、Enterprise ライセンスが必要になります。配布・帰属表示に関する義務と AUP に基づく義務は引き続き適用されます。この基準をホステッド API 呼び出しの料金ルールとして適用しないでください。ライセンスの概要、SD3.5 Large のモデルカード/ライセンス
  • その他のチェックポイント: SDXL、旧バージョンの SD、ファインチューン、サードパーティー製アダプター、コミュニティチェックポイントが同じライセンスを使用していると想定しないでください。正確なモデルと、同梱されるすべてのコンポーネントを確認してください。

これは運用上のガイダンスであり、法的助言ではありません。高額な利用、規制対象の利用、肖像に関わる利用、トレーニング、再配布、またはモデルホスティングに関する利用については、弁護士に相談してください。

プライバシー、安全性、来歴

文書で確認できる事項: Stability は、Platform の入力および出力をサービスの改善・開発やモデルのトレーニングに使用する場合があります。ただし、Platform API のユーザーは、アカウント概要で「Training: Improve the Model for Everyone」を「No」に設定することでオプトアウトできます。一般プライバシーポリシーでは、同期型の画像入力/出力に対する一律の短い保持期間を保証していません。24 時間以内に削除されると想定して、秘密情報、不要な個人データ、生体情報、またはクライアントの機密画像を送信しないでください。プライバシーセンター、プライバシーポリシー

文書で確認できる事項: ホステッド API ではプロンプト/出力の安全フィルターが適用されます。リリースノートには、入力フィルタリング、NSFW フィルタリング、Thorn による既知の CSAM のフィルタリング、C2PA 署名、および電子透かしが記載されています。後続の変換、再圧縮、スクリーンショット、または編集によって来歴を示す信号が削除されたり無効になったりする場合があるため、オリジナルを保管してください。すべての派生物で可視の電子透かしや完全な C2PA マニフェストが保証されると主張しないでください。リリースノート、安全性

成人ユーザーを対象とし、現行の AUP に従ってください。AUP では、権利・プライバシーの侵害、児童の搾取、露骨な性的コンテンツ、同意のない親密な画像、セーフガードの回避、有害または欺瞞的な利用、誤情報、および同意または法的権利のないなりすましが禁止されています。識別可能な人物やアップロードする参照画像について、同意と適法な権利を得てください。API 呼び出しが成功しても、法的な許可が得られたことにはなりません。許容利用ポリシー

移行と変更管理

  • Stable Diffusion 3.0 の識別子 sd3-large、sd3-large-turbo、sd3-medium は、2025-04-17 以降、自動的に対応する SD3.5 モデルへルーティングされています。ログに実際の意図が反映されるよう、エイリアスを明示的な SD3.5 識別子に置き換えてください。
  • Stable Diffusion 1.6 API と Stable Video Diffusion API は、2025-07-24 にサポートを終了しました。従来の画像生成について、プロバイダーは移行先として SDXL を挙げていますが、新しい用途では SDXL を前提として引き継ぐのではなく、明確な要件に照らして Core、Ultra、または SD3.5 を評価してください。
  • 2024-10-11 に非推奨となったモデルには、stable-diffusion-512-v2-1、stable-diffusion-xl-beta-v2-2-2、stable-diffusion-xl-1024-v0-9、esrgan-v1-x2plus が含まれます。新しい例では、これらの ID を使用しないでください。
  • 移行の前に、代表的なゴールデンセットを用意し、プロンプトへの忠実度、テキスト、アイデンティティ、形状、安全性の結果、レイテンシ、返される解像度、クレジットを比較してください。本番環境のバッチで、プロバイダー、エンドポイント、モデル、忠実度の設定を黙って切り替えないでください。
  • 実際に固定できるものを固定してください。エンドポイントのパス、明示的なモデル、リクエストフィールド、クライアントのバージョンが該当します。Core/Ultra などのマネージドサービスは、安定した名称のまま進化することを想定してください。

公式ソース

2026-07-09 に確認済み:

コメント