Skip to content
Learn Agentic AI
Learn Agentic AI11 min read3 views

Gemini Structured Output: Getting JSON and Typed Responses from Google AI

Learn how to get reliable JSON output from Gemini using response_mime_type, JSON schemas, enum constraints, and validation. Build agents that produce machine-readable structured data every time.

Why Structured Output Matters for Agents

Agents that produce free-form text are limited to human consumption. Agents that produce structured data can feed into databases, trigger workflows, update dashboards, and chain into other agents. When your classification agent returns {"sentiment": "negative", "urgency": "high", "category": "billing"} instead of a paragraph, downstream systems can act on it immediately.

Gemini supports native structured output through JSON mode and schema constraints. Unlike prompt-based approaches that ask the model to "return JSON," Gemini's structured output is enforced at the model level — the output is guaranteed to be valid JSON matching your schema.

Basic JSON Mode

The simplest approach sets the response MIME type to JSON:

flowchart TD
    START["Gemini Structured Output: Getting JSON and Typed …"] --> A
    A["Why Structured Output Matters for Agents"]
    A --> B
    B["Basic JSON Mode"]
    B --> C
    C["Schema-Constrained Output"]
    C --> D
    D["Extracting Structured Data from Documen…"]
    D --> E
    E["Array Responses for Batch Processing"]
    E --> F
    F["Validation Pattern for Production"]
    F --> G
    G["FAQ"]
    G --> DONE["Key Takeaways"]
    style START fill:#4f46e5,stroke:#4338ca,color:#fff
    style DONE fill:#059669,stroke:#047857,color:#fff
import google.generativeai as genai
import json
import os

genai.configure(api_key=os.environ["GOOGLE_API_KEY"])

model = genai.GenerativeModel(
    "gemini-2.0-flash",
    generation_config=genai.GenerationConfig(
        response_mime_type="application/json",
    ),
)

response = model.generate_content(
    "Analyze the sentiment of this review: "
    "'The product arrived late but the quality exceeded my expectations. "
    "Customer support was unhelpful when I asked about the delay.'"
)

data = json.loads(response.text)
print(json.dumps(data, indent=2))

With JSON mode enabled, the response is guaranteed to be valid JSON. However, the schema is inferred from the prompt — the model decides what keys and types to use.

Schema-Constrained Output

For production agents, define an explicit schema to guarantee the response structure:

import google.generativeai as genai
from google.generativeai.types import GenerationConfig
import json
import os

genai.configure(api_key=os.environ["GOOGLE_API_KEY"])

# Define the expected output schema
review_schema = {
    "type": "object",
    "properties": {
        "sentiment": {
            "type": "string",
            "enum": ["positive", "negative", "mixed", "neutral"],
        },
        "urgency": {
            "type": "string",
            "enum": ["low", "medium", "high"],
        },
        "topics": {
            "type": "array",
            "items": {"type": "string"},
        },
        "summary": {
            "type": "string",
        },
        "confidence_score": {
            "type": "number",
        },
    },
    "required": ["sentiment", "urgency", "topics", "summary", "confidence_score"],
}

model = genai.GenerativeModel(
    "gemini-2.0-flash",
    generation_config=GenerationConfig(
        response_mime_type="application/json",
        response_schema=review_schema,
    ),
)

response = model.generate_content(
    "Analyze this customer review: 'I have been waiting 3 weeks for my refund. "
    "Every time I call, I get transferred to a different department. This is unacceptable.'"
)

result = json.loads(response.text)
print(f"Sentiment: {result['sentiment']}")
print(f"Urgency: {result['urgency']}")
print(f"Topics: {result['topics']}")

The enum constraint is powerful — it forces the model to choose from your predefined categories, eliminating inconsistent labels like "somewhat positive" or "POSITIVE" that break downstream logic.

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

Extracting Structured Data from Documents

A common agent pattern is extracting structured records from unstructured text:

invoice_schema = {
    "type": "object",
    "properties": {
        "vendor_name": {"type": "string"},
        "invoice_number": {"type": "string"},
        "date": {"type": "string", "description": "ISO 8601 format"},
        "line_items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "description": {"type": "string"},
                    "quantity": {"type": "integer"},
                    "unit_price": {"type": "number"},
                    "total": {"type": "number"},
                },
                "required": ["description", "quantity", "unit_price", "total"],
            },
        },
        "subtotal": {"type": "number"},
        "tax": {"type": "number"},
        "total": {"type": "number"},
    },
    "required": ["vendor_name", "invoice_number", "date", "line_items", "total"],
}

model = genai.GenerativeModel(
    "gemini-2.0-flash",
    generation_config=GenerationConfig(
        response_mime_type="application/json",
        response_schema=invoice_schema,
    ),
)

# Works with both text and image inputs
invoice_image = genai.upload_file("invoice_scan.pdf")
response = model.generate_content([
    "Extract all invoice details from this document.",
    invoice_image,
])

invoice_data = json.loads(response.text)

Array Responses for Batch Processing

When you need multiple structured items from a single prompt, use an array schema:

batch_schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "email": {"type": "string"},
            "intent": {
                "type": "string",
                "enum": ["support", "sales", "billing", "feedback", "spam"],
            },
            "priority": {
                "type": "string",
                "enum": ["low", "medium", "high", "critical"],
            },
            "suggested_response": {"type": "string"},
        },
        "required": ["email", "intent", "priority", "suggested_response"],
    },
}

model = genai.GenerativeModel(
    "gemini-2.0-flash",
    generation_config=GenerationConfig(
        response_mime_type="application/json",
        response_schema=batch_schema,
    ),
)

emails_text = """
Email 1: "Our production server is down, we need immediate help!"
Email 2: "Can you send me pricing for the enterprise plan?"
Email 3: "Just wanted to say your product saved us 20 hours this week."
"""

response = model.generate_content(
    f"Classify each email and suggest a response:\n{emails_text}"
)

classified = json.loads(response.text)
for item in classified:
    print(f"Intent: {item['intent']} | Priority: {item['priority']}")

Validation Pattern for Production

Always validate structured output even with schema enforcement:

from pydantic import BaseModel, field_validator
from typing import Literal

class ReviewAnalysis(BaseModel):
    sentiment: Literal["positive", "negative", "mixed", "neutral"]
    urgency: Literal["low", "medium", "high"]
    topics: list[str]
    summary: str
    confidence_score: float

    @field_validator("confidence_score")
    @classmethod
    def validate_confidence(cls, v):
        if not 0 <= v <= 1:
            raise ValueError("confidence_score must be between 0 and 1")
        return v

# Parse and validate
raw = json.loads(response.text)
validated = ReviewAnalysis(**raw)

FAQ

Does structured output work with streaming?

Yes, but the JSON is only valid once the full response is received. During streaming, you receive partial JSON that cannot be parsed until complete. If you need progressive results, use a streaming JSON parser or wait for the complete response.

What happens if the model cannot match the schema?

If the model cannot generate valid output matching your schema, the response may be empty or contain a minimal valid structure. This is rare with well-designed schemas but can occur with overly restrictive constraints or contradictory requirements.

Can I use Pydantic models directly as the schema?

Not directly in the google-generativeai SDK. You need to pass a JSON Schema dictionary. However, you can generate the schema from a Pydantic model using ReviewAnalysis.model_json_schema() and pass that to response_schema.


#GoogleGemini #StructuredOutput #JSON #DataExtraction #Python #AgenticAI #LearnAI #AIEngineering

Share
C

Written by

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.

Related Articles You May Like

AI Interview Prep

7 AI Coding Interview Questions From Anthropic, Meta & OpenAI (2026 Edition)

Real AI coding interview questions from Anthropic, Meta, and OpenAI in 2026. Includes implementing attention from scratch, Anthropic's progressive coding screens, Meta's AI-assisted round, and vector search — with solution approaches.

Learn Agentic AI

Building a Multi-Agent Data Pipeline: Ingestion, Transformation, and Analysis Agents

Build a three-agent data pipeline with ingestion, transformation, and analysis agents that process data from APIs, CSVs, and databases using Python.

Learn Agentic AI

OpenAI Agents SDK in 2026: Building Multi-Agent Systems with Handoffs and Guardrails

Complete tutorial on the OpenAI Agents SDK covering agent creation, tool definitions, handoff patterns between specialist agents, and input/output guardrails for safe AI systems.

Learn Agentic AI

Building a Research Agent with Web Search and Report Generation: Complete Tutorial

Build a research agent that searches the web, extracts and synthesizes data, and generates formatted reports using OpenAI Agents SDK and web search tools.

Learn Agentic AI

Build a Customer Support Agent from Scratch: Python, OpenAI, and Twilio in 60 Minutes

Step-by-step tutorial to build a production-ready customer support AI agent using Python FastAPI, OpenAI Agents SDK, and Twilio Voice with five integrated tools.

Learn Agentic AI

LangGraph Agent Patterns 2026: Building Stateful Multi-Step AI Workflows

Complete LangGraph tutorial covering state machines for agents, conditional edges, human-in-the-loop patterns, checkpointing, and parallel execution with full code examples.