您可以将 Gemini 配置为生成结构化输出(而非非结构化文本),以便准确提取和标准化信息,以便进一步处理。例如,您可以使用结构化输出从简历中提取信息,并对其进行标准化以构建结构化数据库。
生成 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
传递,从而限制模型选择最合适的选项。
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
:
Literal["Percussion", "String", "Woodwind", "Brass", "Keyboard"]
您还可以将架构作为 JSON 传递:
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
枚举为每个标题指定一个热门程度等级:
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
->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 中使用的架构字段,请参阅架构参考文档。
媒体资源排序
在 Gemini API 中使用 JSON 架构时,属性的顺序非常重要。默认情况下,该 API 会按字母顺序对房源进行排序,而不会保留房源的定义顺序(不过 Google Gen AI SDK 可能会保留此顺序)。如果您向配置了架构的模型提供示例,并且示例的属性顺序与架构的属性顺序不一致,则输出可能会杂乱无章或出乎意料。
为确保属性的排序一致且可预测,您可以使用可选的 propertyOrdering[]
字段。
"propertyOrdering": ["recipeName", "ingredients"]
propertyOrdering[]
(不是 OpenAPI 规范中的标准字段)是一个字符串数组,用于确定响应中的属性顺序。通过指定属性的顺序,然后提供按相同顺序排列属性的示例,您有望提高结果的质量。仅当您手动创建 types.Schema
时,propertyOrdering
才受支持。
Python 中的架构
使用 Python 库时,response_schema
的值必须为以下某个值:
- 类型,如在类型注解中所用(请参阅 Python
typing
模块) genai.types.Schema
的实例genai.types.Schema
的dict
等效项
定义架构的最简单方法是使用 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 模型。通过这种方法,您可以指定键名称,并为与每个键关联的值定义不同的类型,包括嵌套结构。
最佳做法
使用响应架构时,请牢记以下注意事项和最佳实践:
- 回答架构的大小会计入输入 token 限制。
- 默认情况下,字段是可选的,这意味着模型可以填充字段或跳过字段。您可以将字段设置为必填字段,以强制模型提供值。如果关联的输入提示中上下文不足,模型会主要基于其训练所依据的数据生成回答。
复杂的架构可能会导致
InvalidArgument: 400
错误。复杂性可能来自属性名称过长、数组长度限制过长、枚举值过多、对象具有许多可选属性,或者是这些因素的组合。如果您在使用有效架构时看到此错误,请进行以下一项或多项更改以解决此错误:
- 缩短属性名称或枚举名称。
- 展平嵌套数组。
- 减少存在限制的属性的数量,例如具有下限和上限的数量。
- 减少存在复杂限制的属性的数量,例如采用
date-time
等复杂格式的属性。 - 减少可选属性的数量。
- 减少枚举的有效值数量。
如果您未看到预期结果,请在输入提示中添加更多上下文或修改响应架构。例如,查看非结构化输出情况下模型的响应,以了解模型的响应方式。然后,您可以更新响应架构,使其更贴合模型的输出。
后续步骤
现在,您已经了解了如何生成结构化输出,不妨试试使用 Gemini API 工具: