Inspiration

Planning with friends is usually stressful. Someone has a tight budget, someone wants fancy food, someone wants to go out, and someone just wants to chill. Most of the time one person ends up doing all the work. We wanted to fix that. SquadPlanner grew out of our own frustration with group chats full of “whatever works” and “you pick.” We wanted a tool that could understand everyone’s preferences, pull in real travel options, and propose plans that actually feel fair instead of overloading one person or blowing up someone’s budget.

What it does

SquadPlanner helps a group describe who they are, what they like, and what they can afford, then turns that into a tailored 2-day trip. Each person enters their home city, budget, a simple preference profile (nightlife, adventure, shopping, food, urban), plus any notes like dietary needs or schedule constraints, along with a few possible weekend dates.

Behind the scenes, the system picks a weekend that works for everyone, then chooses a destination based on a large activity dataset that captures each city’s overall “vibe” and typical costs. It compares these city profiles to the group’s preferences and budget to find the best fit.

Next, it pulls real flight and hotel options, selects choices that match the group’s constraints, and then builds an itinerary. Activities are scored based on how well they match each person’s tastes, and the planner assembles a balanced morning–afternoon–evening schedule for both days.

To wrap up, it estimates each person’s total trip cost and checks how fair and affordable the plan is across the group. The final output is a clear itinerary with the chosen city, dates, flights, hotel, daily plan, and a simple budget-fairness summary.

How we built it

We built a Flask backend with MongoDB to store user and city data, and a React frontend that collects group inputs and displays the final trip plan and fairness results.

The planning engine lives in trip_planner.py and is powered by Gemini and LangChain. We created a custom activities.csv by filtering the Yelp academic dataset down to high-quality spots in a handful of cities, tagging each place with five vibe dimensions and a simple price signal. This became the foundation for scoring both cities and activities.

The engine uses Python and NumPy to normalize user preferences, build city-level vibe and cost profiles, score activities, and calculate a budget-fairness metric. These functions are exposed as LangChain tools. Additional tools call SerpAPI to fetch and clean flight and hotel data, and a Gemini-powered tool re-scores activities with suggested times and short explanations.

A LangChain agent running on Gemini coordinates the entire workflow: pick a city, compare weekend options and flights, select a hotel, score activities, build a 2-day itinerary, and evaluate fairness. The backend exposes this as an API, and the frontend renders the chosen city, itinerary, costs, and fairness summary.

Challenges we ran into

One major challenge was getting the agent to actually use tools instead of just talking about them. We had to refine prompts, adjust tool schemas, and tweak how we passed input so Gemini would call ⁠ choose_city_tool ⁠, then the flight and hotel tools, then the activity scoring and fairness tools in sequence instead of simply narrating what it would do. Balancing creativity with constraint-respecting behavior was also difficult; the enjoyment tool needed to stay within budgets, honor notes like “no early mornings,” and still suggest interesting activities.

Hooking up real flight and hotel APIs introduced its own issues. SerpAPI’s Google Flights and Hotels outputs are powerful but not perfectly uniform, so we had to debug inconsistent fields, missing prices, and rate limits while still exposing a clean format like price, airline, and times for flights and price per night, rating, and area for hotels. Designing a fairness model that felt intuitive was also non-trivial. We iterated on how to combine affordability and equality so that the fairness score matched what people intuitively felt was a fair or unfair plan. Finally, front-to-back integration required careful validation of tool outputs and model responses so that the Flask backend and React frontend always received data in the shapes they expected.

Accomplishments that we're proud of

We are proud that SquadPlanner is not just a single prompt but a full AI itinerary engine. It combines a curated Yelp-based activity dataset, city scoring, real-time flights and hotels, LLM-based enjoyment scoring, and a fairness model, all orchestrated by an agent built with LangChain and Gemini. Turning the raw Yelp academic dataset into a compact ⁠ activities.csv ⁠ with meaningful vibe tags and price proxies made the recommendations feel grounded and controllable.

We are also proud of the fairness layer. The budget fairness metric not only produces a single score for the trip but also per-person labels that make it clear who is being stretched by the plan. End-to-end, the system forms a smooth pipeline from database to backend to AI engine to frontend, where users enter preferences and budgets, the agent runs tools behind the scenes, and the final plan appears with explanations and cost breakdowns. Most importantly, when we ran our own friend groups through SquadPlanner, the suggestions and fairness feedback actually helped us have more grounded conversations about where to go and what everyone could afford.

What we learned

We learned that agentic AI feels much more like systems design than just prompt writing. Once tools are involved, you are designing workflows and data flows: which tool runs when, what JSON structures move between them, and how the LLM should recover from errors. We also saw how important data engineering is for AI products. The quality of ⁠ activities.csv ⁠—filtering Yelp, defining vibe tags, and adding price proxies—had a huge impact on how good the itineraries felt.

We were reminded of the importance of validating both tool outputs and model outputs before trusting them. Real APIs and LLMs sometimes return unexpected shapes or edge cases, and building robust validation and clear error handling saved a lot of debugging time. Finally, we learned that fairness is multi-dimensional. It is not enough to keep the total cost under a single number; modeling when something feels fair across people with very different budgets is both challenging and rewarding.

What's next for SquadPlanner

Next, we want to expand beyond the initial city set and enrich the activity dataset with more sources such as events, concerts, and outdoor experiences, along with dynamic signals like weather and local events. We would like to support multi-origin trips where friends fly in from different cities and have the agent choose a destination and routing that minimize total cost and travel pain across the group.

We also want deeper integration with travel APIs so that the system moves closer to one-click booking and can react to live price changes. On the user side, we plan to add accounts and trip history so people can save trips, favorite activities, and reuse their preference profiles, letting the AI learn patterns over time. Finally, we would like to make the planning flow more interactive, where the group can see alternative itineraries such as a slightly cheaper version or a more food-focused version, and have the agent adjust the plan live based on that feedback.

Share this project:

Updates