Генерируйте структурированный вывод с помощью Gemini API


Gemini по умолчанию генерирует неструктурированный текст, но некоторым приложениям требуется структурированный текст. В этих случаях вы можете ограничить Gemini ответом в формате JSON — структурированном формате данных, подходящем для автоматической обработки. Вы также можете ограничить модель ответом с одним из параметров, указанных в перечислении.

Вот несколько случаев использования, которые могут потребовать структурированного вывода модели:

  • Создайте базу данных компаний, извлекая информацию о компаниях из газетных статей.
  • Извлекайте стандартизированную информацию из резюме.
  • Извлекайте ингредиенты из рецептов и отображайте ссылку на продуктовый веб-сайт для каждого ингредиента.

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

В этом руководстве показано, как генерировать JSON с помощью generateContent через выбранный вами SDK или напрямую с помощью REST API. В примерах показан только текстовый ввод, хотя Gemini также может создавать ответы JSON на мультимодальные запросы, включающие изображения , видео и аудио .

Прежде чем начать: настройте проект и ключ API.

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

Создать JSON

Когда модель настроена для вывода JSON, она отвечает на любой запрос выводом в формате JSON.

Вы можете управлять структурой ответа JSON, предоставив схему. Существует два способа предоставления схемы в модель:

  • Как текст в подсказке
  • В виде структурированной схемы, предоставляемой посредством конфигурации модели.

Оба подхода работают как в Gemini 1.5 Flash, так и в Gemini 1.5 Pro.

Предоставьте схему в виде текста в приглашении

В следующем примере модели предлагается вернуть рецепты файлов cookie в определенном формате JSON.

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

model = genai.GenerativeModel("gemini-1.5-pro-latest")
prompt = """List a few popular cookie recipes in JSON format.

Use this JSON schema:

Recipe = {'recipe_name': str, 'ingredients': list[str]}
Return: list[Recipe]"""
result = model.generate_content(prompt)
print(result)

Вывод может выглядеть так:

[{"recipeName": "Chocolate Chip Cookies"}, {"recipeName": "Oatmeal Raisin Cookies"}, {"recipeName": "Snickerdoodles"}, {"recipeName": "Sugar Cookies"}, {"recipeName": "Peanut Butter Cookies"}]

Предоставьте схему через конфигурацию модели.

Следующий пример делает следующее:

  1. Создает экземпляр модели, настроенной с помощью схемы для ответа в формате JSON.
  2. Предлагает модели вернуть рецепты печенья.
import typing_extensions as typing

class Recipe(typing.TypedDict):
    recipe_name: str
    ingredients: list[str]

model = genai.GenerativeModel("gemini-1.5-pro-latest")
result = model.generate_content(
    "List a few popular cookie recipes.",
    generation_config=genai.GenerationConfig(
        response_mime_type="application/json", response_schema=list[Recipe]
    ),
)
print(result)

Вывод может выглядеть так:

[{"recipeName": "Chocolate Chip Cookies"}, {"recipeName": "Oatmeal Raisin Cookies"}, {"recipeName": "Snickerdoodles"}, {"recipeName": "Sugar Cookies"}, {"recipeName": "Peanut Butter Cookies"}]

Синтаксис определения схемы

Укажите схему ответа JSON в свойстве response_schema конфигурации вашей модели. Значение response_schema должно быть либо:

Определите схему с помощью аннотации подсказки типа

Самый простой способ определить схему — использовать аннотацию подсказки типа. Именно такой подход использовался в предыдущем примере:

generation_config={"response_mime_type": "application/json",
                   "response_schema": list[Recipe]}

Клиентская библиотека Gemini API Python поддерживает схемы, определенные со следующим подмножеством аннотаций typing (где AllowedType — любая разрешенная аннотация типа):

  • int
  • float
  • bool
  • str (или перечисление)
  • list[AllowedType]
  • Для типов dict:
    • dict[str, AllowedType] . Эта аннотация объявляет, что все значения dict имеют один и тот же тип, но не указывает, какие ключи следует включить.
    • Пользовательские подклассы typing.TypedDict . Этот подход позволяет указать имена ключей и определить различные типы значений, связанных с каждым из ключей.
    • Пользовательские классы данных . Подобно подклассам TypedDict , этот подход позволяет указать имена ключей и определить различные типы значений, связанных с каждым из ключей.
Определите схему с помощью протокольного буфера genai.protos.Schema

Определение буфера протокола Gemini API genai.protos.Schema поддерживает несколько дополнительных функций схемы, которые не поддерживаются для подсказок типов, в том числе:

  • Перечисления для строк
  • Указание формата числовых типов (например, int32 или int64 для целых чисел)
  • Указание обязательных полей.

Если вам нужны эти функции, создайте экземпляр genai.protos.Schema используя один из методов, показанных в разделе «Вызов функций: доступ низкого уровня» .

Используйте перечисление для ограничения вывода

В некоторых случаях вам может потребоваться, чтобы модель выбирала один вариант из списка вариантов. Чтобы реализовать такое поведение, вы можете передать перечисление в свою схему. Вы можете использовать параметр перечисления везде, где можно использовать str в response_schema , поскольку перечисление на самом деле представляет собой список строк. Подобно схеме JSON, перечисление позволяет ограничить выходные данные модели в соответствии с требованиями вашего приложения.

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

Прежде чем запускать примеры кода в этом разделе, обязательно импортируйте библиотеку Google Generative AI:

import google.generativeai as genai

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

import enum

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

model = genai.GenerativeModel("gemini-1.5-pro-latest")

organ = genai.upload_file(media / "organ.jpg")
result = model.generate_content(
    ["What kind of instrument is this:", organ],
    generation_config=genai.GenerationConfig(
        response_mime_type="text/x.enum", response_schema=Choice
    ),
)
print(result)  # Keyboard

Python SDK переведет объявления типов для API. Но на самом деле API принимает подмножество схемы OpenAPI 3.0 ( Schema ). Вы также можете передать схему в формате JSON:

model = genai.GenerativeModel("gemini-1.5-pro-latest")

organ = genai.upload_file(media / "organ.jpg")
result = model.generate_content(
    ["What kind of instrument is this:", organ],
    generation_config=genai.GenerationConfig(
        response_mime_type="text/x.enum",
        response_schema={
            "type": "STRING",
            "enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"],
        },
    ),
)
print(result)  # Keyboard

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

import enum
from typing_extensions import TypedDict

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

class Recipe(TypedDict):
    recipe_name: str
    grade: Grade

model = genai.GenerativeModel("gemini-1.5-pro-latest")

result = model.generate_content(
    "List about 10 cookie recipes, grade them based on popularity",
    generation_config=genai.GenerationConfig(
        response_mime_type="application/json", response_schema=list[Recipe]
    ),
)
print(result)  # [{"grade": "a+", "recipe_name": "Chocolate Chip Cookies"}, ...]

Чтобы начать работу с перечислениями, попробуйте быстрый запуск перечислений Colab .