生成された出力を制御する

モデルの生成済み出力が常に特定のスキーマに準拠するように保証することで、一貫した形式のレスポンスを受信できます。たとえば、他のタスクで使用する確立したデータ スキーマがあるとします。モデルがこのスキーマに従っている場合、後処理なしでモデルの出力からデータを直接抽出できます。

モデルの出力の構造を指定するには、レスポンス スキーマを定義します。これは、モデルのレスポンスのブループリントのように機能します。プロンプトを送信してレスポンス スキーマを含めると、モデルのレスポンスは常に定義されたスキーマに従います。

生成済み出力を制御できるのは、Gemini 1.5 Pro だけです。

サンプル ユースケース

レスポンス スキーマを適用するユースケースの 1 つとして、モデルのレスポンスが有効な JSON を生成し、スキーマに準拠しているかを確認することが挙げられます。生成モデルの出力にはある程度のばらつきがあるため、レスポンス スキーマを含めることで、常に有効な JSON を受け取ることができます。したがって、下流のタスクは、生成されたレスポンスから有効な JSON 入力が得られることを確実に予測できます。

別の例として、モデルの応答方法を制限することが挙げられます。たとえば、モデルが生成したラベルではなく、ユーザー定義のラベルでテキストに注釈を付けることができます。この制約は、positivenegative などの特定のラベルセットを想定しており、goodbad などの他のラベルを混在させたくない場合に有用です。

考慮事項

レスポンス スキーマを使用する場合の制限事項について、次の考慮事項で説明します。

  • サポートされている出力形式は JSON のみです。
  • レスポンス スキーマの定義や使用には、API を使用する必要があります。コンソール サポートはありません。
  • レスポンス スキーマは、入力トークンの上限まで数えられます。

始める前に

レスポンス スキーマを定義して、モデルの出力の構造、フィールド名、各フィールドの想定されるデータ型を指定します。Vertex AI は、OpenAPI 3.0 スキーマ オブジェクトのサブセットを使用します。詳細については、Vertex AI スキーマ リファレンスをご覧ください。

例については、スキーマとモデル レスポンスの例をご覧ください。

モデルの動作とレスポンス スキーマ

モデルがレスポンスを生成するときは、プロンプトからフィールド名とコンテキストを使用します。そのため、意図が明確になるように、明確な構造と曖昧さのないフィールド名を使用することをおすすめします。

デフォルトでは、フィールドは省略可能です。つまり、モデルはフィールドにデータを入力することも、フィールドをスキップすることもできます。フィールドを必須として設定すると、モデルに値を提供させることができます。関連する入力プロンプトに十分なコンテキストがない場合、モデルは主にトレーニングに使用されたデータに基づいてレスポンスを生成します。

期待どおりの結果が表示されない場合は、入力プロンプトにコンテキストを追加するか、レスポンス スキーマを修正します。たとえば、生成制御なしでモデルのレスポンスを確認して、モデルがどのように応答するかを確認します。その後、モデルの出力により適したレスポンス スキーマを更新できます。

レスポンス スキーマを含むプロンプトを送信する

デフォルトでは、すべてのフィールドは省略可能です。つまり、モデルはフィールドに対するレスポンスを生成できます。モデルでフィールドに対するレスポンスを常に強制的に生成させるには、フィールドを必須として設定します。

Python

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Python の設定手順を完了してください。詳細については、Vertex AI Python API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import vertexai

from vertexai.generative_models import GenerationConfig, GenerativeModel

# TODO(developer): Update and un-comment below line
# project_id = "PROJECT_ID"
vertexai.init(project=project_id, location="us-central1")

response_schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "recipe_name": {
                "type": "string",
            },
        },
        "required": ["recipe_name"],
    },
}

model = GenerativeModel("gemini-1.5-pro-001")

response = model.generate_content(
    "List a few popular cookie recipes",
    generation_config=GenerationConfig(
        response_mime_type="application/json", response_schema=response_schema
    ),
)

print(response.text)

REST

データをリクエストする前に、次のように置き換えます。

  • GENERATE_RESPONSE_METHOD: モデルに生成させるレスポンスのタイプ。モデルのレスポンスを返す方法を生成するメソッドを選択します。
    • streamGenerateContent: レスポンスは生成時にストリーミングされます。ユーザーが遅延を感じることは少なくなります。
    • generateContent: レスポンスは、完全に生成された後に返されます。
  • LOCATION: リクエストを処理するリージョン。
  • PROJECT_ID: 実際のプロジェクト ID
  • MODEL_ID: 使用するマルチモーダル モデルのモデル ID。次のオプションがあります。
    • gemini-1.5-pro
  • ROLE: コンテンツに関連付けられた会話におけるロール。単一ターンのユースケースでも、ロールの指定が必要です。指定できる値は以下のとおりです。
    • USER: 送信するコンテンツを指定します。
  • TEXT: プロンプトに含める指示のテキスト。
  • RESPONSE_SCHEMA: レスポンスの生成時に従うモデルのスキーマ。詳細については、スキーマのリファレンスをご覧ください。

HTTP メソッドと URL:

POST https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:GENERATE_RESPONSE_METHOD

リクエストの本文(JSON):

{
  "contents": {
    "role": "ROLE",
    "parts": {
      "text": "TEXT"
    }
  },
  "generation_config": {
    "responseMimeType": "application/json",
    "responseSchema": RESPONSE_SCHEMA,
  }
}

リクエストを送信するには、次のいずれかのオプションを選択します。

curl

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:GENERATE_RESPONSE_METHOD"

PowerShell

リクエスト本文を request.json という名前のファイルに保存して、次のコマンドを実行します。

$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }

Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/publishers/google/models/MODEL_ID:GENERATE_RESPONSE_METHOD" | Select-Object -Expand Content

次のような JSON レスポンスが返されます。

curl コマンドの例

LOCATION="us-central1"
MODEL_ID="gemini-1.0-pro"
PROJECT_ID="test-project"
GENERATE_RESPONSE_METHOD="generateContent"

cat << EOF > request.json
{
  "contents": {
    "role": "user",
    "parts": {
      "text": "List a few popular cookie recipes."
    }
  },
  "generation_config": {
    "maxOutputTokens": 2048,
    "responseMimeType": "application/json",
    "responseSchema": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "recipe_name": {
            "type": "string",
          },
        },
        "required": ["recipe_name"],
      },
    }
  }
}
EOF

curl \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/publishers/google/models/${MODEL_ID}:${GENERATE_RESPONSE_METHOD} -d \
-d `@request.json`

スキーマとモデルのレスポンスの例

以降のセクションでは、さまざまなプロンプトとレスポンス スキーマの例を示します。各コードサンプルの後に、モデル レスポンスのサンプルも記載されています。

レビュー評価を要約する

次の例では、オブジェクトの配列を出力します。ここでは、各オブジェクトに、評価とアイスクリームのフレーバーの名前という 2 つのプロパティがあります。

Python

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Python の設定手順を完了してください。詳細については、Vertex AI Python API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import vertexai

from vertexai.generative_models import GenerationConfig, GenerativeModel

# TODO(developer): Update and un-comment below line
# project_id = "PROJECT_ID"
vertexai.init(project=project_id, location="us-central1")

response_schema = {
    "type": "ARRAY",
    "items": {
        "type": "ARRAY",
        "items": {
            "type": "OBJECT",
            "properties": {
                "rating": {"type": "INTEGER"},
                "flavor": {"type": "STRING"},
            },
        },
    },
}

prompt = """
    Reviews from our social media:

    - "Absolutely loved it! Best ice cream I've ever had." Rating: 4, Flavor: Strawberry Cheesecake
    - "Quite good, but a bit too sweet for my taste." Rating: 1, Flavor: Mango Tango
"""

model = GenerativeModel("gemini-1.5-pro-001")

response = model.generate_content(
    prompt,
    generation_config=GenerationConfig(
        response_mime_type="application/json", response_schema=response_schema
    ),
)

print(response.text)

モデルのレスポンスの例

candidates {
  content {
    role: "model"
    parts {
      text: "[\n    [\n        {\n            \"rating\": 4\n        },\n        {\n            \"flavor\": \"Strawberry Cheesecake\"\n        },\n        {\n            \"rating\": 1\n        },\n        {\n            \"flavor\": \"Mango Tango\"\n        }\n    ]\n] "
    }
  }
  finish_reason: STOP
  safety_ratings {
    category: HARM_CATEGORY_HATE_SPEECH
    probability: NEGLIGIBLE
    probability_score: 0.1139734759926796
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.10070161521434784
  }
  safety_ratings {
    category: HARM_CATEGORY_DANGEROUS_CONTENT
    probability: NEGLIGIBLE
    probability_score: 0.13695430755615234
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.12241825461387634
  }
  safety_ratings {
    category: HARM_CATEGORY_HARASSMENT
    probability: NEGLIGIBLE
    probability_score: 0.11676400154829025
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.05310790613293648
  }
  safety_ratings {
    category: HARM_CATEGORY_SEXUALLY_EXPLICIT
    probability: NEGLIGIBLE
    probability_score: 0.10521054267883301
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.08299414813518524
  }
}
usage_metadata {
  prompt_token_count: 61
  candidates_token_count: 66
  total_token_count: 127
}

曜日ごとの天気を予測する

次の例では、1 週間の各曜日の forecast オブジェクトを出力します。このオブジェクトには、その日の予想気温や湿度などのプロパティの配列が含まれます。

Python

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Python の設定手順を完了してください。詳細については、Vertex AI Python API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import vertexai

from vertexai.generative_models import GenerationConfig, GenerativeModel

# TODO(developer): Update and un-comment below line
# project_id = "PROJECT_ID"
vertexai.init(project=project_id, location="us-central1")

response_schema = {
    "type": "OBJECT",
    "properties": {
        "forecast": {
            "type": "ARRAY",
            "items": {
                "type": "OBJECT",
                "properties": {
                    "Day": {"type": "STRING"},
                    "Forecast": {"type": "STRING"},
                    "Humidity": {"type": "STRING"},
                    "Temperature": {"type": "INTEGER"},
                    "Wind Speed": {"type": "INTEGER"},
                },
                "required": ["Day", "Temperature", "Forecast"],
            },
        }
    },
}

prompt = """
    The week ahead brings a mix of weather conditions.
    Sunday is expected to be sunny with a temperature of 77°F and a humidity level of 50%. Winds will be light at around 10 km/h.
    Monday will see partly cloudy skies with a slightly cooler temperature of 72°F and humidity increasing to 55%. Winds will pick up slightly to around 15 km/h.
    Tuesday brings rain showers, with temperatures dropping to 64°F and humidity rising to 70%. Expect stronger winds at 20 km/h.
    Wednesday may see thunderstorms, with a temperature of 68°F and high humidity of 75%. Winds will be gusty at 25 km/h.
    Thursday will be cloudy with a temperature of 66°F and moderate humidity at 60%. Winds will ease slightly to 18 km/h.
    Friday returns to partly cloudy conditions, with a temperature of 73°F and lower humidity at 45%. Winds will be light at 12 km/h.
    Finally, Saturday rounds off the week with sunny skies, a temperature of 80°F, and a humidity level of 40%. Winds will be gentle at 8 km/h.
"""

model = GenerativeModel("gemini-1.5-pro-001")

response = model.generate_content(
    prompt,
    generation_config=GenerationConfig(
        response_mime_type="application/json", response_schema=response_schema
    ),
)

print(response.text)

モデルのレスポンスの例

candidates {
  content {
    role: "model"
    parts {
      text: "{\"forecast\": [{\"Day\": \"Sunday\", \"Forecast\": \"Sunny\", \"Temperature\": 77, \"Humidity\": \n\"50\", \"Wind Speed\": 10}, {\"Day\": \"Monday\", \"Forecast\": \"Partly Cloudy\", \"Temperature\": 72, \"Humidity\": \"55\", \"Wind Speed\": 15}, {\"Day\": \"Tuesday\", \"Forecast\": \"Rain Showers\", \"Temperature\": 64, \"Humidity\": \"70\", \"Wind Speed\": 20}, {\"Day\": \"Wednesday\", \"Forecast\": \"Thunderstorms\", \"Temperature\": 68, \"Humidity\": \"75\", \"Wind Speed\": 25}, {\"Day\": \"Thursday\", \"Forecast\": \"Cloudy\", \"Temperature\": 66, \"Humidity\": \"60\", \"Wind Speed\": 18}, {\"Day\": \"Friday\", \"Forecast\": \"Partly Cloudy\", \"Temperature\": 73, \"Humidity\": \"45\", \"Wind Speed\": 12}, {\"Day\": \"Saturday\", \"Forecast\": \"Sunny\", \"Temperature\": 80, \"Humidity\": \"40\", \"Wind Speed\": 8}]} "
    }
  }
  finish_reason: STOP
  safety_ratings {
    category: HARM_CATEGORY_HATE_SPEECH
    probability: NEGLIGIBLE
    probability_score: 0.1037486344575882
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.09670579433441162
  }
  safety_ratings {
    category: HARM_CATEGORY_DANGEROUS_CONTENT
    probability: NEGLIGIBLE
    probability_score: 0.18126320838928223
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.10052486509084702
  }
  safety_ratings {
    category: HARM_CATEGORY_HARASSMENT
    probability: NEGLIGIBLE
    probability_score: 0.15960998833179474
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.09518112242221832
  }
  safety_ratings {
    category: HARM_CATEGORY_SEXUALLY_EXPLICIT
    probability: NEGLIGIBLE
    probability_score: 0.1388116478919983
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.10539454221725464
  }
}
usage_metadata {
  prompt_token_count: 280
  candidates_token_count: 249
  total_token_count: 529
}

商品を分類する

次の例では、モデルが特定の値のリストからオブジェクトのタイプと条件を分類する必要がある列挙型を使用しています。

Python

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Python の設定手順を完了してください。詳細については、Vertex AI Python API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import vertexai

from vertexai.generative_models import GenerationConfig, GenerativeModel

# TODO(developer): Update and un-comment below line
# project_id = "PROJECT_ID"
vertexai.init(project=project_id, location="us-central1")

response_schema = {
    "type": "ARRAY",
    "items": {
        "type": "OBJECT",
        "properties": {
            "to_discard": {"type": "INTEGER"},
            "subcategory": {"type": "STRING"},
            "safe_handling": {"type": "INTEGER"},
            "item_category": {
                "type": "STRING",
                "enum": [
                    "clothing",
                    "winter apparel",
                    "specialized apparel",
                    "furniture",
                    "decor",
                    "tableware",
                    "cookware",
                    "toys",
                ],
            },
            "for_resale": {"type": "INTEGER"},
            "condition": {
                "type": "STRING",
                "enum": [
                    "new in package",
                    "like new",
                    "gently used",
                    "used",
                    "damaged",
                    "soiled",
                ],
            },
        },
    },
}

prompt = """
    Item description:
    The item is a long winter coat that has many tears all around the seams and is falling apart.
    It has large questionable stains on it.
"""

model = GenerativeModel("gemini-1.5-pro-001")

response = model.generate_content(
    prompt,
    generation_config=GenerationConfig(
        response_mime_type="application/json", response_schema=response_schema
    ),
)

print(response.text)

モデルのレスポンスの例

candidates {
  content {
    role: "model"
    parts {
      text: " [{\n    \"item_category\": \"winter apparel\",\n    \"subcategory\": \"coat\",\n    \"to_discard\":  1\n  }] "
    }
  }
  finish_reason: STOP
  safety_ratings {
    category: HARM_CATEGORY_HATE_SPEECH
    probability: NEGLIGIBLE
    probability_score: 0.08945459872484207
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.13753245770931244
  }
  safety_ratings {
    category: HARM_CATEGORY_DANGEROUS_CONTENT
    probability: NEGLIGIBLE
    probability_score: 0.19208428263664246
    severity: HARM_SEVERITY_LOW
    severity_score: 0.23810701072216034
  }
  safety_ratings {
    category: HARM_CATEGORY_HARASSMENT
    probability: NEGLIGIBLE
    probability_score: 0.07585817575454712
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.04336579889059067
  }
  safety_ratings {
    category: HARM_CATEGORY_SEXUALLY_EXPLICIT
    probability: NEGLIGIBLE
    probability_score: 0.12667709589004517
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.07396338135004044
  }
}
usage_metadata {
  prompt_token_count: 38
  candidates_token_count: 33
  total_token_count: 71
}

画像内のオブジェクトを特定する

次の例では、Cloud Storage に保存されている 2 つの画像のオブジェクトを識別します。

Python

このサンプルを試す前に、Vertex AI クイックスタート: クライアント ライブラリの使用にある Python の設定手順を完了してください。詳細については、Vertex AI Python API のリファレンス ドキュメントをご覧ください。

Vertex AI に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証を設定するをご覧ください。

import vertexai

from vertexai.generative_models import GenerationConfig, GenerativeModel, Part

# TODO(developer): Update and un-comment below line
# project_id = "PROJECT_ID"
vertexai.init(project=project_id, location="us-central1")

response_schema = {
    "type": "ARRAY",
    "items": {
        "type": "ARRAY",
        "items": {
            "type": "OBJECT",
            "properties": {
                "object": {"type": "STRING"},
            },
        },
    },
}

model = GenerativeModel("gemini-1.5-pro-001")

response = model.generate_content(
    [
        Part.from_uri(
            "gs://cloud-samples-data/generative-ai/image/office-desk.jpeg",
            "image/jpeg",
        ),
        Part.from_uri(
            "gs://cloud-samples-data/generative-ai/image/gardening-tools.jpeg",
            "image/jpeg",
        ),
        "Generate a list of objects in the images.",
    ],
    generation_config=GenerationConfig(
        response_mime_type="application/json", response_schema=response_schema
    ),
)

print(response.text)

モデルのレスポンスの例

candidates {
  content {
    role: "model"
    parts {
      text: "[\n    [\n        {\n            \"object\": \"globe model\"\n        },\n        {\n            \"object\": \"tablet computer\"\n        },\n        {\n            \"object\": \"shopping cart\"\n        },\n        {\n            \"object\": \"Eiffel Tower model\"\n        },\n        {\n            \"object\": \"airplane model\"\n        },\n        {\n            \"object\": \"coffee cup\"\n        },\n        {\n            \"object\": \"computer keyboard\"\n        },\n        {\n            \"object\": \"computer mouse\"\n        },\n        {\n            \"object\": \"passport\"\n        },\n        {\n            \"object\": \"sunglasses\"\n        },\n        {\n            \"object\": \"US Dollar bills\"\n        },\n        {\n            \"object\": \"notepad\"\n        },\n        {\n            \"object\": \"pen\"\n        }\n    ],\n    [\n        {\n            \"object\": \"watering can\"\n        },\n        {\n            \"object\": \"oregano\"\n        },\n        {\n            \"object\": \"flower pot\"\n        },\n        {\n            \"object\": \"flower pot\"\n        },\n        {\n            \"object\": \"gardening gloves\"\n        },\n        {\n            \"object\": \"hand rake\"\n        },\n        {\n            \"object\": \"hand trowel\"\n        },\n        {\n            \"object\": \"grass\"\n        }\n    ]\n] "
    }
  }
  finish_reason: STOP
  safety_ratings {
    category: HARM_CATEGORY_HATE_SPEECH
    probability: NEGLIGIBLE
    probability_score: 0.1872812658548355
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.16357900202274323
  }
  safety_ratings {
    category: HARM_CATEGORY_DANGEROUS_CONTENT
    probability: LOW
    probability_score: 0.37920594215393066
    severity: HARM_SEVERITY_LOW
    severity_score: 0.29320207238197327
  }
  safety_ratings {
    category: HARM_CATEGORY_HARASSMENT
    probability: NEGLIGIBLE
    probability_score: 0.14175598323345184
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.12074951827526093
  }
  safety_ratings {
    category: HARM_CATEGORY_SEXUALLY_EXPLICIT
    probability: NEGLIGIBLE
    probability_score: 0.12241825461387634
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.0955180674791336
  }
}
usage_metadata {
  prompt_token_count: 525
  candidates_token_count: 333
  total_token_count: 858
}