פלט מובנה

אתם יכולים להגדיר את Gemini כך שיפיק פלט מובנה במקום טקסט לא מובנה, כדי לאפשר חילוץ מדויק של מידע וסטנדרטיזציה שלו לצורך עיבוד נוסף. לדוגמה, אפשר להשתמש בפלט מובנה כדי לחלץ מידע מקורות חיים, לקבוע סטנדרט אחיד לנתונים האלה ולבנות מסד נתונים מובנה.

‫Gemini יכול ליצור פלט מובנה בפורמט JSON או ערכי enum.

יצירת JSON

יש שתי דרכים ליצור JSON באמצעות Gemini API:

  • הגדרת סכימה במודל
  • הוספת סכימה להנחיה בטקסט

הדרך המומלצת ליצירת JSON היא הגדרת סכימה במודל, כי היא מגבילה את המודל לפלט JSON.

הגדרת סכימה (מומלץ)

כדי להגביל את המודל ליצירת JSON, מגדירים responseSchema. המודל יחזיר תשובה לכל הנחיה בפורמט JSON.

Python

from google import genai
from pydantic import BaseModel

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

client = genai.Client()
response = client.models.generate_content(
    model="gemini-2.5-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

JavaScript

import { GoogleGenAI, Type } from "@google/genai";

const ai = new GoogleGenAI({});

async function main() {
  const response = await ai.models.generateContent({
    model: "gemini-2.5-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();

Go

package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    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.5-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())
}

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: $GEMINI_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 הוא מערך של מחרוזות. בדומה לסכימת JSON, enum מאפשר להגביל את פלט המודל כך שיתאים לדרישות של האפליקציה.

לדוגמה, נניח שאתם מפתחים אפליקציה לסיווג כלי נגינה לאחת מחמש קטגוריות: "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()
response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents='What type of instrument is an oboe?',
    config={
        'response_mime_type': 'text/x.enum',
        'response_schema': Instrument,
    },
)

print(response.text)
# Woodwind

JavaScript

import { GoogleGenAI, Type } from "@google/genai";

const ai = new GoogleGenAI({});

const response = await ai.models.generateContent({
    model: "gemini-2.5-flash",
    contents: "What type of instrument is an oboe?",
    config: {
      responseMimeType: "text/x.enum",
      responseSchema: {
        type: Type.STRING,
        enum: ["Percussion", "String", "Woodwind", "Brass", "Keyboard"],
      },
    },
  });

console.log(response.text);

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
          "contents": [{
            "parts":[
              { "text": "What type of instrument is an oboe?" }
            ]
          }],
          "generationConfig": {
            "responseMimeType": "text/x.enum",
            "responseSchema": {
              "type": "STRING",
              "enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"]
            }
          }
    }'

ספריית Python תתרגם את הצהרות הסוג עבור ה-API. עם זאת, ה-API מקבל קבוצת משנה של סכימת OpenAPI 3.0 ‏(Schema).

יש עוד שתי דרכים לציין ספירה. אפשר להשתמש ב-Literal: ```

Python

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

אפשר גם להעביר את הסכימה כ-JSON:

Python

from google import genai

client = genai.Client()
response = client.models.generate_content(
    model='gemini-2.5-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()
response = client.models.generate_content(
    model='gemini-2.5-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.

הנה ייצוג של כל השדות Schema בפורמט פסאודו-JSON:

{
  "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 SDKs ישמרו על הסדר הזה). אם מספקים למודל דוגמאות עם סכימה מוגדרת, וסדר המאפיינים בדוגמאות לא עקבי עם סדר המאפיינים בסכימה, הפלט עשוי להיות לא ברור או לא צפוי.

כדי להבטיח סדר עקבי וצפוי של מאפיינים, אפשר להשתמש בשדה האופציונלי 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]. ההערה הזו מכריזה על כך שכל הערכים במילון הם מאותו סוג, אבל לא מציינת אילו מפתחות צריכים להיכלל.
    • מודלים שהוגדרו על ידי המשתמש מודלים של Pydantic. הגישה הזו מאפשרת לכם לציין את שמות המפתחות ולהגדיר סוגים שונים לערכים שמשויכים לכל אחד מהמפתחות, כולל מבנים מקוננים.

תמיכה בסכימת JSON

JSON Schema הוא מפרט חדש יותר מ-OpenAPI 3.0, שעליו מבוסס אובייקט Schema. תמיכה בסכימת JSON זמינה בתצוגה מקדימה באמצעות השדה responseJsonSchema, שמקבל כל סכימת JSON עם המגבלות הבאות:

  • הוא פועל רק עם Gemini 2.5.
  • אפשר להעביר את כל המאפיינים של סכימת JSON, אבל לא כולם נתמכים. פרטים נוספים מופיעים במסמכי התיעוד של השדה.
  • אפשר להשתמש בהפניות רקורסיביות רק כערך של מאפיין אובייקט לא נדרש.
  • הפניות רקורסיביות מפורקות לדרגה סופית, על סמך גודל הסכימה.
  • סכימות שמכילות $ref לא יכולות להכיל מאפיינים אחרים מלבד אלה שמתחילים ב-$.

הנה דוגמה ליצירת סכימת JSON באמצעות Pydantic ושליחה שלה למודל:

curl "https://generativelanguage.googleapis.com/v1alpha/models/\
gemini-2.5-flash:generateContent" \
    -H "x-goog-api-key: $GEMINI_API_KEY"\
    -H 'Content-Type: application/json' \
    -d @- <<EOF
{
  "contents": [{
    "parts":[{
      "text": "Please give a random example following this schema"
    }]
  }],
  "generationConfig": {
    "response_mime_type": "application/json",
    "response_json_schema": $(python3 - << PYEOF
    from enum import Enum
    from typing import List, Optional, Union, Set
    from pydantic import BaseModel, Field, ConfigDict
    import json

    class UserRole(str, Enum):
        ADMIN = "admin"
        VIEWER = "viewer"

    class Address(BaseModel):
        street: str
        city: str

    class UserProfile(BaseModel):
        username: str = Field(description="User's unique name")
        age: Optional[int] = Field(ge=0, le=120)
        roles: Set[UserRole] = Field(min_items=1)
        contact: Union[Address, str]
        model_config = ConfigDict(title="User Schema")

    # Generate and print the JSON Schema
    print(json.dumps(UserProfile.model_json_schema(), indent=2))
    PYEOF
    )
  }
}
EOF

כשמשתמשים ב-SDK, עדיין אי אפשר להעביר ישירות סכימת JSON.

שיטות מומלצות

כשמשתמשים בסכימת תגובה, חשוב לזכור את הנקודות הבאות ואת השיטות המומלצות:

  • גודל סכימת התגובה נספר במגבלת הטוקנים של הקלט.
  • כברירת מחדל, השדות הם אופציונליים, כלומר המודל יכול לאכלס את השדות או לדלג עליהם. אתם יכולים להגדיר שדות כחובה כדי לחייב את המודל לספק ערך. אם אין מספיק הקשר בהנחיה המשויכת, המודל יוצר תשובות שמבוססות בעיקר על הנתונים שעליהם הוא אומן.
  • סכימה מורכבת עלולה לגרום לשגיאה InvalidArgument: 400. מורכבות יכולה לנבוע משמות מאפיינים ארוכים, ממגבלות אורך ארוכות של מערכים, מ-enums עם הרבה ערכים, מאובייקטים עם הרבה מאפיינים אופציונליים או משילוב של הגורמים האלה.

    אם השגיאה הזו מופיעה בסכימה תקינה, צריך לבצע שינוי אחד או יותר מהשינויים הבאים כדי לפתור את השגיאה:

    • לקצר את שמות הנכסים או את שמות ה-enum.
    • השטחת מערכים מקוננים.
    • צריך לצמצם את מספר הנכסים עם מגבלות, כמו מספרים עם מגבלות מינימום ומקסימום.
    • צריך לצמצם את מספר הנכסים עם אילוצים מורכבים, כמו נכסים עם פורמטים מורכבים כמו date-time.
    • צריך לצמצם את מספר המאפיינים האופציונליים.
    • צריך לצמצם את מספר הערכים החוקיים של סוגי הנתונים enum.
  • אם התוצאות לא תואמות לציפיות שלכם, כדאי להוסיף עוד הקשר להנחיות או לשנות את סכימת התגובה. לדוגמה, אפשר לבדוק את התשובה של המודל בלי פלט מובנה כדי לראות איך המודל מגיב. אחר כך תוכלו לעדכן את סכמת התשובה כך שתתאים יותר לפלט של המודל. טיפים נוספים לפתרון בעיות בפלט מובנה זמינים במדריך לפתרון בעיות.

המאמרים הבאים

אחרי שלמדתם איך ליצור פלט מובנה, כדאי לנסות להשתמש בכלים של Gemini API: