使用 Gemini API 生成结构化输出


Gemini 默认会生成非结构化文本,但某些应用需要结构化文本。对于这些用例,您可以限制 Gemini 以 JSON 格式(一种适合自动处理的结构化数据格式)进行响应。您还可以限制模型使用枚举中指定的选项之一进行响应。

以下是可能需要模型提供结构化输出的几种用例:

  • 从报纸文章中提取公司信息,构建公司数据库。
  • 从简历中提取标准化信息。
  • 从食谱中提取食材,并为每种食材显示指向杂货网站的链接。

在问题中,您可以要求 Gemini 生成 JSON 格式的输出,但请注意,模型无法保证只会生成 JSON 格式的输出。如需获得更确定性的响应,您可以在 responseSchema 字段中传递特定的 JSON 架构,以便 Gemini 始终以预期的结构响应。

本指南介绍了如何通过所选 SDK 或直接使用 REST API 使用 generateContent 方法生成 JSON。示例显示了纯文本输入,但 Gemini 还可以针对包含图片视频音频的多模式请求生成 JSON 响应。

开始前须知:设置项目和 API 密钥

在调用 Gemini API 之前,您需要设置项目并配置 API 密钥。

生成 JSON

将模型配置为输出 JSON 后,它会以 JSON 格式的输出回答任何问题。

您可以通过提供架构来控制 JSON 响应的结构。您可以通过以下两种方式向模型提供架构:

  • 作为提示中的文本
  • 作为通过模型配置提供的结构化架构

这两种方法都适用于 Gemini 1.5 Flash 和 Gemini 1.5 Pro。

在提示中以文本形式提供架构

以下示例会提示模型以特定 JSON 格式返回饼干食谱。

由于模型会从提示中的文本获取格式规范,因此您在表示规范的方式上可能会有一定的灵活性。任何用于表示 JSON 架构的合理格式都可以使用。

import google.generativeai as genai

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)

输出可能如下所示:

[{"ingredients": ["1 cup (2 sticks) unsalted butter, softened", "1 cup granulated sugar", "1 cup packed light brown sugar", "2 teaspoons pure vanilla extract", "2 large eggs", "3 cups all-purpose flour", "1 teaspoon baking soda", "1 teaspoon salt", "2 cups chocolate chips"], "recipe_name": "Chocolate Chip Cookies"}, {"ingredients": ["1 cup (2 sticks) unsalted butter, softened", "¾ cup granulated sugar", "¾ cup packed light brown sugar", "1 teaspoon pure vanilla extract", "2 large eggs", "2 ¼ cups all-purpose flour", "1 teaspoon baking soda", "1 teaspoon salt", "1 cup rolled oats", "1 cup raisins"], "recipe_name": "Oatmeal Raisin Cookies"}, {"ingredients": ["1 cup (2 sticks) unsalted butter, softened", "1 ½ cups powdered sugar", "1 teaspoon pure vanilla extract", "2 ¼ cups all-purpose flour", "¼ teaspoon salt", "Sprinkles or colored sugar for decoration"], "recipe_name": "Sugar Cookies"}, {"ingredients": ["1 cup peanut butter", "1 cup granulated sugar", "1 large egg"], "recipe_name": "3-Ingredient Peanut Butter Cookies"}]

通过模型配置提供架构

以下示例会执行以下操作:

  1. 通过架构实例化配置的模型,以 JSON 格式进行响应。
  2. 提示模型返回饼干食谱。
import google.generativeai as genai

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)

输出可能如下所示:

[{"ingredients": ["1 cup (2 sticks) unsalted butter, softened", "1 cup granulated sugar", "1 cup packed light brown sugar", "2 teaspoons pure vanilla extract", "2 large eggs", "3 cups all-purpose flour", "1 teaspoon baking soda", "1 teaspoon salt", "2 cups chocolate chips"], "recipe_name": "Chocolate Chip Cookies"}, {"ingredients": ["1 cup (2 sticks) unsalted butter, softened", "¾ cup granulated sugar", "¾ cup packed light brown sugar", "1 teaspoon pure vanilla extract", "2 large eggs", "2 ¼ cups all-purpose flour", "1 teaspoon baking soda", "1 teaspoon salt", "1 cup rolled oats", "1 cup raisins"], "recipe_name": "Oatmeal Raisin Cookies"}, {"ingredients": ["1 cup (2 sticks) unsalted butter, softened", "1 ½ cups powdered sugar", "1 teaspoon pure vanilla extract", "2 ¼ cups all-purpose flour", "¼ teaspoon salt", "Sprinkles or colored sugar for decoration"], "recipe_name": "Sugar Cookies"}, {"ingredients": ["1 cup peanut butter", "1 cup granulated sugar", "1 large egg"], "recipe_name": "3-Ingredient Peanut Butter Cookies"}]

架构定义语法

在模型配置的 response_schema 属性中指定 JSON 响应的架构。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[str, AllowedType]。此注解声明所有字典值均为同一类型,但未指定应包含哪些键。
    • typing.TypedDict 的用户定义子类。通过这种方法,您可以指定键名称,并为与每个键关联的值定义不同的类型。
    • 用户定义的数据类。与 TypedDict 子类一样,这种方法可让您指定键名称,并为与每个键关联的值定义不同的类型。
使用 genai.protos.Schema 协议缓冲区定义架构

Gemini API genai.protos.Schema 协议缓冲区定义支持一些类型提示不支持的其他架构功能,包括:

  • 字符串的枚举
  • 指定数字类型的格式(例如,整数的 int32int64
  • 指定哪些字段是必填字段。

如果您需要这些功能,请使用函数调用:低级别访问中所述的方法之一实例化 genai.protos.Schema

使用枚举来约束输出

在某些情况下,您可能希望模型从选项列表中选择一个选项。如需实现此行为,您可以在架构中传递枚举。您可以在 response_schema 中可以使用 str 的任何位置使用枚举选项,因为枚举实际上是字符串列表。与 JSON 架构一样,枚举可让您约束模型输出,以满足应用的要求。

例如,假设您正在开发一款应用,用于将乐器图片分类到以下五个类别之一:"Percussion""String""Woodwind""Brass" 或“Keyboard”。您可以创建一个枚举来帮助完成此任务。

在运行本部分中的代码示例之前,请务必导入 Google 生成式 AI 库:

import google.generativeai as genai

在以下示例中,您将枚举类 Choice 作为 response_schema 传递,模型应选择最合适的枚举选项。

import google.generativeai as genai

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 架构的子集(架构)。您也可以将架构作为 JSON 传递:

import google.generativeai as genai

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 google.generativeai as genai

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

如需开始使用枚举,请试用 enum 快速入门 Colab