เอาต์พุตที่มีโครงสร้าง

คุณสามารถกําหนดค่า Gemini สําหรับเอาต์พุตที่มีโครงสร้างแทนข้อความที่ไม่มีโครงสร้างได้ ซึ่งจะช่วยให้ดึงข้อมูลและมาตรฐานข้อมูลได้อย่างแม่นยําสําหรับการประมวลผลเพิ่มเติม เช่น คุณสามารถใช้เอาต์พุตที่มีโครงสร้างเพื่อดึงข้อมูลจากเรซูเม่ กำหนดมาตรฐานเพื่อสร้างฐานข้อมูลที่จัดโครงสร้าง

Gemini สามารถสร้าง JSON หรือค่า Enum เป็นเอาต์พุตที่มีโครงสร้าง

การสร้าง JSON

การสร้าง JSON โดยใช้ Gemini API มี 2 วิธีดังนี้

  • กําหนดค่าสคีมาในโมเดล
  • ระบุสคีมาในพรอมต์ข้อความ

การกำหนดค่าสคีมาในโมเดลเป็นวิธีที่แนะนำในการสร้าง JSON เนื่องจากจะจำกัดโมเดลให้แสดงผล JSON

การกําหนดค่าสคีมา (แนะนํา)

หากต้องการจํากัดรูปแบบให้สร้าง JSON ให้กําหนดค่า responseSchema จากนั้นโมเดลจะตอบกลับพรอมต์ด้วยเอาต์พุตรูปแบบ JSON

PythonJavaScriptGoREST
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

เอาต์พุตอาจมีลักษณะดังนี้

[
  {
    "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"
    ]
  },
  ...
]

ระบุสคีมาในพรอมต์ข้อความ

คุณสามารถระบุสคีมาเป็นภาษาธรรมชาติหรือรหัสจำลองในพรอมต์ข้อความแทนการกำหนดค่าสคีมา เราไม่แนะนําให้ใช้วิธีนี้ เนื่องจากอาจให้ผลลัพธ์ที่มีคุณภาพต่ำ และเนื่องจากโมเดลไม่ได้ถูกจํากัดให้ต้องเป็นไปตามสคีมา

ต่อไปนี้เป็นตัวอย่างทั่วไปของสคีมาที่ให้ไว้ในพรอมต์ข้อความ

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>

เนื่องจากโมเดลรับสคีมาจากข้อความในพรอมต์ คุณจึงอาจมีความยืดหยุ่นในการแสดงสคีมา แต่เมื่อคุณระบุสคีมาในบรรทัด เช่น นี้ โมเดลไม่ได้ถูกจํากัดให้แสดงผล JSON หากต้องการคำตอบที่แน่นอนและมีคุณภาพสูงขึ้น ให้กําหนดค่าสคีมาในโมเดล และอย่าทำสคีมาซ้ำในพรอมต์ข้อความ

การสร้างค่า enum

ในบางกรณี คุณอาจต้องการให้โมเดลเลือกตัวเลือกเดียวจากรายการตัวเลือก หากต้องการใช้ลักษณะการทำงานนี้ ให้ส่ง enum ในสคีมา คุณใช้ตัวเลือก enum ได้ในทุกที่ที่สามารถใช้ string ใน responseSchema เนื่องจาก enum คืออาร์เรย์สตริง Enum ให้คุณจํากัดเอาต์พุตของโมเดลให้เป็นไปตามข้อกําหนดของแอปพลิเคชันได้ เช่นเดียวกับสคีมา JSON

ตัวอย่างเช่น สมมติว่าคุณกำลังพัฒนาแอปพลิเคชันเพื่อจัดหมวดหมู่เครื่องดนตรีออกเป็น 1 ใน 5 หมวดหมู่ ได้แก่ "Percussion", "String", "Woodwind", "Brass" หรือ ""Keyboard"" คุณอาจสร้าง enum เพื่อช่วยในการทำงานนี้

ในตัวอย่างนี้ คุณจะส่ง Enum เป็น responseSchema ซึ่งจํากัดให้โมเดลเลือกตัวเลือกที่เหมาะสมที่สุด

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

ไลบรารี Python จะแปลการประกาศประเภทสําหรับ API อย่างไรก็ตาม API จะยอมรับสคีมา OpenAPI 3.0 บางส่วน (สคีมา)

ยังมีวิธีอื่นๆ อีก 2 วิธีในการระบุการแจกแจง คุณใช้ Literal ในกรณีต่อไปนี้ได้

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

นอกจากนี้ คุณยังส่งสคีมาเป็น 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

นอกจากโจทย์แบบเลือกตอบพื้นฐานแล้ว คุณยังใช้ enum ได้ทุกที่ในสคีมา JSON ตัวอย่างเช่น คุณอาจขอรายการชื่อสูตรอาหารจากโมเดลและใช้ Grade enum เพื่อจัดอันดับความนิยมให้กับแต่ละชื่อ ดังนี้

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)

การตอบกลับอาจมีลักษณะดังนี้

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

เกี่ยวกับสคีมา JSON

การกำหนดค่าโมเดลสำหรับเอาต์พุต JSON โดยใช้พารามิเตอร์ responseSchema จะใช้ออบเจ็กต์ Schema เพื่อกำหนดโครงสร้าง ออบเจ็กต์นี้แสดงชุดย่อยที่เลือกของออบเจ็กต์สคีมา OpenAPI 3.0 และเพิ่มช่อง propertyOrdering ด้วย

ต่อไปนี้คือการแสดงผลแบบจำลอง JSON ของฟิลด์ 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 ของสคีมาต้องเป็น ประเภทข้อมูล OpenAPI ประเภทใดประเภทหนึ่ง หรือเป็นสหพันธ์ของประเภทเหล่านั้น (โดยใช้ anyOf) เฉพาะชุดย่อยของช่องเท่านั้นที่ใช้ได้กับ Type แต่ละรายการ รายการต่อไปนี้จะจับคู่ Type แต่ละรายการกับชุดย่อยของฟิลด์ที่ใช้ได้กับประเภทนั้นๆ

  • 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

ตัวอย่างสคีมาบางส่วนที่แสดงการผสมผสานประเภทและช่องที่ถูกต้องมีดังนี้

{ "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"]
}

ดูเอกสารประกอบฉบับเต็มของช่องสคีมาที่ใช้ใน Gemini API ได้ที่ข้อมูลอ้างอิงสคีมา

การจัดเรียงที่พัก

เมื่อคุณทํางานกับสคีมา JSON ใน Gemini API ลําดับของพร็อพเพอร์ตี้มีความสําคัญ โดยค่าเริ่มต้น API จะจัดเรียงพร็อพเพอร์ตี้ตามลําดับตัวอักษรและไม่เก็บลําดับที่กําหนดพร็อพเพอร์ตี้ (แม้ว่า Google Gen AI SDK อาจเก็บลําดับนี้ไว้) หากคุณระบุตัวอย่างให้กับโมเดลที่มีการกําหนดค่าสคีมาไว้ และลําดับพร็อพเพอร์ตี้ของตัวอย่างไม่สอดคล้องกับลําดับพร็อพเพอร์ตี้ของสคีมา ผลลัพธ์อาจไม่เป็นระเบียบหรือคาดเดาไม่ได้

คุณใช้ฟิลด์ propertyOrdering[] (ไม่บังคับ) เพื่อให้การจัดเรียงพร็อพเพอร์ตี้มีความสอดคล้องและคาดการณ์ได้

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

propertyOrdering[] – ไม่ใช่ช่องมาตรฐานในข้อกำหนด OpenAPI – คืออาร์เรย์สตริงที่ใช้กำหนดลำดับของพร็อพเพอร์ตี้ในการตอบกลับ การระบุลําดับของพร็อพเพอร์ตี้ แล้วให้ตัวอย่างที่มีพร็อพเพอร์ตี้ตามลําดับเดียวกันอาจช่วยปรับปรุงคุณภาพของผลลัพธ์ได้ ระบบจะรองรับ propertyOrdering เมื่อคุณสร้างด้วยตนเองเท่านั้น types.Schema

สคีมาใน Python

เมื่อใช้ไลบรารี Python ค่าของ response_schema ต้องเป็นค่าใดค่าหนึ่งต่อไปนี้

  • ประเภทที่คุณจะใช้ในการอธิบายประกอบประเภท (ดูโมดูล typing ของ Python)
  • อินสแตนซ์ของ genai.types.Schema
  • dict เทียบเท่าของ genai.types.Schema

วิธีที่ง่ายที่สุดในการกำหนดสคีมาคือการใช้ประเภท Pydantic (ดังที่แสดงในตัวอย่างก่อนหน้า)

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

เมื่อคุณใช้ประเภท Pydantic ไลบรารี Python จะสร้างสคีมา JSON ให้คุณและส่งไปยัง API ดูตัวอย่างเพิ่มเติมได้ในเอกสารประกอบของไลบรารี Python

ไลบรารี Python รองรับสคีมาที่กำหนดด้วยประเภทต่อไปนี้ (โดยที่ AllowedType คือประเภทที่อนุญาต)

  • int
  • float
  • bool
  • str
  • list[AllowedType]
  • AllowedType|AllowedType|...
  • สำหรับประเภทที่มีโครงสร้าง
    • dict[str, AllowedType] หมายเหตุนี้ประกาศว่าค่า Dict ทั้งหมดเป็นประเภทเดียวกัน แต่ไม่ระบุว่าควรรวมคีย์ใดบ้าง
    • รูปแบบ Pydantic ที่ผู้ใช้กําหนด วิธีนี้ช่วยให้คุณระบุชื่อคีย์และกำหนดประเภทต่างๆ สำหรับค่าที่เชื่อมโยงกับคีย์แต่ละรายการ รวมถึงโครงสร้างที่ฝังอยู่

แนวทางปฏิบัติแนะนำ

โปรดคำนึงถึงข้อควรพิจารณาและแนวทางปฏิบัติแนะนำต่อไปนี้เมื่อใช้สคีมาคำตอบ

  • ขนาดของสคีมาการตอบกลับจะนับรวมในขีดจํากัดของโทเค็นอินพุต
  • โดยค่าเริ่มต้น ฟิลด์จะเป็นแบบไม่บังคับ ซึ่งหมายความว่าโมเดลจะป้อนข้อมูลในฟิลด์หรือข้ามฟิลด์ก็ได้ คุณสามารถตั้งค่าช่องเป็น "ต้องกรอก" เพื่อบังคับให้โมเดลระบุค่า หากบริบทในพรอมต์การป้อนข้อมูลที่เกี่ยวข้องไม่เพียงพอ โมเดลจะสร้างคำตอบโดยอิงตามข้อมูลที่ใช้ในการฝึกเป็นหลัก
  • สคีมาที่ซับซ้อนอาจทำให้เกิดข้อผิดพลาด InvalidArgument: 400 ความซับซ้อนอาจมาจากชื่อพร็อพเพอร์ตี้ยาว อาร์เรย์ที่มีความยาวเกินขีดจำกัด รายการที่มีค่าหลายรายการ ออบเจ็กต์ที่มีพร็อพเพอร์ตี้ที่ไม่บังคับจำนวนมาก หรือปัจจัยเหล่านี้รวมกัน

    หากคุณได้รับข้อผิดพลาดนี้กับสคีมาที่ใช้ได้ ให้ทําการเปลี่ยนแปลงอย่างน้อย 1 ข้อต่อไปนี้เพื่อแก้ไขข้อผิดพลาด

    • ย่อชื่อพร็อพเพอร์ตี้หรือชื่อ Enum
    • รวมอาร์เรย์ที่ซ้อนกัน
    • ลดจํานวนพร็อพเพอร์ตี้ที่มีข้อจํากัด เช่น จํานวนที่มีขีดจํากัดต่ำสุดและสูงสุด
    • ลดจำนวนที่พักที่มีข้อจำกัดที่ซับซ้อน เช่น ที่พักที่มีรูปแบบที่ซับซ้อน เช่น date-time
    • ลดจำนวนพร็อพเพอร์ตี้ที่ไม่บังคับ
    • ลดจำนวนค่าที่ถูกต้องสำหรับลิสต์แบบจำกัด
  • หากไม่เห็นผลลัพธ์ที่คาดไว้ ให้เพิ่มบริบทในพรอมต์อินพุตหรือแก้ไขสคีมาคำตอบ เช่น ตรวจสอบคําตอบของโมเดลโดยไม่มีเอาต์พุต Structured เพื่อดูว่าโมเดลตอบสนองอย่างไร จากนั้นคุณสามารถอัปเดตสคีมาคำตอบเพื่อให้เหมาะกับเอาต์พุตของโมเดลมากขึ้น

ขั้นตอนถัดไป

เมื่อทราบวิธีสร้าง Structured Data แล้ว คุณอาจต้องการลองใช้เครื่องมือ Gemini API ต่อไปนี้