![]()
Touri is an AI-powered multi-agent travel planner built with CrewAI and Groq LLMs. It uses specialized agents for flights, accommodations, and itinerary generation, integrating real-time APIs like FlightAPI.io, Booking.com, OpenWeatherMap, and currency exchange services. Given user travel preferences, Touri automatically creates a complete trip plan with live flight and hotel options, weather-aware itineraries, budget summaries, and PDF export through an interactive Streamlit interface.
Travel planning often requires users to search across multiple platforms for flights, hotels, weather forecasts, currency exchange rates and local activities. This process is time-consuming, fragmented and difficult to optimize, especially when balancing budget, convenience and personal preferences. Traditional travel applications typically provide isolated services rather than an intelligent end-to-end planning experience.
Recent advances in Large Language Models (LLMs) and Agentic AI systems have enabled the development of autonomous agents capable of reasoning, tool usage and collaborative decision-making. Multi-agent architectures are particularly effective for complex tasks because they divide responsibilities among specialized agents that work together toward a common objective.
Touri is an AI-powered multi-agent travel planning system designed to automate the entire trip planning workflow. Built using CrewAI and powered by Groq LLM inference, the platform coordinates specialized agents for flight search, accommodation discovery and itinerary generation. Each agent interacts with real-world APIs to retrieve live travel data, ensuring accurate and up-to-date recommendations. The system combines these outputs into a structured travel plan that includes transportation, lodging, weather-aware itineraries, budget summaries and PDF export functionality through an interactive Streamlit interface.
Planning a complete trip manually is inefficient because travel information is distributed across multiple disconnected services. Users must repeatedly compare flight prices, hotel availability, weather conditions, transportation options and activity schedules while also managing budget constraints and personal travel preferences. This leads to:
Existing travel platforms primarily focus on individual tasks such as booking flights or hotels, rather than providing an autonomous, integrated planning experience. Furthermore, many AI-based systems rely heavily on static datasets or generated responses without grounding their outputs in real-time external data.
Touri functions as an AI-powered digital travel agency that automates the complete travel planning process through a collaborative multi-agent architecture. Instead of requiring users to manually search across multiple platforms, the system intelligently coordinates specialized AI agents to handle different travel-related tasks in parallel.
The platform integrates real-time APIs for flights, accommodations, weather forecasting, and currency conversion, enabling the system to generate accurate and data-driven travel recommendations. Each agent is responsible for a specific domain:
These agents collaborate under a central orchestration layer powered by CrewAI, producing a unified travel plan tailored to the user’s preferences, budget and travel dates.
By combining Agentic AI, Large Language Models and real-time tool integration, Touri transforms traditional travel planning into an intelligent, automated and personalized digital travel agency experience.
The system is designed as a sequential multi-agent pipeline where specialized AI agents collaborate to automate the entire travel planning workflow. Instead of relying on a single monolithic model, the architecture decomposes the planning process into smaller domain-specific tasks handled independently by dedicated agents.
The workflow begins with user input containing travel preferences such as destination, dates, budget, and travel style. The request is then processed through three autonomous agents in sequence:
Finally, the outputs are merged into a structured travel plan and presented through an interactive Streamlit user interface.
User Input
↓
FlightAgent
↓
AccommodationAgent
↓
ItineraryAgent
↓
Travel Plan Assembly
↓
Streamlit UI + PDF Export
All agents inherit from a shared BaseTravelAgent class responsible for LLM initialization, retry handling, tool registration, shared CrewAI configuration.
This abstraction enables consistent behavior across all agents while simplifying scalability and maintenance.
class BaseTravelAgent: GROQ_MODELS = { "llama-70b": "llama-3.3-70b-versatile", "llama-8b": "llama-3.1-8b-instant", "gpt-oss-20b": "openai/gpt-oss-20b", "gpt-oss-120b": "openai/gpt-oss-120b", } def __init__(self, model: str = "llama-70b", temperature: float = 0.3): self.llm = LLM( model=f"groq/{self.GROQ_MODELS[model]}", temperature=temperature, max_retries=6, )
The modular design allows new agents or tools to be integrated into the system without modifying the orchestration logic.
The FlightAgent is responsible for retrieving real-time flight information using FlightAPI.io. The agent receives the user’s origin, destination, travel date, passenger count, and travel class, then invokes the API through a structured CrewAI tool.
The system uses the official FlightAPI.io path-parameter format:
GET https://api.flightapi.io/onewaytrip/{api_key}/{origin}/{dest}/{date}/{adults}/0/0/{class}/USD
The API response contains multiple cross-referenced collections such as itineraries, legs, segments, carriers, places.
The agent resolves these references into clean structured flight objects that include airline name, price, departure time, arrival time, duration, layovers, and booking links.
The AccommodationAgent handles hotel and accommodation discovery through the Booking.com RapidAPI integration. The workflow follows a two-stage retrieval process.
First, the destination city is converted into a Booking.com destination identifier using the locations endpoint: /v1/hotels/locations.
After retrieving the dest_id, the system performs a hotel availability search using: /v1/hotels/search.
The agent filters and structures accommodation results based on pricing, amenities, review score, hotel type and location relevance.
This enables the planner to provide realistic lodging recommendations aligned with the user’s budget and travel preferences.
The ItineraryAgent generates personalized day-by-day travel schedules using destination context, user interests and weather conditions.
The agent integrates the OpenWeatherMap API to retrieve weather forecasts for the travel period. This allows the itinerary generation process to account for environmental conditions when selecting activities.
The generated itineraries include:
This approach creates itineraries that are both practical and context-aware rather than purely generative.
One of the key technical challenges when integrating Groq with CrewAI tools is ensuring compatibility with function-calling schemas. Groq’s API requires every tool to expose an explicit Pydantic schema containing clearly defined properties.
Without a valid schema definition, the API raises a BadRequestError indicating that the required field exists without corresponding properties.
To address this, each tool defines an explicit args_schema using Pydantic models.
class FlightSearchInput(BaseModel): origin: str = Field(..., description="Departure airport IATA code") destination: str = Field(..., description="Arrival airport IATA code") departure_date: str = Field(..., description="Date in YYYY-MM-DD format") return_date: Optional[str] = Field(default=None) adults: int = Field(default=1) travel_class: str = Field(default="ECONOMY")
This design ensures reliable function calling, input validation, predictable tool execution and improved interoperability with Groq LLMs.
Large language models frequently generate responses wrapped in markdown code blocks or mixed with explanatory text. To guarantee reliable parsing, the project implements a custom JSON extraction mechanism based on balanced brace tracking.
The parser scans character-by-character while tracking nested braces and quoted strings to safely identify the first complete JSON object.
def safe_parse_json(text: str): # Strip markdown code blocks if text.startswith("```"): text = text.split("```")[1] # Balanced brace parsing logic
This significantly improves robustness when handling imperfect LLM outputs.
After all agents complete execution, the system applies a deterministic post-processing stage to ensure consistency and correctness.
The _create_travel_plan() pipeline performs several corrections:
LLM-generated dates are overridden using the actual trip start date and itinerary day number.
A single exchange rate is fetched and consistently applied across all travel costs.
The weather forecast is appended directly to the final travel plan.
Flight, accommodation, and activity costs are summed to generate a complete budget breakdown.
This hybrid approach combines LLM reasoning with deterministic validation for greater reliability.
Touri is designed for both technical and non-technical users interested in intelligent travel automation and AI-driven planning systems.
Individuals looking for an automated and personalized way to plan trips without manually browsing multiple platforms for flights, hotels, weather and activities.
Companies seeking to modernize travel planning workflows using AI agents and real-time API integrations.
Developers interested in multi-agent systems, CrewAI orchestration, LLM tool calling, real-world API integration and Agentic AI applications.
Learners exploring practical applications of autonomous AI agents, travel recommendation systems, LLMs and AI workflow orchestration.
{ "departure_city": "Addis Ababa", "destination_city": "Paris", "start_date": "2026-07-10", "end_date": "2026-07-15", "budget": 2500, "currency": "USD", "preferences": { "travel_style": "comfort", "accommodation_preference": "hotel", "flight_class": "economy", "interests": [ "culture", "museums", "food", "architecture" ] } }
{ "flights": [ { "airline": "Air France", "departure_time": "2026-07-10 08:15", "arrival_time": "2026-07-10 15:45", "duration": "7h 30m", "price": 780 } ], "accommodations": [ { "name": "Paris Central Hotel", "price_per_night": 160, "total_price": 800, "amenities": [ "Free WiFi", "Breakfast", "Airport Shuttle" ] } ], "daily_itinerary": [ { "day": 1, "activities": [ "Eiffel Tower Visit", "Seine River Cruise", "French Dinner Experience" ] }, { "day": 2, "activities": [ "Louvre Museum", "Notre-Dame Cathedral", "Montmartre Walking Tour" ] } ], "weather_forecast": { "average_temperature": "24°C", "condition": "Partly Cloudy" }, "budget_summary": { "flights": 780, "accommodation": 800, "activities": 450, "total": 2030 } }
A demonstration video showcasing the end-to-end workflow of Touri.
Touri — AI Multi-Agent Travel Planner
The project follows a modular multi-agent architecture powered by CrewAI.
Frontend (Streamlit UI)
↓
TravelCrew Orchestrator
↓
┌───────────────────────┐
│ Flight Agent │
├───────────────────────┤
│ Accommodation Agent │
├───────────────────────┤
│ Itinerary Agent │
└───────────────────────┘
↓
External APIs + LLM Tools
CrewAI
Groq LLMs
Python
Streamlit
Pydantic
LiteLLM
| API | Purpose |
|---|---|
| FlightAPI.io | Real-time flight search |
| Booking.com RapidAPI | Hotel and accommodation search |
| OpenWeatherMapI | Weather forecasts |
| ExchangeRate API | Currency conversion |
| Groq API | LLM inference |
The application requires the following environment variables:
GROQ_API_KEY=your_groq_key
FLIGHT_API_KEY=your_flightapi_key
RAPIDAPI_KEY=your_rapidapi_key
OPENWEATHER_API_KEY=your_weather_key
EXCHANGE_RATE_API_KEY=your_exchange_key
MIT License
This project is open-source and available for educational, research, and commercial usage under the MIT License.
The project documentation (README.md) includes:
Installation guide
Environment setup
API configuration
Agent workflow explanation
Tool integration details
GitHub Repository:
https://github.com/endx-star/Touri
Problem: Groq rejected tool calls with invalid JSON schema ('required' present but 'properties' missing).
Cause: CrewAI's BaseTool subclasses without args_schema generate schemas with required fields but no properties, which Groq's strict validation rejects.
Fix: Added explicit Pydantic args_schema to all four tools. Resolved completely.
Problem: Flight tool returned {"success": true, "data": {"flights": [ ] } } despite a valid API key.
Cause: The original implementation used query parameters and expected data.status == 'success'. The actual API uses path parameters and returns flat cross-referenced arrays.
Fix: Rewrote URL construction and response parser to match the actual API contract. Flight results populated correctly after fix.
Problem: safe_parse_json failed on outputs like 'Here it is: \n{"flights": [ ] }' and {"accommodations": [...]} \n\nGo ahead: \n{"accommo... (two JSON objects).
Cause: Regex-based extraction with re.DOTALL greedily matched from first { to last }, spanning multiple JSON objects.
Fix: Replaced regex with balanced brace parser. Correctly extracts the first complete JSON object regardless of surrounding text.
Problem: RateLimitError on llama-3.3-70b-versatile (12k TPM) and llama-3.1-8b-instant (6k TPM) during multi-agent execution.
Cause: Three agents executing back-to-back consumed the full TPM budget within one minute.
Fix: Split crew into three sequential mini-crews with 12-second pauses. Combined with exponential backoff retry, the system completes successfully on the free tier.
The system successfully produces complete travel plans end-to-end with the following components and data sources:
| Component | Data Source |
|---|---|
| Flight search | FlightAPI.io |
| Hotel search | Booking.com (RapidAPI) |
| Itinerary generation | Groq LLM + OpenWeatherMap |
| Currency conversion | ExchangeRate API |
Explicit args_schema on all tools is mandatory for Groq function calling without it, 100% of tool calls fail.
LLM output is unreliable for structured data without deterministic post-processing. Dates, in particular, must be corrected server-side regardless of prompt instructions.
Sequential execution with inter-task pauses is sufficient to stay within free-tier TPM limits for a 3-agent system.
Balanced brace parsing is significantly more robust than regex for extracting JSON from LLM output that may contain prose, multiple JSON objects, or markdown formatting.
Touri demonstrates that a multi-agent LLM system can reliably orchestrate real-world API calls to produce actionable, structured travel plans. The key engineering insights from this project are:
1.Tool schema correctness is non-negotiable when using strict function-calling APIs like Groq , Pydantic args_schema must be explicitly defined on every tool.
2. LLM output should be treated as unreliable structured data: deterministic post-processing (date correction, price conversion, JSON extraction) is essential for production reliability.
3. Rate limit management requires architectural decisions, not just retry logic: splitting tasks into separate crews with deliberate pauses is more effective than relying solely on backoff.
4. Agent autonomy should be bounded : max_iter=1 with clear, concise task prompts produces more consistent results than allowing agents to iterate freely, especially under token constraints.
Future work could explore parallel agent execution using async CrewAI flows, integration with booking APIs for direct reservation, and a conversational adjustment interface for iterative plan refinement.
Built by Endale Tegegnework powered by Ready Tensor AI course making intelligent travel plannning accessible to everyone