Inspiration
Every "AI travel agent" built in the last two years is the same thing wearing a different skin: a chatbot wrapper around a search box. Ask it to plan a trip and it gives you the same five landmarks it would give anyone — because it isn't reasoning from you, it's reasoning from whatever's statistically common in its training data. That's not personalization. That's a guess with good grammar.
Agents aregetting smarter, but they're culturally blind." That sentence described exactly what was wrong with every travel AI we'd tried they can plan a day-by-day schedule, but they have no idea who they're planning it for. A traveler who loves Afrobeats, slow mornings, and street food should get a fundamentally different Lisbon than someone who loves minimalist design, early starts, and fine dining. No LLM can know that on its own. A taste graph can.
Nala is our answer: a voice-first travel agent that uses Qloo's taste graph as the actual decision-making substrate, not a sprinkle of flavor text on top of a generic plan.
What it does
You tell Nala two or three things you genuinely love — an artist, a show, a cuisine, a brand, anything — and the city you're headed to. In real time, you watch Nala:
- Resolve your favorites into real entities on Qloo's taste graph (not just text matching — actual disambiguated cultural entities).
- Query Qloo's Insights API for places in your destination city that score highly against your specific taste signals — not "top 10 things to do in Lisbon," but the five restaurants, neighborhoods, and venues that overlap with what you've already told us you love.
- Bridge your home culture to your destination's — Nala surfaces local artists, musicians, and media in the destination city that share taste-graph affinity with your existing favorites, so you land somewhere unfamiliar already knowing what to listen to and who to look for.
- Narrate, out loud, in a warm conversational voice (via AssemblyAI), an itinerary built only from what Qloo actually returned — Nala is not allowed to recommend a place the taste graph didn't surface.
The UI shows its own reasoning step-by-step — "Resolving your favorites," "Finding culturally-matched places," "Finding local artists who match your taste" — so nothing is a black box. And we put a generic, non-personalized itinerary for the same city right next to Nala's, side by side, so the difference isn't a claim — it's visible.
How we built it
- Qloo API is the brain:
/searchto resolve free-text favorites into taste-graph entities,/v2/tagsto pull shared taste signals across those entities, and/v2/insightsto generate taste-weighted places and cross-domain cultural matches (we deliberately avoided the legacy/recommendationsendpoints per the hackathon's own guidance, and usedfeature.explainability=trueon every Insights call so we could show why each recommendation was chosen, not just what it was). - Lovable scaffolded our UI and Supabase project fast, so we could spend our limited hours on the Qloo logic instead of boilerplate.
- Codex is where we wrote the real agent orchestration — a Supabase Edge Function pipeline that chains the Qloo calls, enforces a grounding check (an LLM response is rejected and regenerated if it mentions a place the taste graph never returned), and runs the generic-vs-grounded comparison in parallel.
- AssemblyAI powers the voice layer end to end: real-time streaming speech-to-text for input (using short-lived server-minted tokens, never exposing our API key client-side), and text-to-speech so Nala speaks the final itinerary back in a natural voice.
- Supabase (Postgres) stores trips, resolved entities, and the full Qloo reasoning trace so every past session is replayable — useful for debugging and genuinely satisfying to scroll back through during the build.
Challenges we ran into
- Keeping the LLM honest. The single hardest problem wasn't calling Qloo — it was stopping our language model from quietly "helping" by adding a plausible-sounding restaurant that Qloo never returned. We had to build an explicit grounding check that strips or regenerates any place/artist mention not present in the actual Qloo response set.
- Making Qloo visible, not just useful. It would have been easy to call the API server-side and just show a nice itinerary — but that hides the entire point of entering this hackathon. We spent real time building the live step-by-step trace UI specifically so judges (and users) can see Qloo doing the work, including the explainability scores behind each pick.
- Latency stacking. Resolving multiple favorites, then querying shared tags, then places, then the cultural bridge, is four-plus sequential API surfaces. We parallelized everything that didn't have a hard dependency and used the trace UI itself to turn "waiting" into part of the experience rather than dead air.
- Voice without exposing secrets. AssemblyAI's own docs are blunt that you should never expose a permanent API key client-side — so our first working voice prototype had to be thrown out and rebuilt around server-minted, single-use temporary tokens.
Accomplishments that we're proud of
- A genuinely agentic pipeline — multi-step, inspectable, and falsifiable — not a single prompt pretending to be an agent.
- The side-by-side comparison screen, which turns "trust us, it's personalized" into something a judge can see with their own eyes in under thirty seconds.
- A full closed-loop voice experience: speak your favorites, hear your itinerary back, with zero exposed secrets anywhere in the client bundle.
- Every single cultural recommendation Nala makes traces back to a real Qloo entity ID and an explainability score — nothing in the itinerary is unaccountable.
What we learned
- A taste graph is a fundamentally different kind of ground truth than an LLM's training data — it's current, explicit, and queryable, where an LLM's "knowledge" of what's popular is frozen, implicit, and unverifiable.
- Explainability isn't a nice-to-have bolted on at the end — designing the UI around showing the reasoning changed how we built the backend from day one, because every API call had to produce something worth displaying.
- Constraining an LLM to narrate rather than decide produces dramatically more trustworthy output than giving it the freedom to recommend.
What's next for Nala - AI Travel Agent
- Real-time voice conversation (upgrading from turn-based STT/TTS to a full streaming voice session) so Nala feels like a live phone call with a travel agent, not a form with a microphone button.
- Multilingual taste resolution, so a favorite typed in Portuguese, Twi, or Bahasa resolves against Qloo exactly as reliably as English input.
- Real booking integration once we're past hackathon scope, so the loop goes all the way from "tell Nala what you love" to a confirmed reservation.
- Group trips — resolving shared taste overlap across multiple travelers so Nala can plan a trip that's genuinely grounded in everyone's taste, not just one person's.
Built With
- anthropic
- assemblyai
- assemblyai-streaming
- claude
- css3
- cursor
- deno
- framer-motion
- html5
- javascript
- lovable
- postgresql
- qloo
- qloo-api
- react
- rest-api
- shadcn-ui
- supabase
- supabase-edge-functions
- tailwindcss
- typescript
- vercel
- vite
- webspeech-api
Log in or sign up for Devpost to join the conversation.