Intro to Structured Output with the Gemini API
Source notebook
Repo path:
gemini/controlled-generation/intro_controlled_generation.ipynb· Open on GitHub · intro
Shows how to make Gemini 2.5 Flash return JSON, enums, and schema-constrained multimodal outputs.
Summary
This notebook teaches controlled generation with the Gemini API in Vertex AI using the Google Gen AI SDK. It walks through JSON output with Pydantic models, OpenAPI-style schemas, and preview JSON Schema, then applies the same pattern to enums, game character data, log extraction, review sentiment, image object detection, and order updates with conditional fields.
Key code patterns
Create enterprise GenAI client
from google import genai
client = genai.Client(
enterprise=True,
project=PROJECT_ID,
location=LOCATION,
)Connects the notebook to a Google Cloud project and location before calling Gemini.
Pydantic JSON schema
class CountryInfo(BaseModel):
name: str
population: int
capital: str
response = client.models.generate_content(
model=MODEL_ID,
contents="Fetch key facts for the United States.",
config=GenerateContentConfig(
response_mime_type="application/json",
response_schema=CountryInfo,
),
)Uses a Pydantic model as the response schema so Gemini returns predictable JSON.
Parsed structured response
country: CountryInfo = response.parsed
print(country.name)
print(country.population)
print(country.capital)Shows that structured output can be consumed as a typed parsed object, not only raw text.
OpenAPI-style schema
response_schema = {
"type": "OBJECT",
"properties": {"name": {"type": "STRING"}},
"required": ["name"],
}
config=GenerateContentConfig(
response_mime_type="application/json",
response_schema=response_schema,
)Demonstrates dictionary schemas with required fields for JSON generation.
Preview JSON Schema
response = client.models.generate_content(
model=MODEL_ID,
contents="Fetch key facts for the United Kingdom.",
config=GenerateContentConfig(
response_mime_type="application/json",
response_json_schema=country_info_schema,
),
)Uses response_json_schema for JSON Schema features such as conditional requirements.
Enum output
class InstrumentEnum(Enum):
PERCUSSION = "Percussion"
STRING = "String"
response = client.models.generate_content(
model=MODEL_ID,
contents="What instrument plays multiple notes at once?",
config=GenerateContentConfig(
response_mime_type="text/x.enum",
response_schema=InstrumentEnum,
),
)Constrains the model to return one value from a predefined enum.
Multimodal structured output
contents=[
Part.from_uri(
file_uri="gs://cloud-samples-data/generative-ai/image/office-desk.jpeg",
mime_type="image/jpeg",
),
prompt,
]Combines Cloud Storage image inputs with a JSON response schema for object detection.
Safety settings with schema
safety_settings=[
SafetySetting(
category="HARM_CATEGORY_DANGEROUS_CONTENT",
threshold="BLOCK_LOW_AND_ABOVE",
)
]Shows safety controls can be passed alongside response_mime_type and response_schema.
Models & APIs used
- Models: gemini-2.5-flash
- APIs / services: Vertex AI, Agent Platform API, Cloud Storage
- SDKs / libraries:
google-genai,pydantic
When to use this
Use this pattern when an application needs Gemini responses in predictable JSON or enum formats for reliable downstream processing.
Gotchas & caveats
- The notebook requires a Google Cloud project and the Agent Platform API enabled.
- Colab users must run auth.authenticate_user before using the client.
- PROJECT_ID falls back to GOOGLE_CLOUD_PROJECT and LOCATION falls back to GOOGLE_CLOUD_REGION.
- The examples set LOCATION to global.
- JSON Schema support is described as preview.
- For OpenAPI schema, only enum, items, maxItems, nullable, properties, and required are listed as supported; other fields are ignored.
- Fields are optional by default unless listed in required.
- Cloud Storage image examples depend on gs://cloud-samples-data image URIs being accessible.
Best practices
- Set response_mime_type to application/json for JSON outputs.
- Use response_schema with Pydantic or OpenAPI-style schemas for controlled JSON generation.
- Use response_json_schema when JSON Schema conditional logic is needed.
- Use response.parsed to consume structured outputs as objects or dictionaries.
- Use text/x.enum when the model must choose from predefined enum values.
- Mark fields as required when the model must provide them.
- Use nullable fields when the prompt may not contain enough context for a meaningful value.
- Apply safety_settings together with controlled generation for content-sensitive prompts.
Related
- Concepts: Getting Started · Gemini Capabilities · Prompt Engineering
- Entities: Vertex AI · Google GenAI SDK · Cloud Storage · Gemini
- Area: Gemini Notebooks
- Best practices: Getting Started - Best Practices · Gemini Capabilities - Best Practices · Prompt Engineering - Best Practices