结构化输出

您可以将 Gemini 配置为生成结构化输出(而非非结构化文本),以便准确提取和标准化信息,以便进一步处理。例如,您可以使用结构化输出从简历中提取信息,并对其进行标准化以构建结构化数据库。

Gemini 可以生成 JSON枚举值作为结构化输出。

生成 JSON

您可以通过以下两种方式使用 Gemini API 生成 JSON:

  • 在模型上配置架构
  • 在文本提示中提供架构

在模型上配置架构是生成 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(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。如需获得更确定性、更高质量的回答,请在模型上配置架构,并避免在文本提示中重复架构。

生成枚举值

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

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

在以下示例中,您将枚举作为 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 架构(架构)的子集。

您还可以通过以下两种方式指定枚举。您可以使用 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

除了基本多选题之外,您还可以在 JSON 架构中的任何位置使用枚举。例如,您可以请求模型提供食谱标题列表,并使用 Grade 枚举为每个标题指定一个热门程度等级:

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 架构简介

使用 responseSchema 参数将模型配置为 JSON 输出时,需要依赖 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 -> enumformatnullable
  • integer -> formatminimummaximumenumnullable
  • number -> formatminimummaximumenumnullable
  • boolean -> nullable
  • array -> minItemsmaxItemsitemsnullable
  • object -> propertiesrequiredpropertyOrderingnullable

以下是一些示例架构,展示了有效的类型和字段组合:

{ "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 中使用的架构字段,请参阅架构参考文档

媒体资源排序

在 Gemini API 中使用 JSON 架构时,属性的顺序非常重要。默认情况下,该 API 会按字母顺序对房源进行排序,而不会保留房源的定义顺序(不过 Google Gen AI SDK 可能会保留此顺序)。如果您向配置了架构的模型提供示例,并且示例的属性顺序与架构的属性顺序不一致,则输出可能会杂乱无章或出乎意料。

为确保属性的排序一致且可预测,您可以使用可选的 propertyOrdering[] 字段。

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

propertyOrdering[](不是 OpenAPI 规范中的标准字段)是一个字符串数组,用于确定响应中的属性顺序。通过指定属性的顺序,然后提供按相同顺序排列属性的示例,您有望提高结果的质量。仅当您手动创建 types.Schema 时,propertyOrdering 才受支持。

Python 中的架构

使用 Python 库时,response_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 模型。通过这种方法,您可以指定键名称,并为与每个键关联的值定义不同的类型,包括嵌套结构。

最佳做法

使用响应架构时,请牢记以下注意事项和最佳实践:

  • 回答架构的大小会计入输入 token 限制。
  • 默认情况下,字段是可选的,这意味着模型可以填充字段或跳过字段。您可以将字段设置为必填字段,以强制模型提供值。如果关联的输入提示中上下文不足,模型会主要基于其训练所依据的数据生成回答。
  • 复杂的架构可能会导致 InvalidArgument: 400 错误。复杂性可能来自属性名称过长、数组长度限制过长、枚举值过多、对象具有许多可选属性,或者是这些因素的组合。

    如果您在使用有效架构时看到此错误,请进行以下一项或多项更改以解决此错误:

    • 缩短属性名称或枚举名称。
    • 展平嵌套数组。
    • 减少存在限制的属性的数量,例如具有下限和上限的数量。
    • 减少存在复杂限制的属性的数量,例如采用 date-time 等复杂格式的属性。
    • 减少可选属性的数量。
    • 减少枚举的有效值数量。
  • 如果您未看到预期结果,请在输入提示中添加更多上下文或修改响应架构。例如,查看非结构化输出情况下模型的响应,以了解模型的响应方式。然后,您可以更新响应架构,使其更贴合模型的输出。

后续步骤

现在,您已经了解了如何生成结构化输出,不妨试试使用 Gemini API 工具: