mcpField
A
amazon-nova-canvas

amazon-nova-canvas

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

amazon-nova-canvas について

Amazon Bedrock を使う画像生成ワークフロー向けのスキルです。Nova Canvas のタスク種別、入力条件、呼び出し方法を説明し、Legacy のモデルであるため利用前にアカウント資格、リージョン、ライフサイクルを確認するよう示します。

主な機能

  1. 01画像生成と編集のタスク
  2. 02リクエスト項目と入力条件
  3. 03画像サイズと形式の検証
  4. 04Bedrock InvokeModel の呼び出し案内
  5. 05Legacy ライフサイクルの確認

活用シーン

  1. 01テキストから画像を生成
  2. 02参照画像からバリエーションを作成
  3. 03背景除去や画像領域の編集
  4. 04既存 Nova Canvas ワークロードの呼び出し計画

インストール

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

$npx skills add https://github.com/calesthio/generative-media-skills --skill amazon-nova-canvas

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

同梱ファイルEVAL.md

詳細

Amazon Nova Canvas

Amazon Bedrock のネイティブな InvokeModel API に対して構築します。すべての推論は有料の同期画像生成処理として扱い、返されたバイト列は変更せずに保持してください。

まずライフサイクルのゲートを確認する

2026-07-09 時点で確認したところ、AWS はサポート対象リージョンで amazon.nova-canvas-v1:0 を Legacy として掲載し、提供終了日を 2026-09-30 としています。これを新規の本番環境の依存先にしないでください。新規のお客様は Legacy モデルを使用できません。既存のお客様も、15 日間利用がないとアクセスできなくなる可能性があります。提供終了日またはその直後には、プロバイダーとの文書化された個別契約がない限り、リクエストは失敗します。ステークホルダーの承認によってサービスの提供期間が延長されることはありません。

AWS は、基盤モデルが Legacy に移行した後の新規ファインチューニングジョブと新規のプロビジョンドスループットエンドポイントも禁止しています。提供される場合、一般向けの延長アクセスには、プロバイダーが設定した高い料金が適用される可能性があります。利用資格のある既存のお客様が利用を継続する前に、次の手順を実施してください。

  1. 利用予定のリージョンで GetFoundationModel または ListFoundationModels を呼び出します。
  2. アカウントが引き続き利用資格を満たし、アクティブであることを確認し、現在の料金を検証します。また、提供終了前、または有料推論が認められている文書化済みの個別契約の下でのみ、別途承認を得た低コストのカナリアテストを実施します。
  3. ライフサイクル、エンドポイント、リージョン、後継モデルに関する情報を、Nova Canvas のモデルページで再確認します。
  4. 代替モデル ID を推測してはいけません。移行の担当者と切り替え日を明記します。

現在の本番環境に関する情報(2026-07-09 に確認):

項目値
ベースモデル IDamazon.nova-canvas-v1:0
ランタイムbedrock-runtime
APIネイティブな同期 InvokeModel。Converse、Responses、Chat Completions、Bedrock Mantle ではありません
推論ルートリージョン内のみ。地理的推論プロファイルもグローバル推論プロファイルもありません
ベースモデルのサービスティアStandard のみ
ベースモデルのプロビジョンドスループット非対応
リージョン内での提供状況us-east-1、eu-west-1、ap-northeast-1
プロンプトの言語英語
入力/出力テキストと画像/画像
ライフサイクル現在サポートされているすべてのリージョンで Legacy。提供終了日は 2026-09-30

画像やプロンプトを別のリージョンに移動してはいけません。リージョンの選択は、データレジデンシーに関する判断です。

シークレットを埋め込まずにアクセスを確立する

AWS SDK の認証情報プロバイダーチェーンと、有効期間の短いロール認証情報を優先してください。AWS のコンピューティング環境では、最小権限の実行ロールをアタッチします。ローカル開発では、IAM Identity Center、aws login、または AssumeRole プロファイルを使用します。アクセスキーや Bedrock API キーをソース、コマンド履歴、マニフェスト、プロンプト、ログに含めてはいけません。

Bedrock は、AWS_BEARER_TOKEN_BEDROCK を通じたサービス固有のベアラー API キーにも対応しています。長期有効な Bedrock API キーは IAM ユーザーに紐付けられます。組織のキーに関するポリシーで認められている場合に限り使用し、シークレットマネージャーに保管してローテーションしてください。この環境変数は、現行の AWS SDK で認識されます。Bedrock API キー認証と AWS 認証情報プロバイダーチェーンを参照してください。

実際に使用するモデルとリージョンに対してのみ bedrock:InvokeModel を許可します。例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "InvokeNovaCanvasOnly",
      "Effect": "Allow",
      "Action": "bedrock:InvokeModel",
      "Resource": [
        "arn:aws:bedrock:us-east-1::foundation-model/amazon.nova-canvas-v1:0",
        "arn:aws:bedrock:eu-west-1::foundation-model/amazon.nova-canvas-v1:0",
        "arn:aws:bedrock:ap-northeast-1::foundation-model/amazon.nova-canvas-v1:0"
      ]
    }
  ]
}

可能であれば、このリストを 1 つのリージョンに絞ってください。モデルの検出、カスタマイズ、S3、KMS、ログ記録、ウォーターマーク検出の操作には個別の権限が必要です。推論ロールの権限を事前に広げてはいけません。

公式のタスクを選択する

現在のリクエスト/レスポンススキーマに記載されたタスクタイプのみを使用してください。

目標taskTypeパラメータオブジェクト主な入力
テキストから画像を生成TEXT_IMAGEtextToImageParamstext。negativeText、styleは任意
レイアウト/構図の条件付けTEXT_IMAGEtextToImageParamsconditionImageを追加。controlMode、controlStrengthは任意
パレットの指定COLOR_GUIDED_GENERATIONcolorGuidedGenerationParamscolors、text。referenceImage、negativeTextは任意
参照画像のバリエーションIMAGE_VARIATIONimageVariationParamsimages。text、negativeText、similarityStrengthは任意または曖昧
領域の置換/削除INPAINTINGinPaintingParamsimage、maskPrompt/maskImageのいずれか一方のみ。生成テキストは任意
領域外の拡張/置換OUTPAINTINGoutPaintingParamsimage、マスクはいずれか一方のみ。outPaintingMode、生成テキストは任意
前景の切り抜きBACKGROUND_REMOVALbackgroundRemovalParamsimageのみ
商品/衣服の試着VIRTUAL_TRY_ONvirtualTryOnParamssourceImage、referenceImage、マスクモードを1つ

アップスケーリング、画像から動画への変換、非同期ジョブ、ストリーミング、ドキュメントに記載された2つ以外のControlNet名、任意のスタイルID、OpenAI互換のルートを作り出してはいけません。

被写体の一貫性は、推論時のタスクタイプではありません。Canvasは以前、ファインチューニングをサポートしていましたが、基盤モデルがLegacyであるため、AWSは現在、新しいファインチューニングジョブを禁止しています。Legacyになる前に作成されたカスタムCanvasモデルのみ、限定的に文書化されたライフサイクルのルールに従って評価してください。それ以外の場合は、後継のIDを作り出さず、Activeな代替モデルを選択して検証してください。

共通スキーマを正確に適用する

BACKGROUND_REMOVAL以外のすべてのタスクでは、imageGenerationConfigは任意です。

{
  "width": 1024,
  "height": 1024,
  "quality": "standard",
  "cfgScale": 6.5,
  "seed": 12,
  "numberOfImages": 1
}
  • quality:standard(デフォルト)またはpremium。
  • cfgScale:1.1~10(両端を含む)。デフォルトは6.5です。まず4~7の範囲で試してください。
  • numberOfImages:1~5。デフォルトは1です。
  • seed:0~2,147,483,646。デフォルトは12です。実験やマニフェストでは固定してください。シードは比較に役立ちますが、サービスやモデルの更新をまたいでバイト単位で同一の出力を保証するものではありません。
  • widthとheight:デフォルトは1024です。編集入力に従って出力されるINPAINTING、OUTPAINTING、VIRTUAL_TRY_ONでは、両方とも省略してください。
  • BACKGROUND_REMOVALでは、設定オブジェクト全体を省略してください。

画像生成の寸法は、各辺が320~4096(両端を含む)で16の倍数、アスペクト比が1:4~4:1、かつ文書に記載されたピクセル上限以内であることを必須とします。境界値については、AWSが公開している対応解像度の例を使うか、カナリアテストを行ってください。ピクセル数がちょうど4,194,304の場合に受け付けられるかどうかについて、AWSのページ間で記述が一致していません。

入力画像は、8-bit RGBのBase64エンコードされたPNGまたはJPEGである必要があります。PNGにはアルファチャンネルを含められますが、入力ピクセルを透明または半透明にすることはできません。入力画像の寸法にも、各辺、アスペクト比、ピクセル数のルールが適用されますが、各辺は16の倍数でなくてもかまいません。エンコード前にローカルで検証してください。

タスク固有のペイロード

各 <BASE64_...> プレースホルダーを、データ URL ではなく Base64 エンコードされた画像バイト列に置き換えてください。

任意の条件指定を伴うテキストから画像への生成:

{
  "taskType": "TEXT_IMAGE",
  "textToImageParams": {
    "text": "Editorial product photograph of a ceramic teapot on pale oak, soft window light, three-quarter view",
    "negativeText": "text, watermark, duplicate objects, distorted handle",
    "style": "PHOTOREALISM",
    "conditionImage": "<BASE64_PNG_OR_JPEG>",
    "controlMode": "CANNY_EDGE",
    "controlStrength": 0.7
  },
  "imageGenerationConfig": {
    "width": 1024,
    "height": 1024,
    "quality": "standard",
    "cfgScale": 6.5,
    "seed": 24816,
    "numberOfImages": 1
  }
}

テキストから画像への生成のみを行う場合は、3 つの条件指定フィールドを省略してください。controlMode は CANNY_EDGE(デフォルト)または SEGMENTATION、controlStrength は 0~1(デフォルトは 0.7)です。ドキュメントに記載されている 8 つの style 値は次のとおりです。

3D_ANIMATED_FAMILY_FILM、DESIGN_SKETCH、FLAT_VECTOR_ILLUSTRATION、GRAPHIC_NOVEL_ILLUSTRATION、MAXIMALISM、MIDCENTURY_RETRO、PHOTOREALISM、SOFT_DIGITAL_PAINTING。

色を指定した生成:

{
  "taskType": "COLOR_GUIDED_GENERATION",
  "colorGuidedGenerationParams": {
    "colors": ["#16324F", "#E8C547", "#F7F4EA"],
    "text": "Flat editorial illustration of a harbor market at sunrise",
    "negativeText": "gradients, text, logo"
  },
  "imageGenerationConfig": {
    "width": 1536,
    "height": 1024,
    "quality": "standard",
    "cfgScale": 6.5,
    "seed": 7301,
    "numberOfImages": 1
  }
}

#RRGGBB 値を 1~10 個指定してください。省略可能な referenceImage は、指定した色と競合するとともに、独自の色を生成に反映します。

画像のバリエーション:

{
  "taskType": "IMAGE_VARIATION",
  "imageVariationParams": {
    "images": ["<BASE64_REFERENCE_1>", "<BASE64_REFERENCE_2>"],
    "similarityStrength": 0.7,
    "text": "Studio product photograph, centered composition",
    "negativeText": "text, extra products"
  },
  "imageGenerationConfig": {
    "width": 1024,
    "height": 1024,
    "quality": "standard",
    "cfgScale": 6.5,
    "seed": 901,
    "numberOfImages": 1
  }
}

画像を 1~5 枚指定してください。similarityStrength は 0.2~1.0 で、値が低いほどバリエーションが大きくなります。AWS の概要では text は任意とされていますが、詳細なスキーマでは必須と記載されており、省略に関する無関係な説明も含まれています。正確なリージョンで認可済みのカナリアテストによって省略時の動作が確認されるまでは、本番環境で空でない text を指定してください。

インペインティング:

{
  "taskType": "INPAINTING",
  "inPaintingParams": {
    "image": "<BASE64_SOURCE>",
    "maskImage": "<BASE64_MASK>",
    "text": "A small matte-black table lamp",
    "negativeText": "cord, text"
  },
  "imageGenerationConfig": {
    "quality": "standard",
    "cfgScale": 6.5,
    "seed": 41,
    "numberOfImages": 1
  }
}

maskImage または maskPrompt のいずれか一方を使用し、両方を同時に指定しないでください。インペインティングマスクでは、純粋な黒のピクセルが変更され、純粋な白のピクセルが保護されます。AWS は text を必須としていますが、同じページには、省略するとマスクされたオブジェクトが削除されて背景が補完されるとも記載されています。置き換えには text を指定し、削除目的で省略する場合は、テスト済みの方法のみを使用してください。

アウトペインティング:

{
  "taskType": "OUTPAINTING",
  "outPaintingParams": {
    "image": "<BASE64_SOURCE>",
    "maskPrompt": "ceramic teapot",
    "outPaintingMode": "PRECISE",
    "text": "A ceramic teapot on a breakfast table in a bright Scandinavian kitchen",
    "negativeText": "text, duplicate teapot"
  },
  "imageGenerationConfig": {
    "quality": "standard",
    "cfgScale": 6.5,
    "seed": 42,
    "numberOfImages": 1
  }
}

DEFAULT は境界をなじませますが、背景を大きく変更するとハローが生じることがあります。PRECISE は境界をより厳密になぞります。明示的なアウトペインティングマスクを指定する場合、詳細な入力ガイドでは白いピクセルが変更されると説明されています。AWS のスキーマに関する記述では、ほかの箇所で白黒の説明に一貫性がありません。そのため、統合テストに小さな視覚的テストデータを含め、極性が記録されていないマスクは拒否してください。

背景の削除:

{
  "taskType": "BACKGROUND_REMOVAL",
  "backgroundRemovalParams": {"image": "<BASE64_SOURCE>"}
}

8 ビットの透明度を持つ PNG が 1 枚生成されることを想定してください。デコードした画像にアルファチャンネルがあることを確認し、imageGenerationConfig は追加しないでください。

バーチャル試着:

{
  "taskType": "VIRTUAL_TRY_ON",
  "virtualTryOnParams": {
    "sourceImage": "<BASE64_PERSON_OR_SCENE>",
    "referenceImage": "<BASE64_PRODUCT>",
    "maskType": "GARMENT",
    "garmentBasedMask": {
      "maskShape": "BOUNDING_BOX",
      "garmentClass": "UPPER_BODY",
      "garmentStyling": {"outerLayerStyle": "OPEN"}
    },
    "maskExclusions": {
      "preserveBodyPose": "ON",
      "preserveHands": "ON",
      "preserveFace": "ON"
    },
    "mergeStyle": "BALANCED",
    "returnMask": true
  },
  "imageGenerationConfig": {
    "quality": "standard",
    "cfgScale": 6.5,
    "seed": 43,
    "numberOfImages": 1
  }
}

バーチャル試着では text と negativeText はサポートされていません。マスクの分岐は次のいずれか 1 つだけを選択してください。

  • IMAGE + imageBasedMask.maskImage。
  • GARMENT + garmentBasedMask.garmentClass。ドキュメントに記載された衣服のクラスと、適用可能なスタイリングの指定のみを使用してください。
  • PROMPT + promptBasedMask.maskPrompt。置き換え対象と元画像のシルエットが異なる場合は、BOUNDING_BOX を推奨します。

マスク外のピクセルを維持するには BALANCED、継ぎ目を減らしながらすべてのピクセルをわずかに変化させてもよい場合は SEAMLESS、継ぎ目が目立つリスクがあっても細かいロゴやテキストを重視する場合は DETAILED を選択してください。サイズやフィットが正確であるかのように結果を表現しないでください。AWS は、フィットの精度は保証されないと明記しています。

画像キャプションとしてプロンプトを作成する

被写体、動作、場所、構図、カメラ/視点、照明、配色、表現手法を説明する、簡潔な英語のキャプションを記述してください。望ましくない概念は、negativeText に名詞またはフレーズとして記述してください。どちらのフィールドでも no、not、without は避けてください。「award winning」、「4K」、「best quality」などの文言で水増ししないでください。

短いシーンテキストは二重引用符で囲み、その後、手動で確認してください。Nova Canvas は、一貫性のあるタイポグラフィの生成が得意ではありません。法的な文言、価格、ロゴ、UI テキストなど正確さが求められる要素は、後工程で決定論的なグラフィックツールを使って合成してください。

各フィールドの文字数は、肯定側と否定側それぞれ 1~1024 文字にしてください。2025 年のサービスカードには、2 つのフィールドを合計して上限 1,024 文字と記載されていますが、現在の API ページでは各フィールドの上限が 1,024 文字と説明されています。リージョン固有のカナリアテストで別の結果が確認されない限り、より保守的な合計上限を使用してください。

範囲を限定し、来歴を保持する Python 呼び出しを使用する

boto3 と Pillow をインストールし、スクリプトの外部で認証情報を設定します。有料推論の承認を得てから実行してください。この例では、テキストから画像へのリクエストを 1 回実行し、レスポンスを検証したうえで、元の PNG/JPEG バイトをアトミックに書き込み、機密情報を含まないマニフェストを作成します。

from __future__ import annotations

import argparse
import base64
import binascii
import hashlib
import io
import json
import os
import sys
import tempfile
from datetime import datetime, timezone
from pathlib import Path

import boto3
from botocore.config import Config
from botocore.exceptions import BotoCoreError, ClientError
from PIL import Image, UnidentifiedImageError

MODEL_ID = "amazon.nova-canvas-v1:0"
ALLOWED_REGIONS = {"us-east-1", "eu-west-1", "ap-northeast-1"}
MAX_RESPONSE_BYTES = 25_000_000
MAX_REQUEST_BYTES = 25_000_000
MAX_DECODED_IMAGE_BYTES = 20_000_000
Image.MAX_IMAGE_PIXELS = 20_000_000


def atomic_write(path: Path, data: bytes) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    temp_name = None
    try:
        with tempfile.NamedTemporaryFile(dir=path.parent, delete=False) as handle:
            temp_name = handle.name
            handle.write(data)
            handle.flush()
            os.fsync(handle.fileno())
        os.replace(temp_name, path)
    finally:
        if temp_name and os.path.exists(temp_name):
            os.unlink(temp_name)


def validate_dimensions(width: int, height: int) -> None:
    if not (320 <= width <= 4096 and 320 <= height <= 4096):
        raise ValueError("Each side must be between 320 and 4096 pixels")
    if width % 16 or height % 16:
        raise ValueError("Each generation dimension must be divisible by 16")
    if max(width / height, height / width) > 4:
        raise ValueError("Aspect ratio must be between 1:4 and 4:1")
    # Conservative because AWS pages disagree at the exact 4,194,304 boundary.
    if width * height > 4_194_304:
        raise ValueError("Pixel count exceeds the documented Canvas limit")


def decode_and_inspect(encoded: str) -> tuple[bytes, str, tuple[int, int]]:
    try:
        raw = base64.b64decode(encoded, validate=True)
    except (binascii.Error, ValueError) as exc:
        raise ValueError("Response image is not strict base64") from exc
    if not raw or len(raw) > MAX_DECODED_IMAGE_BYTES:
        raise ValueError("Decoded image is empty or exceeds the local safety cap")
    try:
        with Image.open(io.BytesIO(raw)) as probe:
            fmt = probe.format
            size = probe.size
            probe.verify()
        with Image.open(io.BytesIO(raw)) as probe:
            probe.load()
    except (UnidentifiedImageError, OSError, Image.DecompressionBombError) as exc:
        raise ValueError("Decoded bytes are not a valid bounded image") from exc
    if fmt not in {"PNG", "JPEG"}:
        raise ValueError(f"Unexpected response image format: {fmt}")
    if size[0] * size[1] > 4_194_304:
        raise ValueError(f"Unexpected response dimensions: {size}")
    return raw, fmt.lower().replace("jpeg", "jpg"), size


def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("prompt")
    parser.add_argument("--negative", default="text, watermark, distorted anatomy")
    parser.add_argument("--region", default=os.getenv("AWS_REGION", "us-east-1"))
    parser.add_argument("--width", type=int, default=1024)
    parser.add_argument("--height", type=int, default=1024)
    parser.add_argument("--seed", type=int, default=12)
    parser.add_argument("--quality", choices=("standard", "premium"), default="standard")
    parser.add_argument("--output", type=Path, default=Path("nova-canvas-output"))
    parser.add_argument("--store-prompt", action="store_true")
    args = parser.parse_args()

    if args.region not in ALLOWED_REGIONS:
        raise ValueError("Nova Canvas is not documented for that In-Region endpoint")
    validate_dimensions(args.width, args.height)
    if not (0 <= args.seed <= 2_147_483_646):
        raise ValueError("Seed is outside the documented range")
    if not (1 <= len(args.prompt) <= 1024 and 1 <= len(args.negative) <= 1024):
        raise ValueError("Prompt fields must each contain 1-1024 characters")
    if len(args.prompt) + len(args.negative) > 1024:
        raise ValueError("Conservative combined prompt cap exceeded")

    payload = {
        "taskType": "TEXT_IMAGE",
        "textToImageParams": {
            "text": args.prompt,
            "negativeText": args.negative,
        },
        "imageGenerationConfig": {
            "width": args.width,
            "height": args.height,
            "quality": args.quality,
            "cfgScale": 6.5,
            "seed": args.seed,
            "numberOfImages": 1,
        },
    }
    request_body = json.dumps(payload, separators=(",", ":")).encode("utf-8")
    if len(request_body) > MAX_REQUEST_BYTES:
        raise ValueError("Serialized request exceeds the InvokeModel body limit")

    # Default to one paid attempt because InvokeModel has no client idempotency token.
    # Enable more attempts only behind an explicit duplicate-spend policy.
    client = boto3.client(
        "bedrock-runtime",
        region_name=args.region,
        config=Config(
            connect_timeout=10,
            read_timeout=300,
            retries={"mode": "standard", "total_max_attempts": 1},
        ),
    )

    try:
        response = client.invoke_model(
            modelId=MODEL_ID,
            contentType="application/json",
            accept="application/json",
            body=request_body,
        )
        body = response["body"].read(MAX_RESPONSE_BYTES + 1)
        if len(body) > MAX_RESPONSE_BYTES:
            raise ValueError("Response exceeds the InvokeModel API body limit")
        document = json.loads(body)
    except ClientError as exc:
        meta = exc.response.get("ResponseMetadata", {})
        error = exc.response.get("Error", {})
        print(
            f"Bedrock error code={error.get('Code')} status={meta.get('HTTPStatusCode')} "
            f"request_id={meta.get('RequestId')}",
            file=sys.stderr,
        )
        return 2
    except (BotoCoreError, json.JSONDecodeError, ValueError) as exc:
        print(f"Invocation/response failure: {type(exc).__name__}: {exc}", file=sys.stderr)
        return 3

    images = document.get("images")
    moderation_error = document.get("error")
    if not isinstance(images, list) or not images:
        print(f"No releasable image returned; moderation={moderation_error!r}", file=sys.stderr)
        return 4
    if len(images) != 1:
        print(f"Unexpected returned image count: {len(images)}", file=sys.stderr)
        return 4

    raw, extension, size = decode_and_inspect(images[0])
    output_path = args.output.with_suffix(f".{extension}")
    atomic_write(output_path, raw)  # Keep C2PA/watermark-bearing bytes unchanged.

    response_meta = response.get("ResponseMetadata", {})
    manifest = {
        "created_at": datetime.now(timezone.utc).isoformat(),
        "model_id": MODEL_ID,
        "region": args.region,
        "task_type": payload["taskType"],
        "config": payload["imageGenerationConfig"],
        "prompt_sha256": hashlib.sha256(args.prompt.encode()).hexdigest(),
        "negative_sha256": hashlib.sha256(args.negative.encode()).hexdigest(),
        "prompt": args.prompt if args.store_prompt else None,
        "negative_text": args.negative if args.store_prompt else None,
        "aws_request_id": response_meta.get("RequestId"),
        "moderation_notice": moderation_error,
        "output_file": output_path.name,
        "output_format": extension,
        "output_dimensions": list(size),
        "output_sha256": hashlib.sha256(raw).hexdigest(),
    }
    atomic_write(
        output_path.with_suffix(output_path.suffix + ".manifest.json"),
        json.dumps(manifest, indent=2, sort_keys=True).encode(),
    )
    print(output_path)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())

検証のためだけに返された画像を再度開いて保存しないでください。一般的な画像ライブラリは C2PA メタデータを削除することがあります。まず元のバイトをハッシュ化してアーカイブしてください。後続の変換が必要な場合は、元の画像を保持し、派生関係を記録し、該当する AWS の規約に従って来歴を保持してください。

モデレーション、サービスエラー、リトライを慎重に扱う

Canvas には 2 種類のエラーチャネルがあります。

  • リクエストの検証エラー、または安全でないテキスト/画像入力:HTTP 400 ValidationException。変更せずにリトライしないでください。通常のスキーマエラーと Canvas のコンテンツフィルターによるメッセージを区別しますが、フィルターを回避しようとしてはいけません。
  • 生成結果が安全でない場合:HTTP 200 でも、リクエストした数より少ない images と、一部またはすべての画像がブロックされたことを示す error 文字列が含まれることがあります。件数の不一致と error は、通信の成功ではなくモデレーションの結果として扱ってください。

InvokeModel API では、AccessDeniedException(403)、ResourceNotFoundException(404)、ModelTimeoutException(408)、ModelErrorException(424)、ThrottlingException/ModelNotReadyException(429)、InternalServerException(500)、ServiceUnavailableException(503)も記載されています。

429 と 503 には、ジッターを加えた指数バックオフを使用し、総試行回数を少数に制限して、アカウントのクォータを下回る同時実行数制限を設けてください。400、403、404 は変更せずにリトライしないでください。接続リセットやタイムアウトが発生した場合、サービス側では処理が完了し、画像の料金が発生している可能性があります。また、InvokeModel にはクライアントの冪等性トークンがありません。エスカレーションするか、重複料金に関する明示的なポリシーに従ってリトライしてください。診断には同じシード/設定を使用しますが、これによって 2 回目の料金が発生しないとは限りません。

AWS が Canvas に推奨しているとおり、read_timeout は少なくとも 300 秒に設定してください。特に、プレミアム品質、高解像度、または複数画像の場合は重要です。接続タイムアウトは大幅に短くしてください。

HTTP ステータスだけでなく、本番環境での出力を検証する

返された画像ごとに、以下を行います。

  1. サイズ上限を設けた JSON ボディと、厳密な base64 を要求します。
  2. 上限を設けてバイトにデコードし、実際の画像形式と寸法を検証します。
  3. リリース可能な画像が意図した数だけあることを確認します。HTTP 200 でも error を確認してください。
  4. 背景を削除する場合は、意味のあるアルファチャンネルを持つ PNG を要求し、被写体の輪郭を確認したうえで、明るい背景、暗い背景、チェッカーボード背景への合成をテストします。
  5. 編集では、選択したモードが保持を保証する領域をピクセル単位で比較し、継ぎ目、ハロー、被写体の同一性、手や顔、製品の表記、形状を確認します。
  6. 用途に応じた評価基準を使って、プロンプトへの準拠、オブジェクトの数、カメラ/視点、色調、解剖学的正確さ、事実/製品に関する主張、シーン内のテキスト、保護対象の特性、禁止コンテンツを検証します。
  7. 公開用、商用、肖像に関わるもの、影響の大きいもの、または規制対象のコンテンツは、適格な人間のレビュー担当者に回してください。
  8. 元のバイト、リクエスト ID、モデル ID、リージョン、タスク、設定、シード、ハッシュ、モデレーションの結果、レビュー判断、親画像/派生画像の関係を保持します。
  9. シード、タスクの種類、人口統計、エッジケース、既知の失敗を網羅する固定の回帰テストセットを維持し、モデル/サービスの更新後に再テストします。

ウォーターマークの検証に成功しても、作成者、真実性、同意、権利が証明されたと主張しないでください。画像が変更されていると、ウォーターマーク検出の精度が低下することがあります。

呼び出し前にコストとクォータを管理する

AWS は Canvas の料金を、解像度の範囲と品質に基づいて生成画像ごとに設定しています。Bedrock の料金ページは動的に更新されるため、ジョブを見積もる、または実行する直前に、ページとアカウントの実際の Legacy アクセスに対する請求額を再確認してください。AWS のライフサイクルポリシーによると、パブリックな延長アクセスではプロバイダーが設定する料金が高くなる場合があります。そのため、以下の静的な表は Legacy アカウントの現在の料金を示すものではありません。2026-07-09 に確認したスナップショット:

出力範囲標準プレミアム
1024×1024 以下$0.04/画像$0.06/画像
2048×2048 以下$0.06/画像$0.08/画像

要求画像数 × 単価 × 試行回数を見積もり、ストレージ、転送、ログ記録、レビュー、派生画像の処理、カスタムモデルの料金を加算してください。モデレーション、失敗、再試行によって請求総額が変わる場合があります。保存した画像だけが課金対象になると想定せず、AWS Cost Explorer/Budgets と実際の請求データを使用してください。バッチ処理の前に、画像数、試行回数、同時実行数、支出額に厳格な上限を設定してください。

Bedrock のクォータ表には現在、サポート対象リージョンごとに、オンデマンドの Nova Canvas リクエストは 1 分あたり 100 件と記載されており、変更不可とされています。AWS は、アカウントによってクォータが異なる場合があると説明しています。Service Quotas を照会し、アカウントとリージョンで実際に発生するスロットリングを確認してください。より小さい方の値を下回るようにレートを制限してください。1 回のリクエストで 5 枚の画像を生成する場合、リクエスト数としては 1 件ですが、画像生成のコストは 5 枚分になり、処理時間も長くなる可能性があります。

基本の Nova Canvas はプロビジョンドスループットに対応していません。この Legacy モデルの新しいファインチューニングジョブや、新しいプロビジョンドスループットのエンドポイントは作成しないでください。Legacy になる前に作成されたカスタム Canvas モデルは、AWS のライフサイクルルールに基づき、既存のデプロイを継続するか、新しいオンデマンドのカスタムデプロイを利用できる場合があります。過去のファインチューニングに関するドキュメントから一般化せず、該当するリソースと構成を確認してください。

プライバシー、権利、安全性、来歴を保護する

  • すべてのプロンプト、ソース、参照画像、マスク、ロゴ、衣服/製品の画像、および人物の肖像を使用する権利を取得してください。実在する人物の加工、生体情報の処理、デジタルレプリカの作成については、適切な同意を得てください。バーチャル試着は、人物の画像を変更する許可を意味するものではありません。
  • 適用される法律またはAWS Responsible AI Policyで禁止されている行為に、出力を使用しないでください。設定で無効にできない Canvas の安全フィルターを回避しようとしないでください。
  • 出力は確率的なドラフトとして扱ってください。製品を誤って表現したり、見えていない面を幻覚したり、解剖学的形状を歪めたり、バイアスを持ち込んだり、誤ったテキストを描画したりする可能性があります。証拠として、または重大な意思決定の唯一の根拠として使用しないでください。
  • 承認済みのデータ分類、リージョン、保持期間、アクセス、暗号化、インシデント対応の管理策で許可されていない限り、機密データをプロンプトや参照画像に含めないでください。モデル呼び出しのログ記録を無効にするか、保護してください。有効にすると、リクエスト/レスポンス全体が顧客管理のログまたは S3 にコピーされる可能性があります。
  • 現在のCanvas サービスカードによると、Bedrock は Canvas の入力または出力を Bedrock モデルのトレーニングに使用せず、顧客間またはサードパーティのモデルプロバイダーと共有しません。AWS の新しい不正使用検出のドキュメントでは、モデル固有の例外を設ける可能性を留保しつつ、デフォルトでデータを保持しないと説明されています。機密データを処理する前に両方の情報を再確認し、適用される契約を文書化してください。
  • 所有権や、権利侵害がないことを約束しないでください。弁護士とともに、現行の AWS 契約、サービス規約、適用されるライセンス、現地法を確認してください。サービスカードには、AWS サービス規約に記載された条件に従い、一般提供されている Nova の出力に対する知的財産の補償が記載されていますが、これは権利確認の代わりにはなりません。
  • Canvas は、生成画像に不可視のウォーターマークと、モデル/プラットフォーム/タスクの来歴を含む C2PA Content Credentials を追加します。これらを保持してください。現行の AWS サービス規約では、生成時の来歴データを削除または変更することが禁止されています。
  • メタデータが削除されていなければ、Content Credentials Verify で Content Credentials を検査できます。Canvas の AWS ウォーターマーク検出は現在プレビューで、us-east-1 と us-west-2 で利用でき、最大 18 MB の JPEG/PNG に対応します。また、編集後は精度が低下する可能性があります。バージョン管理とフォールバックの対策なしに、プレビュー API にコンプライアンスの確実な依存関係を構築しないでください。

過去のカスタムモデルにゲートを設ける

新たに Canvas のファインチューニングプロジェクトを開始しないでください。AWS の現行ライフサイクルポリシーでは、基盤モデルが Legacy に移行した後、新しいカスタマイズジョブが禁止されています。組織が 2026-03-30 の Legacy 移行日より前に Canvas カスタムモデルを作成していた場合は、トレーニングの承認、IAM ロール、S3/KMS の管理策、評価記録、現在のデプロイ、課金、削除/保持義務、EOL 移行計画を棚卸ししてください。AWS によると、そのような既存のカスタムモデルでは、既存のオンデマンドデプロイまたは Legacy 移行前の Provisioned Throughput エンドポイントを継続利用でき、新しいオンデマンドのカスタムデプロイを作成できます。一方、新しいファインチューニングジョブや新しい Provisioned Throughput エンドポイントは作成できません。

新たに被写体の一貫性が必要な場合は、カスタマイズを現在サポートしている Active モデルを探し、個別に検証したうえで、プロバイダー/モデルの変更前に承認を得てください。Nova Canvas の後継モデルを推測したり、過去の Canvas ハイパーパラメーターを別のモデルにそのまま移植したりしないでください。

既知のドキュメント間の矛盾を記録する

現在確認されている以下の AWS の不一致を、黙って解消しないでください。

  • 画像のバリエーション:概要では text は任意とされていますが、詳細なスキーマでは必須とされ、インペインティングに関する説明も含まれています。省略が許可されることを認定済みのカナリアテストで確認できない限り、text を含めてください。
  • プロンプトの長さ:スキーマでは、ポジティブフィールドとネガティブフィールドのそれぞれに 1~1024 文字とされていますが、2025 年のサービスカードでは合計 1,024 文字とされています。デフォルトでは、より厳しい合計上限を適用してください。
  • ピクセルの境界:概要では 2048×2048 が有効とされ、編集では 419 万ピクセル以下が許可されています。一方、詳細な入力ガイドでは、総ピクセル数は 4,194,304 未満でなければならないとされています。公開済みの例とカナリアテストの境界値を優先してください。
  • アウトペインティングのマスク:専用の入力ガイドでは白いピクセルが変更されるとされていますが、スキーマの説明では、インペインティングとアウトペインティングは逆であると述べる前に、黒い部分が変更されるという説明が繰り返されています。フィクスチャーテストで極性を確定してください。
  • シード:現在のスキーマでは 0~2,147,483,646 が許可されていますが、一部の公式 SDK の例では、より小さい 0~858,993,459 の範囲が引き続き記載されています。スキーマの範囲を使用するか、最大限の後方互換性が必要な場合は、より小さい範囲を使用してください。
  • プロビジョンドスループット:ベースモデルのページではサポート対象外とされています。また、過去のファインチューニング資料ではカスタマイズ済み Canvas のプロビジョンドサービングが説明されていますが、現行のライフサイクルポリシーでは、Legacy 以降の新しい Provisioned Throughput エンドポイントが禁止されています。継続利用の対象として扱うのは、Legacy より前に作成された条件を満たすカスタムリソースのみとしてください。

境界値が重要な場合は、ソース URL、取得日、リージョン、正確なペイロード、応答ステータス/メッセージ、SDK のバージョン、AWS リクエスト ID を保存してください。ライフサイクルまたはドキュメントが変更された後は、再検証してください。

主な情報源

上記の変動する情報はすべて、2026-07-09 に以下の AWS 公式情報源で確認しました。

コメント