Google 官方模型页将稳定版 gemini-3.8-flash 的 Structured outputs 标为 Supported;结构化输出文档给出的 exact model 配置是 response_format:type="text"、mime_type="application/json",再把 JSON Schema 放入 schema。它能约束 JSON 的语法和形状,但应用仍须验证字段语义,并处理 schema 过大、嵌套过深或不被支持的情况。
适合的任务:信息抽取、固定枚举分类、结构化摘要、为下游 API 准备类型化输入,以及需要流式处理 JSON 片段的任务。
不适合的任务:把 JSON 合法当成事实正确或安全授权;模型生成的字段仍是不可信输入,不能绕过业务校验、权限和人工确认。
适用的模型版本:稳定版 gemini-3.8-flash,API 模型 ID 与官方代码中的 model 字符串一一对应。
适用的客户端、Agent 或 API:Google Gemini API 的 Interactions API。Google GenAI SDK 支持用 Pydantic(Python)和 Zod(JavaScript)定义 schema;其他 SDK、代理框架或第三方平台需自行核对字段映射。
输出说明:模型页将输出模态列为 Text;结构化 JSON 通过文本响应返回,不应将其误解为独立的 JSON 输出模态。
下面保留 Google 结构化输出示例的核心 schema、模型 ID 和请求字段;Recipe.model_json_schema() 由 Pydantic 生成 JSON Schema,model_validate_json 在应用侧解析并校验返回值。
from google import genai
from pydantic import BaseModel, Field
from typing import List, Optional
class Ingredient(BaseModel):
name: str = Field(description="Name of the ingredient.")
quantity: str = Field(description="Quantity of the ingredient, including units.")
class Recipe(BaseModel):
recipe_name: str = Field(description="The name of the recipe.")
prep_time_minutes: Optional[int] = Field(
description="Optional time in minutes to prepare the recipe."
)
ingredients: List[Ingredient]
instructions: List[str]
client = genai.Client()
prompt = """
Please extract the recipe from the following text.
The user wants to make delicious chocolate chip cookies.
They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,
1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,
3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.
For the best part, they'll need 2 cups of semisweet chocolate chips.
First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,
baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar
until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry
ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons
onto ungreased baking sheets and bake for 9 to 11 minutes.
"""
interaction = client.interactions.create(
model="gemini-3.8-flash",
input=prompt,
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Recipe.model_json_schema()
},
)
recipe = Recipe.model_validate_json(interaction.output_text)
print(recipe)不使用 Pydantic 时,保持官方请求字段不变,将 schema 直接传入:
response_format = {
"type": "text",
"mime_type": "application/json",
"schema": {
"type": "object",
"properties": {
"label": {
"type": "string",
"enum": ["positive", "neutral", "negative"],
"description": "The classification label."
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "A confidence score between 0 and 1."
}
},
"required": ["label", "confidence"],
"additionalProperties": False
}
}
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Classify the sentiment of: The new UI is incredibly intuitive.",
response_format=response_format,
)官方示例通过 stream=True 创建流;每个 step.delta 的文本块是可拼接的有效 JSON 片段。不要在收到第一个片段时就把它当成完整对象,需在结束后拼接并执行最终 schema 校验。
from pydantic import BaseModel
from typing import Literal
class Feedback(BaseModel):
sentiment: Literal["positive", "neutral", "negative"]
summary: str
stream = client.interactions.create(
model="gemini-3.8-flash",
input="The new UI is incredibly intuitive. Add a very long summary to test streaming!",
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Feedback.model_json_schema()
},
stream=True
)
for event in stream:
if event.event_type == "step.delta":
if event.delta.type == "text" and getattr(event.delta, "text", None):
print(event.delta.text, end="", flush=True)Google 文档明确说明这是 JSON Schema 的子集,当前可使用:
| 类别 | 支持项 |
|---|---|
| 基础类型 | string、number、integer、boolean、object、array、null |
| 描述属性 | title、description |
| 对象 | properties、required、additionalProperties |
| 字符串 | enum、format(如 date-time、date、time) |
| 数字 | enum、minimum、maximum |
| 数组 | items、prefixItems、minItems、maxItems |
允许空值时,应把 null 放进类型数组,例如 {"type": ["string", "null"]}。schema 中的 description 用于引导模型,不是应用层的数据验证或权限规则。
Structured outputs:格式化最终回答;适合要求最终结果具有固定结构的任务。
Function calling:对话期间提出要执行的函数及参数;应用负责校验、执行和回传结果。
结构化输出 + 内置工具:Google 文档将该组合标为 Preview,且示例使用 Gemini 3 系列模型;不要把文档中的 gemini-3.1-pro-preview 示例改写成 3.8 专属的工具保证。Gemini 3.8 Flash 的模型页分别列出 Structured outputs、Function calling 和搜索等能力,但是否能在目标账户、SDK 版本和具体工具组合中使用,仍需实测。
固定 model="gemini-3.8-flash",先用小型 object schema 验证 SDK、账户和 Interactions API 的字段映射。
检查响应是否能被 JSON 解析,再用 Pydantic、Zod 或等价校验器验证类型、枚举、数值范围、必填字段和业务规则。
逐步增加嵌套层级和数组约束;记录 schema 被拒绝、解析失败、字段缺失及语义错误,避免把复杂 schema 问题归因于提示词。
对流式请求只增量消费文本,结束后再拼接和校验完整 JSON;失败时保留可诊断的错误状态,不把半截对象交给下游。
若同时启用工具,先独立验证结构化输出,再验证工具调用;对工具参数执行白名单、权限、幂等和人工确认检查。
| 官方页面 | 可核实内容 | 本文使用方式 |
|---|---|---|
| Gemini 3.8 Flash 模型页 | 模型 ID 为 gemini-3.8-flash;稳定版;Structured outputs Supported;输入 token 上限 1,048,576,输出 token 上限 65,536 | 证明 exact model 与能力状态,不把 token 上限当成每次请求建议值 |
| 结构化输出文档 | Python 示例使用 client.interactions.create、response_format、mime_type="application/json" 和 schema;支持 Pydantic/Zod;可流式输出 | 形成可执行配置与流式处理约束 |
| 结构化输出文档的 JSON Schema 支持段 | 仅支持 JSON Schema 子集,并警告 schema 过大或嵌套过深可能被拒绝 | 形成 schema 设计和错误处理边界 |
Structured outputs 主要保证输出符合语法和声明的形状;Google 明确要求应用自行验证值,并为“符合 schema 但语义错误”的结果实现错误处理。
“Supported”不等于所有地区、账户层级、SDK 版本、代理框架或第三方路由都已同步;生产上线前要做真实 smoke test。
JSON Schema 只实现官方列出的子集;未列出的关键字不能假定有效。大型或深层嵌套 schema 可能被拒绝。
schema 中的 description 是模型引导信息,不能承担权限、隐私、SQL 注入防护或业务授权职责。
流式块可拼接为最终 JSON,但中间片段不一定是完整对象;必须在结束后完成解析和业务校验。
结构化输出和函数调用解决不同问题。任何写入、付款、发信、删除或设备控制都必须由应用侧权限、审计和人工确认保护。
模型页的 token 上限、能力开关、价格和生命周期可能变化;本文仅记录 2026-09-08 采集时的官方页面状态。
Google 的核心配置要求是:使用 text 类型并将 mime_type 设为 application/json,然后在 schema 字段提供 JSON Schema。工程上应把它视为“可校验的输出契约”,而不是事实正确性或执行权限的保证。
Gemini 3.8 Flash