ADK Structured Output

Use schemas to make sure inputs and outputs are correctly shaped — useful when passing information between agents.

Three relevant agent fields

  • input_schema (optional) — defines the expected input structure. If set, the user message content passed to this agent must be a JSON string conforming to the schema. Your instructions should guide the user or preceding agent accordingly.
  • output_schema (optional) — defines the desired output structure. If set, the agent’s final response must be a JSON string conforming to the schema.
    • Constraint: can’t be used together with tools or with transferring/delegating to other agents.
  • output_key (optional) — provide a string key. If set, the text content of the agent’s final response is automatically saved to the session’s state dictionary under this key. Useful for passing results between agents or workflow steps.
    • Example: output_key="found_capital" → stores result in state['found_capital'].

Example — Pydantic schema + output_key

from pydantic import BaseModel, Field
 
class CapitalOutput(BaseModel):
    capital: str = Field(description="The capital of the country.")
    # the agent returns an object with the country's capital
 
structured_capital_agent = LlmAgent(
    # ... name, model, description
    instruction="""You are a Capital Information Agent. Given a country, respond ONLY with a JSON object containing the capital. Format: {"capital": "capital_name"}""",
    output_schema=CapitalOutput,     # Enforce JSON output
    output_key="found_capital",      # Store result in state['found_capital']
    # Cannot use tools=[get_capital_city] effectively here
)

Describe the schema clearly in the instruction

IMPORTANT: Your response MUST be valid JSON matching this structure:
{
    "subject": "Subject line here",
    "body": "Email body here with proper paragraphs and formatting"
}
 
DO NOT include any explanations or additional text outside the JSON response.

This returns:

{"subject": "Coffee tomorrow morning?", "body": "Hi etc."}

In state we then see:

email:
    subject: ...
    body: ...

This state is overwritten the next time an email is written.

See next