本文根據 Gemini API 官方文檔(Structured outputs 的 Interactions 版與 generateContent 版、Quickstart、OpenAI compatibility、Troubleshooting guide)、官方 SDK 倉庫和 Google 官方網誌整理,資料核對於 2026-10-10。
適用於誰
- 想讓 Gemini 返回固定字段的 JSON,再存數據庫或傳給下游程序的開發者;
- 搜「gemini structured output」「gemini api json schema」「json mode」「pydantic」的人;
- 以前靠在提示詞裏寫「請只輸出 JSON」,但總是遇到多餘文字或字段缺失的人。
基礎調用方法見本站《Gemini API Python 調用教學:安裝 google-genai SDK、流式輸出、多輪對話與傳圖片》。
結論先說
- 結構化輸出就是在請求裏附一份 JSON Schema,模型生成的文本會是符合這份 Schema 的 JSON 字符串。
- 新版 Interactions API 的寫法:
response_format={"type": "text", "mime_type": "application/json", "schema": 你的Schema}。 - Python 用 Pydantic、JavaScript 用 Zod 最省事:用它們定義結構、導出 Schema,再用同一個定義校驗返回結果。
- 語法正確不等於內容正確:官方提醒輸出保證是合法 JSON,但字段的值仍要在程序裏校驗。
- 只支持 JSON Schema 的一個子集,過大或嵌套過深的 Schema 可能被拒絕。
一、什麼時候用結構化輸出
官方列的三類典型用途:
- 數據提取:從一段文字裏抽出姓名、日期、金額等字段;
- 結構化分類:把文本歸入預先定義好的類別;
- 智能體流程:為工具或下游接口生成結構化的輸入。
它和函數調用(function calling)都用到 JSON Schema,但目的不同。官方的區分是:結構化輸出用來規定最終回答的格式;函數調用用於對話過程中讓模型請你執行某個動作,拿到結果後它再繼續回答。
二、Python:用 Pydantic 定義結構
python
from typing import List, Literal, Optional
from google import genai
from pydantic import BaseModel, Field
class Item(BaseModel):
name: str = Field(description="商品名稱")
quantity: int = Field(description="購買數量")
class Order(BaseModel):
customer: str = Field(description="下單人姓名")
items: List[Item]
urgency: Literal["普通", "加急"] = Field(description="是否加急")
note: Optional[str] = Field(description="備註,原文沒有提到就為空")
client = genai.Client()
text = "王芳要訂 3 箱礦泉水和 2 包 A4 紙,明天上午必須送到,送貨前先打個電話。"
interaction = client.interactions.create(
model="gemini-3.8-flash",
input=f"請從下面這段話裏提取訂單資料:\n{text}",
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Order.model_json_schema(), # Pydantic 導出 JSON Schema
},
)
order = Order.model_validate_json(interaction.output_text) # 解析並校驗
print(order.customer, order.urgency, [i.name for i in order.items])
幾個寫法要點:
Field(description=...)裏的說明會進入 Schema,官方建議用 description 告訴模型每個字段要什麼;Literal[...]會變成 Schema 裏的enum,適合做分類;Optional[...]表示這個字段可以是null;interaction.output_text是 JSON 字符串,用model_validate_json一步完成解析和類型校驗。
三、JavaScript:JSON Schema 加 Zod 校驗
官方 Interactions 版文檔的寫法是:先寫一份 JSON Schema 傳給 API,再用 Zod 從同一份 Schema 生成校驗器。
javascript
// 先安裝:npm install @google/genai zod
import { GoogleGenAI } from "@google/genai";
import * as z from "zod";
const ticketJsonSchema = {
type: "object",
properties: {
category: {
type: "string",
enum: ["帳單問題", "技術故障", "功能建議", "其他"],
description: "工單類別",
},
summary: { type: "string", description: "一句話概括用戶的問題" },
need_reply: { type: "boolean", description: "是否需要人工回覆" },
},
required: ["category", "summary", "need_reply"],
};
const ticketSchema = z.fromJSONSchema(ticketJsonSchema); // 由同一份 Schema 生成校驗器
const ai = new GoogleGenAI({});
const interaction = await ai.interactions.create({
model: "gemini-3.8-flash",
input: "請給這條用戶反饋分類:『上個月被重複扣了兩次費,麻煩盡快處理。』",
response_format: {
type: "text",
mime_type: "application/json",
schema: ticketJsonSchema,
},
});
const ticket = ticketSchema.parse(JSON.parse(interaction.output_text));
console.log(ticket);
四、支持哪些 Schema 寫法
官方文檔說明,結構化輸出支持 JSON Schema 規範的一個子集:
| 類別 | 支持的內容 |
|---|---|
type | string、number、integer、boolean、object、array、null(可空寫成 {"type": ["string", "null"]}) |
| 說明性字段 | title、description |
| 對象 | properties、required、additionalProperties |
| 字符串 | enum、format(如 date-time、date、time) |
| 數字 | enum、minimum、maximum |
| 數組 | items、prefixItems、minItems、maxItems |
官方示例還演示了 anyOf(讓輸出結構隨內容變化,例如「垃圾資訊」和「正常內容」返回不同字段)和遞歸結構(例如組織架構裏員工下面還有員工)。Google 官方網誌在介紹這項能力時提到,遞歸結構靠 $ref 實現,輸出裏字段的順序會和 Schema 裏鍵的順序保持一致。
五、流式輸出
結構化輸出可以和流式一起用。官方說明,流裏的文本片段是合法的 JSON 局部字符串,把它們按順序拼起來就是完整的 JSON:
python
stream = client.interactions.create(
model="gemini-3.8-flash",
input="……",
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Order.model_json_schema(),
},
stream=True,
)
chunks = []
for event in stream:
if event.event_type == "step.delta" and event.delta.type == "text":
chunks.append(event.delta.text)
order = Order.model_validate_json("".join(chunks))
注意單個片段不是完整 JSON,要等流結束、拼接完成後再解析。
六、和搜尋等工具一起用
官方文檔有一節「Structured outputs with tools」,標註為預覽功能,僅 Gemini 3 系列支持:可以把結構化輸出和 Google 搜尋接地、URL 上下文、代碼執行、文件搜尋以及函數調用組合,例如讓模型先聯網查資料,再按你的 Schema 返回結果。寫法是在同一個請求裏同時傳 tools 和 response_format:
python
interaction = client.interactions.create(
model="gemini-3.1-pro-preview",
input="……",
tools=[{"type": "google_search"}, {"type": "url_context"}],
response_format={
"type": "text",
"mime_type": "application/json",
"schema": MatchResult.model_json_schema(), # MatchResult 是你自己定義的 Pydantic 類
},
)
七、限制與官方建議
限制(官方原話的意思):
- 只是子集:不是所有 JSON Schema 特性都支持;舊版文檔補充說,不支持的屬性會被模型忽略。
- 複雜度:非常大或嵌套很深的 Schema 可能被 API 拒絕。遇到報錯時,官方建議縮短屬性名、減少嵌套、減少約束條件。
最佳實踐:
- 用
description把每個字段說清楚; - 用具體的類型(
integer、string、enum),不要什麼都用字符串; - 提示詞裏仍然要說明任務本身;
- 校驗值:輸出是語法正確的 JSON,但內容是否合理要自己檢查,並為「符合 Schema 但語義不對」的情況準備處理邏輯。
官方 SDK 倉庫的 README 還有一條提醒:不管用哪種方式定義了 Schema,不要在提示詞裏再重複一遍(包括給出期望 JSON 的示例),否則輸出質素可能下降。
官方排錯頁裏和結構化輸出有關的兩條:
- 輸出裏反覆出現重複文本:可能是提示詞裏指定的字段順序和 Schema 不一致。建議不要在提示詞裏規定字段順序,並把所有輸出字段設為必填。
- 輸出裏出現大量重複的換行符:通常是輸入裏帶了
\u、\t這類轉義序列。建議把它們換成 UTF-8 字符,並在系統指令裏說明允許的轉義只有\\、\n和\"。
另外,從 Gemini 3.6 Flash、3.5 Flash-Lite 起,「預填回覆開頭」(讓請求以一段模型角色的內容結尾,比如預先寫一個左花括號來逼模型輸出 JSON)已不被支持,會返回 400。官方給的替代方案正是系統指令和結構化輸出。
八、舊版接口和 OpenAI 兼容寫法
舊版 generateContent:官方文檔頁現在的寫法是把 response_format 放進 config,結構多一層 text:
python
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="……",
config={
"response_format": {
"text": {"mime_type": "application/json", "schema": Order.model_json_schema()}
},
},
)
order = Order.model_validate_json(response.text)
你在較早的官方資料(SDK 倉庫 README、2025 年 11 月的官方網誌)裏還會看到另一種寫法:config 裏寫 response_mime_type: "application/json" 加 response_json_schema。讀舊代碼時知道兩者是一回事即可,新代碼照當前文檔頁寫。
舊版文檔列出的支持模型包括 Gemini 3.8 Flash、3.6 Flash、3.5 Flash-Lite、3.1 Flash-Lite、3.1 Pro Preview 和 2.5 系列。
OpenAI 兼容接口:用 OpenAI SDK 調 Gemini 時,官方示例用的是 client.beta.chat.completions.parse(..., response_format=你的Pydantic類),結果在 completion.choices[0].message.parsed。接入方法見本站《Gemini API 接口地址(Base URL)是什麼:原生端點與 OpenAI 兼容調用寫法》。
常見問題
Q:結構化輸出和「JSON 模式」是一回事嗎?
官方文檔現在統一叫 Structured outputs(結構化輸出),做法就是把 mime_type 設為 application/json 並在 schema 裏給出結構。
Q:返回的 JSON 一定能解析嗎?
官方的表述是輸出為語法合法、符合 Schema 的 JSON 字符串。但有一種情況要防:如果設了很小的最大輸出 token,回答可能被截斷,官方說明這個上限包含思考 token。
Q:字段的值不對怎麼辦?
按官方的最佳實踐,先把 description 寫清楚、類型收緊(能用 enum 就不用自由文本)、在提示詞裏把任務說明白;程序裏保留校驗和兜底邏輯。
Q:圖片、PDF 也能提取成 JSON 嗎?
可以。把文件和提示一起放進 input,再加 response_format,傳文件的方法見 Python 調用教學。舊版文檔還連結了官方示例庫裏「從 PDF 發票和表單提取結構化數據」的例子。
參考資料
- Structured outputs(Interactions API 版,官方):https://ai.google.dev/gemini-api/docs/structured-output
- Structured outputs(generateContent 版,官方):https://ai.google.dev/gemini-api/docs/generate-content/structured-output
- Gemini API quickstart(官方):https://ai.google.dev/gemini-api/docs/quickstart
- OpenAI compatibility(官方):https://ai.google.dev/gemini-api/docs/openai
- Troubleshooting guide(官方):https://ai.google.dev/gemini-api/docs/troubleshooting
- What's new in Gemini 3.6 Flash and 3.5 Flash-Lite(官方):https://ai.google.dev/gemini-api/docs/whats-new-gemini-3.6
- Improving Structured Outputs in the Gemini API(Google 官方網誌):https://blog.google/innovation-and-ai/technology/developers-tools/gemini-api-structured-outputs/
- googleapis/python-genai(官方 SDK 倉庫):https://github.com/googleapis/python-genai
0 條評論
還沒有評論,來搶沙發~