0% found this document useful (0 votes)
3 views8 pages

Structured Output - Solution

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views8 pages

Structured Output - Solution

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

The solution:

Structured output

with pydantic

Enforcing JSON with output_schema

According to ADK documentation, 


use Pydantic BaseModel to define the exact structure you need:

from pydantic import BaseModel, Field

class ProductInfo(BaseModel):

product_name: str = Field(description="The name of the product")

price: float = Field(description="The price in USD")

storage: str = Field(description="The storage capacity")

structured_agent = LlmAgent(

model="gemini-2.5-flash",

instruction="""Extract product information and respond with JSON.

Format: {"product_name": "name", "price": 999.99, "storage": "256GB"}""",

output_schema=ProductInfo # Enforces this exact structure

From ADK docs:

“output_schema (optional): Define a schema representing the desired output structure.

If set, the agent’s final response must be a JSON string conforming to this schema.”

Reference: ADK docs - Structuring data


Core concepts
1. Defining schemas with Pydantic
2. Using output_schema in agents

Create a Pydantic model that represents your Apply the schema to your agent:
desired output:

from pydantic import BaseModel, Field

structured_agent = LlmAgent(

model="gemini-2.5-flash",

class CapitalOutput(BaseModel):
name="capital_finder",

capital: str = instruction="""You are a Capital


Field(description="The capital of the Information Agent.

country") Given a country, respond ONLY with


a JSON object containing the capital.

Format: {"capital":
"capital_name"}""",

Key points:
output_schema=CapitalOutput #
Enforce JSON output

Must inherit from BaseModel - you cannot


)
use Python dictionaries or plain classes

Each field has a type (str, float, int, bool, etc.)

Use Field(description=...) to help the LLM What this does:

understand each field

Pass the class itself to output_schema, not


The agent must return JSON matching 

the schema

an instance: output_schema=CapitalOutput
Invalid responses are automatically rejected

Important:
Your code gets guaranteed structure

According to ADK documentation, “The input and


output schema is typically a Pydantic BaseModel.”
You must define your schema as a Pydantic class—
dictionaries like {"name": "string"} will not work.

2
3. Storing Results with output_key

Save the agent’s response to session state 
 Important note about 



for later use: multi-agent workflows:

While this module shows output_schema on the


structured_agent = LlmAgent(
root_agent, structured output is equally valuable for
model="gemini-2.5-flash",
intermediate sub-agents in multi-agent workflows
instruction="Extract capital city (covered in course 5). When you have multiple
as JSON",
agents working together, using output_schema on
output_schema=CapitalOutput,
sub-agents ensures consistent data format when
output_key="found_capital" #
passing information between agents. For example:
Store in
[Link]["found_capital"]

)
from pydantic import BaseModel, Field

from typing import List, Dict

class ApiResponse(BaseModel):

status: str =
Field(description="success, error, or
partial")

status_code: int =
Field(description="HTTP status code")

data: Dict =
Field(description="Main response
data")

metadata: Dict =
Field(description="Request metadata")
# Must define to appear

errors: List[str] =
Field(default=[], description="Error
messages if any")

# Without 'metadata' in the schema,


the model won't include it in output

# The schema is a contract—only


defined fields appear in responses

3
4. Complex schemas

Build more sophisticated structures: Important—Schema completeness:

The schema defines the EXACT output structure.


The LLM will ONLY include fields you define in your
from pydantic import BaseModel, Field
Pydantic BaseModel. If you need nested objects like
from typing import List, Optional

metadata, errors, or pagination in your output, you


must explicitly define them all in the schema:
class ProductDetails(BaseModel):

name: str =
Field(description="Product name")

price: float = from pydantic import BaseModel, Field

Field(description="Price in USD")
from typing import List, Dict

storage_options: List[str] =
Field(description="Available storage class ApiResponse(BaseModel):

capacities")
status: str =
in_stock: bool = Field(description="success, error, or
Field(description="Whether the partial")

product is in stock")
status_code: int =
discount: Optional[float] = Field(description="HTTP status code")

Field(default=None, data: Dict =


description="Discount percentage if Field(description="Main response
any")

data")

metadata: Dict =
product_agent = LlmAgent(
Field(description="Request metadata")
model="gemini-2.5-flash",
# Must define to appear

instruction="""Extract complete errors: List[str] =


product information as JSON.
Field(default=[], description="Error
Include: name, price, messages if any")

storage_options (list), in_stock


(boolean), and discount (if # Without 'metadata' in the schema,
mentioned).""",
the model won't include it in output

output_schema=ProductDetails
# The schema is a contract—only
) defined fields appear in responses

Supported types:
This ensures you get exactly the structure you

need, nothing more, nothing less.

Basic: str, int, float, bool

Collections: List[T], Dict[str, T]


Reference: ADK Docs - Structuring Data

Optional: Optional[T] for nullable fields

Nested: Other BaseModel classes

4
Hands-on example
Let’s build a complete product extraction agent with structured output.

Step 1: Create the project

adk create product_extractor

cd product_extractor

Step 2: Write the agent with structured output

Replace the contents of [Link] with:

"""

Product extraction agent with structured JSON output.

Demonstrates ADK's output_schema with Pydantic BaseModel.

"""

from [Link] import LlmAgent

from pydantic import BaseModel, Field

# Step 1: Define the output structure with Pydantic

class ProductInfo(BaseModel):

product_name: str = Field(description="The full name of the product")

price: float = Field(description="The price in USD")

storage: str = Field(description="Storage capacity (e.g., '256GB')")

color: str = Field(default="Not specified", description="Product color if


mentioned")

# Step 2: Create agent with output_schema

root_agent = LlmAgent(

model="gemini-2.5-flash",

name="product_extractor",

description="Extracts product information from user messages and returns


structured JSON",

instruction="""You are a Product Information Extractor.

Your task:

- Read the user's message about a product

- Extract: product_name, price, storage, and color (if mentioned)

- Respond ONLY with valid JSON matching this format:

5
Step 2: Write the agent cont.

"product_name": "product name here",

"price": 999.99,

"storage": "256GB",

"color": "Space Black"

Rules:

- price must be a number (no dollar signs)

- storage must include unit (GB, TB)

- If color not mentioned, use "Not specified"

- Output ONLY the JSON, no explanation text""",

output_schema=ProductInfo, # Enforce this exact structure

output_key="extracted_product" # Store result in session state

Step 3: Run and test

adk web

Visit [Link] and test these inputs:

Test 1: Complete information

You: "I want the iPhone 15 Pro with 256GB in Space Black for $999"

Expected JSON output:

"product_name": "iPhone 15 Pro",

"price": 999.0,

"storage": "256GB",

"color": "Space Black"

6
Step 3: Run and test cont.

Test 2: Missing color

You: "Samsung Galaxy S24 with 512GB, costs $1199"

Expected JSON output:

"product_name": "Samsung Galaxy S24",

"price": 1199.0,

"storage": "512GB",

"color": "Not specified"

Test 3: Different format

You: "Get me a MacBook Pro 1TB, price is $2499"

Expected JSON output:

"product_name": "MacBook Pro",

"price": 2499.0,

"storage": "1TB",

"color": "Not specified"

What to notice:
Output is always valid JSON

Same structure every time

Missing fields get default values

Easy to parse in your application

7
Key takeaways
output_schema enforces structured JSON output using Pydantic BaseModel

Pass the class (not an instance): output_schema=ProductInfo

output_key stores results in session state for workflow integration

Instructions must guide JSON format - tell the agent what to output

Validation is automatic - invalid responses are rejected

Use field descriptions to help the LLM understand each field's purpose

You might also like