Skip to main content

Lab 4 Solution: Structured Haiku & Sentiment Analysis

Goal

In this lab, we evolved the "Haiku Poet" into a structured analyzer. We used a Pydantic schema to force the agent to return data (JSON) instead of just text, and we used output_key to persist that data in the session state.

haiku_poet_agent/agent.py

from pydantic import BaseModel
from google.adk.agents import LlmAgent

# Define the structured output schema
class HaikuAnalysis(BaseModel):
haiku: str
sentiment: str

# Define the root agent with v1.0 structured features
root_agent = LlmAgent(
name="haiku_analyzer_agent",
model="gemini-2.5-flash",
description="An agent that writes a haiku and analyzes the sentiment of the input.",
instruction="""
You are a wise analyzer. Your task is to:
1. Write a haiku (5-7-5 syllables) based on the user's input.
2. Categorize the sentiment of the input as "positive", "negative", or "neutral".

You MUST respond only with a JSON object matching the requested schema.
""",
output_schema=HaikuAnalysis, # Force the LLM to follow the Pydantic model
output_key="last_analysis" # Automatically save the JSON to session state
)

Key Changes Explained

  1. Pydantic Model: By defining HaikuAnalysis, we create a formal contract for the agent's output. The ADK uses this to tell the model exactly how to format the JSON.
  2. output_schema: This parameter activates the "Structured Output" mode. It simplifies parsing because the ADK handles the validation. If the model returns malformed JSON, the ADK will automatically try to correct it (or throw a clear error).
  3. output_key: By setting this to "last_analysis", every time the agent finishes a turn, the resulting JSON is stored in ctx.session.state["last_analysis"]. This makes the data available for debugging or for other agents in the same session.

Self-Reflection Answers

  1. Why is it better to use output_schema instead of just asking the LLM to "respond in JSON" in the text instructions?

    • Answer: While text instructions work occasionally, they are unreliable. LLMs often add preamble (e.g., "Sure, here is your JSON:") or slightly vary the keys. output_schema leverages the model's native constrained decoding capabilities (when supported) or applies strict validation and automatic retries by the ADK, ensuring the output is always 100% valid JSON that your code can depend on.
  2. What happened to the agent's ability to use tools once you enabled output_schema? Why does the ADK enforce this restriction?

    • Answer: The agent can no longer use tools. The ADK enforces this because structured output mode optimizes the model's generation process specifically for following a schema. Mixing tool-calling (which involves a separate "reasoning" loop) with strict JSON generation is complex and error-prone. If you need both, you should use a multi-agent system: one agent to use tools and another to format the final result into JSON.
  3. Look at the Dev UI's "Session State". How could another agent in a future multi-agent system use the data stored in the "last_analysis" key?

    • Answer: In a multi-agent workflow (like a SequentialAgent), the next agent in the chain can access ctx.session.state["last_analysis"]. For example, a "Reviewer Agent" could check the sentiment and, if it's "negative," change its own instruction to be more empathetic, all without having to re-parse the previous agent's text response.