Output terstruktur

Anda dapat mengonfigurasi Gemini untuk output terstruktur, bukan teks tidak terstruktur, sehingga memungkinkan ekstraksi dan standardisasi informasi yang akurat untuk pemrosesan lebih lanjut. Misalnya, Anda dapat menggunakan output terstruktur untuk mengekstrak informasi dari resume, menstandarkannya untuk membuat database terstruktur.

Gemini dapat menghasilkan JSON atau nilai enum sebagai output terstruktur.

Membuat JSON

Ada dua cara untuk membuat JSON menggunakan Gemini API:

  • Mengonfigurasi skema pada model
  • Memberikan skema dalam perintah teks

Mengonfigurasi skema pada model adalah cara yang direkomendasikan untuk membuat JSON, karena membatasi model untuk menghasilkan JSON.

Mengonfigurasi skema (direkomendasikan)

Untuk membatasi model agar menghasilkan JSON, konfigurasikan responseSchema. Model kemudian akan merespons perintah apa pun dengan output berformat JSON.

from google import genai
from pydantic import BaseModel

class Recipe(BaseModel):
    recipe_name: str
    ingredients: list[str]

client = genai.Client(api_key="GOOGLE_API_KEY")
response = client.models.generate_content(
    model="gemini-2.0-flash",
    contents="List a few popular cookie recipes, and include the amounts of ingredients.",
    config={
        "response_mime_type": "application/json",
        "response_schema": list[Recipe],
    },
)
# Use the response as a JSON string.
print(response.text)

# Use instantiated objects.
my_recipes: list[Recipe] = response.parsed
import { GoogleGenAI, Type } from "@google/genai";

const ai = new GoogleGenAI({ "GOOGLE_API_KEY" });

async function main() {
  const response = await ai.models.generateContent({
    model: "gemini-2.0-flash",
    contents:
      "List a few popular cookie recipes, and include the amounts of ingredients.",
    config: {
      responseMimeType: "application/json",
      responseSchema: {
        type: Type.ARRAY,
        items: {
          type: Type.OBJECT,
          properties: {
            recipeName: {
              type: Type.STRING,
            },
            ingredients: {
              type: Type.ARRAY,
              items: {
                type: Type.STRING,
              },
            },
          },
          propertyOrdering: ["recipeName", "ingredients"],
        },
      },
    },
  });

  console.log(response.text);
}

main();
package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, &genai.ClientConfig{
        APIKey:  "GOOGLE_API_KEY",
        Backend: genai.BackendGeminiAPI,
    })
    if err != nil {
        log.Fatal(err)
    }

    config := &genai.GenerateContentConfig{
        ResponseMIMEType: "application/json",
        ResponseSchema: &genai.Schema{
            Type: genai.TypeArray,
            Items: &genai.Schema{
                Type: genai.TypeObject,
                Properties: map[string]*genai.Schema{
                    "recipeName": {Type: genai.TypeString},
                    "ingredients": {
                        Type:  genai.TypeArray,
                        Items: &genai.Schema{Type: genai.TypeString},
                    },
                },
                PropertyOrdering: []string{"recipeName", "ingredients"},
            },
        },
    }

    result, err := client.Models.GenerateContent(
        ctx,
        "gemini-2.0-flash",
        genai.Text("List a few popular cookie recipes, and include the amounts of ingredients."),
        config,
    )
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(result.Text())
}
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
      "contents": [{
        "parts":[
          { "text": "List a few popular cookie recipes, and include the amounts of ingredients." }
        ]
      }],
      "generationConfig": {
        "responseMimeType": "application/json",
        "responseSchema": {
          "type": "ARRAY",
          "items": {
            "type": "OBJECT",
            "properties": {
              "recipeName": { "type": "STRING" },
              "ingredients": {
                "type": "ARRAY",
                "items": { "type": "STRING" }
              }
            },
            "propertyOrdering": ["recipeName", "ingredients"]
          }
        }
      }
}' 2> /dev/null | head

Output-nya mungkin terlihat seperti ini:

[
  {
    "recipeName": "Chocolate Chip Cookies",
    "ingredients": [
      "1 cup (2 sticks) unsalted butter, softened",
      "3/4 cup granulated sugar",
      "3/4 cup packed brown sugar",
      "1 teaspoon vanilla extract",
      "2 large eggs",
      "2 1/4 cups all-purpose flour",
      "1 teaspoon baking soda",
      "1 teaspoon salt",
      "2 cups chocolate chips"
    ]
  },
  ...
]

Memberikan skema dalam perintah teks

Daripada mengonfigurasi skema, Anda dapat memberikan skema sebagai bahasa alami atau pseudo-kode dalam perintah teks. Metode ini tidak direkomendasikan, karena mungkin menghasilkan output berkualitas lebih rendah, dan karena model tidak dibatasi untuk mengikuti skema.

Berikut adalah contoh umum skema yang diberikan dalam perintah teks:

List a few popular cookie recipes, and include the amounts of ingredients.

Produce JSON matching this specification:

Recipe = { "recipeName": string, "ingredients": array<string> }
Return: array<Recipe>

Karena model mendapatkan skema dari teks dalam perintah, Anda mungkin memiliki beberapa fleksibilitas dalam cara merepresentasikan skema. Namun, saat Anda menyediakan skema inline seperti ini, model sebenarnya tidak dibatasi untuk menampilkan JSON. Untuk respons yang lebih deterministik dan berkualitas lebih tinggi, konfigurasikan skema pada model, dan jangan duplikasikan skema dalam perintah teks.

Membuat nilai enum

Dalam beberapa kasus, Anda mungkin ingin model memilih satu opsi dari daftar opsi. Untuk menerapkan perilaku ini, Anda dapat meneruskan enum dalam skema. Anda dapat menggunakan opsi enum di mana pun Anda dapat menggunakan string di responseSchema, karena enum adalah array string. Seperti skema JSON, enum memungkinkan Anda membatasi output model untuk memenuhi persyaratan aplikasi.

Misalnya, anggaplah Anda sedang mengembangkan aplikasi untuk mengklasifikasikan alat musik ke dalam salah satu dari lima kategori: "Percussion", "String", "Woodwind", "Brass", atau ""Keyboard"". Anda dapat membuat enum untuk membantu tugas ini.

Pada contoh berikut, Anda meneruskan enum sebagai responseSchema, yang membatasi model untuk memilih opsi yang paling sesuai.

Python
from google import genai
import enum

class Instrument(enum.Enum):
  PERCUSSION = "Percussion"
  STRING = "String"
  WOODWIND = "Woodwind"
  BRASS = "Brass"
  KEYBOARD = "Keyboard"

client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
    model='gemini-2.0-flash',
    contents='What type of instrument is an oboe?',
    config={
        'response_mime_type': 'text/x.enum',
        'response_schema': Instrument,
    },
)

print(response.text)
# Woodwind

Library Python akan menerjemahkan deklarasi jenis untuk API. Namun, API menerima subset skema OpenAPI 3.0 (Skema).

Ada dua cara lain untuk menentukan enumerasi. Anda dapat menggunakan Literal:

Python
Literal["Percussion", "String", "Woodwind", "Brass", "Keyboard"]

Anda juga dapat meneruskan skema sebagai JSON:

Python
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
    model='gemini-2.0-flash',
    contents='What type of instrument is an oboe?',
    config={
        'response_mime_type': 'text/x.enum',
        'response_schema': {
            "type": "STRING",
            "enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"],
        },
    },
)

print(response.text)
# Woodwind

Selain masalah pilihan ganda dasar, Anda dapat menggunakan enum di mana saja dalam skema JSON. Misalnya, Anda dapat meminta daftar judul resep ke model dan menggunakan enum Grade untuk memberi setiap judul nilai popularitas:

Python
from google import genai

import enum
from pydantic import BaseModel

class Grade(enum.Enum):
    A_PLUS = "a+"
    A = "a"
    B = "b"
    C = "c"
    D = "d"
    F = "f"

class Recipe(BaseModel):
  recipe_name: str
  rating: Grade

client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
    model='gemini-2.0-flash',
    contents='List 10 home-baked cookie recipes and give them grades based on tastiness.',
    config={
        'response_mime_type': 'application/json',
        'response_schema': list[Recipe],
    },
)

print(response.text)

Responsnya mungkin terlihat seperti ini:

[
  {
    "recipe_name": "Chocolate Chip Cookies",
    "rating": "a+"
  },
  {
    "recipe_name": "Peanut Butter Cookies",
    "rating": "a"
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies",
    "rating": "b"
  },
  ...
]

Tentang skema JSON

Mengonfigurasi model untuk output JSON menggunakan parameter responseSchema bergantung pada objek Schema untuk menentukan strukturnya. Objek ini mewakili subset tertentu dari objek Skema OpenAPI 3.0, dan juga menambahkan kolom propertyOrdering.

Berikut adalah representasi pseudo-JSON dari semua kolom Schema:

{
  "type": enum (Type),
  "format": string,
  "description": string,
  "nullable": boolean,
  "enum": [
    string
  ],
  "maxItems": integer,
  "minItems": integer,
  "properties": {
    string: {
      object (Schema)
    },
    ...
  },
  "required": [
    string
  ],
  "propertyOrdering": [
    string
  ],
  "items": {
    object (Schema)
  }
}

Type skema harus berupa salah satu Jenis Data OpenAPI, atau gabungan jenis tersebut (menggunakan anyOf). Hanya sebagian kolom yang valid untuk setiap Type. Daftar berikut memetakan setiap Type ke subkumpulan kolom yang valid untuk jenis tersebut:

  • string -> enum, format, nullable
  • integer -> format, minimum, maximum, enum, nullable
  • number -> format, minimum, maximum, enum, nullable
  • boolean -> nullable
  • array -> minItems, maxItems, items, nullable
  • object -> properties, required, propertyOrdering, nullable

Berikut adalah beberapa contoh skema yang menunjukkan kombinasi jenis dan kolom yang valid:

{ "type": "string", "enum": ["a", "b", "c"] }

{ "type": "string", "format": "date-time" }

{ "type": "integer", "format": "int64" }

{ "type": "number", "format": "double" }

{ "type": "boolean" }

{ "type": "array", "minItems": 3, "maxItems": 3, "items": { "type": ... } }

{ "type": "object",
  "properties": {
    "a": { "type": ... },
    "b": { "type": ... },
    "c": { "type": ... }
  },
  "nullable": true,
  "required": ["c"],
  "propertyOrdering": ["c", "b", "a"]
}

Untuk dokumentasi lengkap kolom Skema seperti yang digunakan di Gemini API, lihat Referensi skema.

Pengurutan properti

Saat Anda menggunakan skema JSON di Gemini API, urutan properti sangat penting. Secara default, API mengurutkan properti menurut abjad dan tidak mempertahankan urutan properti yang ditentukan (meskipun Google Gen AI SDK dapat mempertahankan urutan ini). Jika Anda memberikan contoh ke model dengan skema yang dikonfigurasi, dan urutan properti contoh tidak konsisten dengan urutan properti skema, output-nya mungkin tidak beraturan atau tidak terduga.

Untuk memastikan pengurutan properti yang konsisten dan dapat diprediksi, Anda dapat menggunakan kolom propertyOrdering[] opsional.

"propertyOrdering": ["recipeName", "ingredients"]

propertyOrdering[] – bukan kolom standar dalam spesifikasi OpenAPI – adalah array string yang digunakan untuk menentukan urutan properti dalam respons. Dengan menentukan urutan properti, lalu memberikan contoh dengan properti dalam urutan yang sama, Anda berpotensi meningkatkan kualitas hasil. propertyOrdering hanya didukung saat Anda membuat types.Schema secara manual.

Skema di Python

Saat Anda menggunakan library Python, nilai response_schema harus berupa salah satu dari berikut:

  • Jenis, seperti yang akan Anda gunakan dalam anotasi jenis (lihat modul typing Python)
  • Instance genai.types.Schema
  • dict yang setara dengan genai.types.Schema

Cara termudah untuk menentukan skema adalah dengan jenis Pydantic (seperti yang ditunjukkan dalam contoh sebelumnya):

Python
config={'response_mime_type': 'application/json',
        'response_schema': list[Recipe]}

Saat Anda menggunakan jenis Pydantic, library Python akan membuat skema JSON untuk Anda dan mengirimkannya ke API. Untuk contoh tambahan, lihat dokumen library Python.

Library Python mendukung skema yang ditentukan dengan jenis berikut (dengan AllowedType adalah jenis yang diizinkan):

  • int
  • float
  • bool
  • str
  • list[AllowedType]
  • AllowedType|AllowedType|...
  • Untuk jenis terstruktur:
    • dict[str, AllowedType]. Anotasi ini mendeklarasikan semua nilai dict untuk menjadi jenis yang sama, tetapi tidak menentukan kunci yang harus disertakan.
    • Model Pydantic yang ditentukan pengguna. Pendekatan ini memungkinkan Anda menentukan nama kunci dan menentukan berbagai jenis untuk nilai yang terkait dengan setiap kunci, termasuk struktur bertingkat.

Praktik terbaik

Perhatikan pertimbangan dan praktik terbaik berikut saat Anda menggunakan skema respons:

  • Ukuran skema respons Anda diperhitungkan dalam batas token input.
  • Secara default, kolom bersifat opsional, artinya model dapat mengisi kolom atau melewatkannya. Anda dapat menetapkan kolom sesuai kebutuhan untuk memaksa model memberikan nilai. Jika tidak ada cukup konteks dalam perintah input terkait, model akan menghasilkan respons terutama berdasarkan data yang digunakan untuk melatihnya.
  • Skema yang kompleks dapat menyebabkan error InvalidArgument: 400. Kompleksitas mungkin berasal dari nama properti yang panjang, batas panjang array yang panjang, enum dengan banyak nilai, objek dengan banyak properti opsional, atau kombinasi faktor-faktor ini.

    Jika Anda mendapatkan error ini dengan skema yang valid, lakukan satu atau beberapa perubahan berikut untuk mengatasi error:

    • Persingkat nama properti atau nama enum.
    • Meratakan array bertingkat.
    • Kurangi jumlah properti dengan batasan, seperti angka dengan batas minimum dan maksimum.
    • Kurangi jumlah properti dengan batasan yang kompleks, seperti properti dengan format yang kompleks seperti date-time.
    • Kurangi jumlah properti opsional.
    • Kurangi jumlah nilai yang valid untuk enum.
  • Jika Anda tidak melihat hasil yang diharapkan, tambahkan lebih banyak konteks ke perintah input atau revisi skema respons Anda. Misalnya, tinjau respons model tanpa output terstruktur untuk melihat respons model. Kemudian, Anda dapat memperbarui skema respons agar lebih sesuai dengan output model.

Langkah berikutnya

Setelah mempelajari cara membuat output terstruktur, Anda dapat mencoba menggunakan alat Gemini API: