Lab 18 Solution: Building a Smart Travel Planner
Goal
This file contains the complete code for the agent.py script in the Smart Travel Planner lab.
travel-planner/agent.py
from __future__ import annotations
from google.adk.agents import Agent, ParallelAgent, SequentialAgent
# ============================================================================
# PARALLEL SEARCH AGENTS
# ============================================================================
# ===== Parallel Branch 1: Flight Finder =====
flight_finder = Agent(
name="flight_finder",
model="gemini-2.5-flash",
description="Searches for available flights",
instruction=(
"You are a flight search specialist. Based on the user's travel request, "
"suggest 2-3 realistic flight options.\n"
"\n"
"For each option, include:\n"
"- Airline\n"
"- Approximate departure/arrival times\n"
"- Estimated price\n"
"\n"
"Output ONLY the flight options."
),
output_key="flight_options" # UNIQUE key to avoid conflicts!
)
# ===== Parallel Branch 2: Hotel Finder =====
hotel_finder = Agent(
name="hotel_finder",
model="gemini-2.5-flash",
description="Searches for available hotels",
instruction=(
"You are a hotel search specialist. Based on the user's travel request, "
"suggest 2-3 realistic hotel options.\n"
"\n"
"For each option, include:\n"
"- Hotel Name\n"
"- Star rating\n"
"- Key amenities\n"
"- Estimated price per night\n"
"\n"
"Output ONLY the hotel options."
),
output_key="hotel_options" # UNIQUE key to avoid conflicts!
)
# ===== Parallel Branch 3: Activity Finder =====
activity_finder = Agent(
name="activity_finder",
model="gemini-2.5-flash",
description="Searches for local activities and attractions",
instruction=(
"You are a travel activity specialist. Based on the user's destination, "
"suggest 3-4 must-do activities or attractions.\n"
"\n"
"For each activity, include:\n"
"- Name of attraction\n"
"- Brief description\n"
"- Best time to visit\n"
"- Estimated cost\n"
"\n"
"Output ONLY the activity list."
),
output_key="activity_options" # UNIQUE key to avoid conflicts!
)
# ============================================================================
# SYNTHESIS AGENT
# ============================================================================
# ===== Merger Agent: Itinerary Builder =====
itinerary_builder = Agent(
name="itinerary_builder",
model="gemini-2.5-flash",
description="Compiles the final travel itinerary",
instruction=(
"You are an expert travel agent. Create a complete, day-by-day travel itinerary "
"based on the options provided by your team.\n"
"\n"
"**Flight Options:**\n"
"{flight_options}\n"
"\n"
"**Hotel Options:**\n"
"{hotel_options}\n"
"\n"
"**Activity Options:**\n"
"{activity_options}\n"
"\n"
"Create a cohesive itinerary that:\n"
"1. Selects the best flight and hotel combination (explain your choice briefly).\n"
"2. Organizes the activities into a logical daily schedule.\n"
"3. Adds practical travel tips for the destination.\n"
"\n"
"Format the output as a beautiful, easy-to-read travel plan."
)
)
# ============================================================================
# PIPELINE ASSEMBLY
# ============================================================================
# 1. Create the Parallel Step (Fan-Out)
parallel_search = ParallelAgent(
name="parallel_search",
sub_agents=[
flight_finder,
hotel_finder,
activity_finder
],
description="Executes all search agents concurrently"
)
# 2. Create the Sequential Pipeline (Gather)
travel_planning_system = SequentialAgent(
name="TravelPlanningSystem",
sub_agents=[
parallel_search, # Step 1: Get all data at once
itinerary_builder # Step 2: Synthesize the result
],
description="Full travel planning workflow"
)
# 3. Define Root Agent
root_agent = travel_planning_system
Self-Reflection Answers
-
What would be the performance impact if you replaced the
ParallelAgentin this lab with aSequentialAgent?- Answer: The execution time would increase significantly. In a sequential setup, the total time would be the sum of all three search agents' execution times (Time_Flight + Time_Hotel + Time_Activity). With
ParallelAgent, the total time is roughly equal to the slowest single agent (max(Time_Flight, Time_Hotel, Time_Activity)). For IO-bound tasks like LLM generation or API calls, parallel execution is much faster.
- Answer: The execution time would increase significantly. In a sequential setup, the total time would be the sum of all three search agents' execution times (Time_Flight + Time_Hotel + Time_Activity). With
-
It is critical that the three finder agents have different
output_keys. What would happen if they all had the sameoutput_key, like"search_result"?- Answer: This would cause a race condition. Since they share the same session state object and are running at the same time, they would all try to write to
state['search_result']. The final value in that key would be unpredictable—it would just be whichever agent happened to finish last, overwriting the results of the others. Theitinerary_builderwould then only see one partial result instead of all three.
- Answer: This would cause a race condition. Since they share the same session state object and are running at the same time, they would all try to write to
-
Can you think of another real-world problem (besides travel planning) where the fan-out/gather pattern would be a highly effective architecture?
- Answer:
- Code Review: Run a
SecurityScannerAgent,StyleCheckerAgent, andBugFinderAgentin parallel on a pull request, then use aSummaryAgentto compile a final review report. - Medical Diagnosis: Have specialist agents (Cardiologist, Neurologist, etc.) analyze a patient's chart concurrently, then have a Lead Doctor agent synthesize a diagnosis.
- News Aggregation: Search for "Politics", "Technology", and "Sports" news in parallel, then generate a "Daily Briefing" newsletter.
- Code Review: Run a
- Answer: