Структурированный вывод

Вы можете настроить Gemini на структурированный вывод вместо неструктурированного текста, что обеспечит точное извлечение и стандартизацию информации для дальнейшей обработки. Например, структурированный вывод можно использовать для извлечения информации из резюме и её стандартизации для создания структурированной базы данных.

Gemini может генерировать значения JSON или enum в качестве структурированного вывода.

Генерация JSON

Существует два способа генерации JSON с использованием API Gemini:

  • Настройте схему на основе модели
  • Предоставьте схему в текстовом запросе

Настройка схемы на основе модели является рекомендуемым способом генерации JSON, поскольку она ограничивает модель выводом JSON.

Настройка схемы (рекомендуется)

Чтобы ограничить генерацию JSON-данных моделью, настройте responseSchema . После этого модель будет отвечать на любые запросы выводом в формате JSON.

Питон

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();

Идти

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())
}

ОТДЫХ

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. Для более детерминированного и качественного ответа настройте схему в модели и не дублируйте её в текстовом приглашении.

Генерация значений перечисления

В некоторых случаях может потребоваться, чтобы модель выбирала один вариант из списка. Для реализации этого поведения можно передать перечисление в схему. Параметр перечисления можно использовать везде, где можно использовать string в responseSchema , поскольку перечисление — это массив строк. Как и схема JSON, перечисление позволяет ограничить выходные данные модели в соответствии с требованиями вашего приложения.

Например, предположим, что вы разрабатываете приложение для классификации музыкальных инструментов по пяти категориям: "Percussion" , "String" , "Woodwind" , "Brass" или « "Keyboard" ». Вы можете создать перечисление для решения этой задачи.

В следующем примере вы передаете перечисление как responseSchema , ограничивая модель выбором наиболее подходящего варианта.

Питон

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);

ОТДЫХ

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 : ```

Питон

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

И вы также можете передать схему как JSON:

Питон

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

Помимо базовых задач с множественным выбором, вы можете использовать перечисление в любом месте JSON-схемы. Например, вы можете запросить у модели список названий рецептов и использовать перечисление Grade , чтобы присвоить каждому названию степень популярности:

Питон

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 . Этот объект представляет собой выбранное подмножество объекта 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"]
}

Полную документацию по полям схемы, используемым в API Gemini, см. в справочнике по схеме .

Заказ недвижимости

При работе со схемами JSON в API Gemini порядок свойств важен. По умолчанию API упорядочивает свойства в алфавитном порядке и не сохраняет порядок их определения (хотя пакеты SDK Google Gen AI могут сохранять этот порядок). Если вы предоставляете примеры для модели с настроенной схемой, и порядок свойств в примерах не соответствует порядку свойств в схеме, вывод может быть беспорядочным или неожиданным.

Чтобы обеспечить последовательный и предсказуемый порядок свойств, можно использовать необязательное поле propertyOrdering[] .

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

propertyOrdering[] – нестандартное поле в спецификации OpenAPI – представляет собой массив строк, используемый для определения порядка свойств в ответе. Указав порядок свойств и предоставив примеры со свойствами в том же порядке, вы потенциально можете улучшить качество результатов. propertyOrdering поддерживается только при ручном создании types.Schema .

Схемы в Python

При использовании библиотеки Python значение response_schema должно быть одним из следующих:

  • Тип, который вы бы использовали в аннотации типа (см. модуль typing Python)
  • Экземпляр genai.types.Schema
  • dict эквивалент genai.types.Schema

Самый простой способ определить схему — с помощью типа Pydantic (как показано в предыдущем примере):

Питон

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 Schema доступна в виде предварительного просмотра с помощью поля responseJsonSchema , которое принимает любую JSON Schema со следующими ограничениями:

  • Работает только с 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

Прямая передача JSON-схемы при использовании SDK пока не поддерживается.

Лучшие практики

При использовании схемы ответа учитывайте следующие соображения и передовые практики:

  • Размер вашей схемы ответа учитывается при расчете лимита входных токенов.
  • По умолчанию поля необязательны, то есть модель может заполнять их самостоятельно или пропускать. Вы можете настроить поля так, чтобы модель обязательно предоставляла значение. Если в соответствующем запросе на ввод данных недостаточно контекста, модель генерирует ответы, основанные преимущественно на данных, на которых она обучалась.
  • Сложная схема может привести к ошибке InvalidArgument: 400 Сложность может быть обусловлена длинными именами свойств, большими ограничениями на длину массивов, перечислениями с большим количеством значений, объектами с большим количеством необязательных свойств или сочетанием этих факторов.

    Если вы получили эту ошибку при правильной схеме, внесите одно или несколько из следующих изменений, чтобы устранить ошибку:

    • Сократите имена свойств или перечислений.
    • Сглаживание вложенных массивов.
    • Сократите количество свойств с ограничениями, например, чисел с минимальными и максимальными пределами.
    • Сократите количество свойств со сложными ограничениями, например, свойств со сложными форматами, такими как date-time .
    • Сократите количество необязательных свойств.
    • Уменьшите количество допустимых значений для перечислений.
  • Если вы не видите ожидаемых результатов, добавьте больше контекста в запросы на ввод данных или скорректируйте схему ответа. Например, проверьте ответ модели без структурированного вывода, чтобы увидеть, как она реагирует. Затем вы можете обновить схему ответа, чтобы она лучше соответствовала выводимым данным модели. Дополнительные советы по устранению неполадок со структурированным выводом см. в руководстве по устранению неполадок .

Что дальше?

Теперь, когда вы научились генерировать структурированный вывод, вы можете попробовать использовать инструменты API Gemini: