Building a Smart Travel Planner with crewai and Streamlit
- Naveen
- 0
Planning a trip can be time-consuming, but with the power of AI and Streamlit, you can build your own Smart Travel Planner. This tutorial will guide you step-by-step through creating a web app where intelligent agents handle tasks like finding flights, recommending accommodations, and planning activities.
By the end of this article, you’ll understand how the code works and how to customize it for your needs. Let’s dive in!
Project Structure
Our travel planner consists of four main components:
- Tools – for performing specific actions
- Agents – specialized AI personas with specific roles
- Travel Crew – coordinates the agents
- User Interface – built with Streamlit
Let’s break down each component and build them step by step
1. Creating the Tool Class
First, we’ll create a Tool class that represents different capabilities our agents can use:
class Tool: def __init__(self, name: str, func: callable, description: str): self.name = name self.func = func self.description = description def run(self, input_text: str) -> str: return self.func(input_text)
Each tool has a name, function, and description. This modular approach makes it easy to add new tools later.
2. Building the Agent Class
Next, we’ll create our Agent class. Each agent has a specific role, goal, and set of tools:
class Agent: def __init__(self, role: str, goal: str, backstory: str, tools: List[Tool]): self.role = role self.goal = goal self.backstory = backstory self.tools = tools def execute_task(self, task_description: str) -> str: prompt = f""" Role: {self.role} Goal: {self.goal} Background: {self.backstory} Available Tools: {self._format_tools()} Task: {task_description} Please provide a detailed response considering your role and available tools. """ try: response = completion( model="groq/llama-3.3-70b-versatile", messages=[{ "role": "user", "content": prompt }], temperature=0.1 ) return response['choices'][0]['message']['content'] except Exception as e: return f"Error executing task: {str(e)}"
The agent uses LiteLLM to generate responses based on its role and the given task.
3. Implementing the Travel Crew
The TravelCrew class coordinates our agents:
class TravelCrew: def __init__(self, agents: List[Agent]): self.agents = agents def execute_plan(self, travel_details: Dict[str, Any]) -> Dict[str, str]: results = {} for agent in self.agents: task = self._generate_task(agent, travel_details) results[agent.role] = agent.execute_task(task) return results def _generate_task(self, agent: str, details: Dict[str, Any]) -> str: base_prompt = f""" Plan a trip from {details['from_location']} to {details['to']} with the following details: - Budget: ${details['budget']} - Dates: {details['dates']} - Travelers: {details['travelers']} - Preferences: {details['preferences']} """ return base_prompt
4. Setting Up the Tools and Agents
Now let’s create our specific tools and agents:
# Initialize tools search_tool = Tool( name="Search", func=lambda q: f"Searching for: {q}", description="Search for travel-related information online" ) scrape_tool = Tool( name="Scraper", func=lambda url: f"Scraping data from: {url}", description="Extract information from travel websites" ) # Initialize agents agents = [ Agent( role="Flight Specialist", goal="Find the best flight options within budget", backstory="Expert in flight research with deep knowledge of airlines, routes, and pricing patterns.", tools=[search_tool, scrape_tool] ), # Add other agents here... ] # Initialize crew crew = TravelCrew(agents)
5. Building the Streamlit Interface
Finally, let’s create our user interface with Streamlit:
# Configure page st.set_page_config(page_title="Smart Travel Planner") # Add custom styling st.markdown(""" <style> .reportview-container { background-color: #f0f2f6; } .big-font { font-size: 20px !important; } .stButton>button { background-color: #021526; color: white; font-size: 18px; padding: 10px 24px; border-radius: 5px; } </style> """, unsafe_allow_html=True) # Create input fields col1, col2 = st.columns(2) with col1: from_location = st.text_input("From", placeholder="e.g., New York, USA") to = st.text_input("To", placeholder="e.g., Paris, France") travel_dates = st.text_input("Travel Dates", placeholder="e.g., June 1-7, 2024") budget = st.number_input("Budget (USD)", min_value=100, value=1000) with col2: travelers = st.number_input("Number of Travelers", min_value=1, value=2) preferences = st.text_area("Travel Preferences", placeholder="e.g., food, culture, adventure")
Handling User Input and Generating Plans
The final piece is handling the user’s input and generating the travel plan:
if st.button("Generate Travel Plan"): if not from_location or not to or not travel_dates: st.warning("Please fill in all required fields.") else: with st.spinner("Creating your personalized travel plan..."): travel_details = { "from_location": from_location, "to": to, "dates": travel_dates, "budget": budget, "travelers": travelers, "preferences": preferences } results = crew.execute_plan(travel_details) # Display results st.subheader("Your Travel Plan") for role, result in results.items(): with st.expander(f"💡 {role} Recommendations"): st.write(result)
Putting it all together
import os from litellm import completion from typing import List, Dict, Any import streamlit as st # Configure page st.set_page_config(page_title="Smart Travel Planner") # Styling st.markdown(""" <style> .reportview-container { background-color: #f0f2f6; } .big-font { font-size: 20px !important; } .stButton>button { background-color: #021526; color: white; font-size: 18px; padding: 10px 24px; border-radius: 5px; } </style> """, unsafe_allow_html=True) class Tool: def __init__(self, name: str, func: callable, description: str): self.name = name self.func = func self.description = description def run(self, input_text: str) -> str: return self.func(input_text) class Agent: def __init__(self, role: str, goal: str, backstory: str, tools: List[Tool]): self.role = role self.goal = goal self.backstory = backstory self.tools = tools def execute_task(self, task_description: str) -> str: # Construct the prompt with agent context and tools prompt = f""" Role: {self.role} Goal: {self.goal} Background: {self.backstory} Available Tools: {self._format_tools()} Task: {task_description} Please provide a detailed response considering your role and available tools. """ try: response = completion( model="groq/llama-3.3-70b-versatile", messages=[{ "role": "user", "content": prompt }], temperature=0.7 ) return response['choices'][0]['message']['content'] except Exception as e: return f"Error executing task: {str(e)}" def _format_tools(self) -> str: return "\n".join([f"- {tool.name}: {tool.description}" for tool in self.tools]) class TravelCrew: def __init__(self, agents: List[Agent]): self.agents = agents def execute_plan(self, travel_details: Dict[str, Any]) -> Dict[str, str]: results = {} for agent in self.agents: task = self._generate_task(agent, travel_details) results[agent.role] = agent.execute_task(task) return results def _generate_task(self, agent: str, details: Dict[str, Any]) -> str: base_prompt = f""" Plan a trip from {details['from_location']} to {details['to']} with the following details: - Budget: ${details['budget']} - Dates: {details['dates']} - Travelers: {details['travelers']} - Preferences: {details['preferences']} """ return base_prompt # Initialize tools search_tool = Tool( name="Search", func=lambda q: f"Searching for: {q}", description="Search for travel-related information online" ) scrape_tool = Tool( name="Scraper", func=lambda url: f"Scraping data from: {url}", description="Extract information from travel websites" ) # Initialize agents agents = [ Agent( role="Flight Specialist", goal="Find the best flight options within budget", backstory="""Expert in flight research with deep knowledge of airlines, routes, and pricing patterns. Skilled at finding the best balance between cost and convenience.""", tools=[search_tool, scrape_tool] ), Agent( role="Accommodation Expert", goal="Recommend suitable accommodations", backstory="""Lodging expert with deep knowledge of hotels, vacation rentals, and unique stays. Focuses on value, location, and amenities.""", tools=[search_tool, scrape_tool] ), Agent( role="Activity Planner", goal="Create engaging itineraries", backstory="""Experienced travel coordinator who excels at crafting perfect day-by-day itineraries that balance activities, rest, and travel time.""", tools=[search_tool, scrape_tool] ) ] # Initialize crew crew = TravelCrew(agents) # Streamlit Interface st.title("🌍 Smart Travel Planner") st.markdown("Let AI agents help plan your perfect trip!") # Input Collection col1, col2 = st.columns(2) with col1: from_location = st.text_input("From", placeholder="e.g., New York, USA") to = st.text_input("To", placeholder="e.g., Paris, France") travel_dates = st.text_input("Travel Dates", placeholder="e.g., June 1-7, 2024") budget = st.number_input("Budget (USD)", min_value=100, value=1000) with col2: travelers = st.number_input("Number of Travelers", min_value=1, value=2) preferences = st.text_area("Travel Preferences", placeholder="e.g., food, culture, adventure") if st.button("Generate Travel Plan"): if not from_location or not to or not travel_dates: st.warning("Please fill in all required fields.") else: with st.spinner("Creating your personalized travel plan..."): travel_details = { "from_location": from_location, "to": to, "dates": travel_dates, "budget": budget, "travelers": travelers, "preferences": preferences } results = crew.execute_plan(travel_details) # Display results st.subheader("Your Travel Plan") for role, result in results.items(): with st.expander(f"💡 {role} Recommendations"): st.write(result) st.info("Note: This is an AI-generated plan. Please verify all details before making reservations.")
Running the Application
To run your travel planner, save all the code in a file (e.g., travel_planner.py
) and run:
streamlit run travel_planner.py
Key Features and Benefits
- Modular Design: Easy to add new tools and agents
- Role-Based Agents: Specialized expertise for different aspects of travel planning
- User-Friendly Interface: Clean, intuitive design with Streamlit
- AI-Powered Recommendations: Personalized travel plans based on user preferences
- Expandable Architecture: Ready for additional features and improvements
Areas for Enhancement
- Add more sophisticated tools for real-time flight and hotel data
- Implement caching for faster responses
- Add support for multiple currencies
- Include weather data integration
- Add map visualization for itineraries
Conclusion
We’ve built a functional AI-powered travel planner that combines the power of large language models with a user-friendly interface. The modular design makes it easy to extend and improve the application as needed.
Remember to handle API keys securely and add proper error handling before deploying to production.
Author
-
Naveen Pandey has more than 2 years of experience in data science and machine learning. He is an experienced Machine Learning Engineer with a strong background in data analysis, natural language processing, and machine learning. Holding a Bachelor of Science in Information Technology from Sikkim Manipal University, he excels in leveraging cutting-edge technologies such as Large Language Models (LLMs), TensorFlow, PyTorch, and Hugging Face to develop innovative solutions.
View all posts