Inspiration
Moving to a new city changes your address, but not your taste. Yet your favourite café, the band you always went to see, the film everyone in your circle loved: none of it comes with you. Generic "best of" lists don't help, because a five-star place can still feel like the wrong room. [Add one sentence about your own experience of moving or of someone you know.]
We asked a simple question: what in this city is the equivalent of the thing I loved back home? That is a question about taste, and it's exactly what Qloo's taste graph knows.
What it does
Homecoming translates your taste from the city you left to the city you moved to.
- You name two cities and a few favourites: a place, an artist or a film.
- Qloo finds what people with your taste love in the new city.
- Each match shows the traits it shares with your original, so you can judge the match yourself.
- Jev scores how close the match is, and the best three are kept.
- A short first-weeks plan turns the matches into things to actually do.
How we built it
- Qloo resolves each favourite to an entity with
/search, then/v2/insightsreturns places or artists and films that people with that taste love in the new city. - Jev 1.13 judges each pair. For every candidate it answers two yes/no probability questions, one about atmosphere and one about the role it plays in daily life. The fit score is their average:
$$\text{fit} = \frac{p_{\text{vibe}} + p_{\text{role}}}{2}$$
We fetch eight candidates per favourite, keep the three with the highest fit, and drop any below 0.3 unless that would leave nothing.
- Nemotron writes the first-weeks plan from the matched places and shared tags only. If the model is unavailable, the plan is assembled directly from the matches, so it never invents a venue.
- Frontend: Next.js, React and Tailwind, with a small design system and checked colour contrast. -Backend: FastAPI. Hosted on Vercel and Render.
The three AI pieces each do what they are best at: Qloo finds, Jev judges, the language model writes.
Challenges
- Messy taste data. Early results carried tags like "Restroom" and age brackets, and repeated the same tag twice. We built a tag cleaner so the shared traits shown are actually about taste.
- Weak matches. A hotel showed up as a match for a bakery. Fetching more candidates and letting Jev choose the best fixed most of it, and the labels "strong", "good" and "loose" keep the scores honest.
- Jev only sees tags, not the venues themselves, so we treat its score as a grounded estimate of closeness, not a review.
- Free-tier limits. The hosted language model returned a 403 error, which pushed us to build the no-model fallback plan.
- Shipping. Deployment problems and a design that needed a full rebuild after feedback. Along the way we learned that Tailwind silently drops opacity classes on CSS-variable colours.
What we learned
Grounding matters more than model size. Once a language model is told to use only data from the taste graph, it stops guessing, and splitting the work between a retrieval layer, a fast scorer and a writer made each part easier to test and to fix. Building for failure was just as important: every AI call can fail, and the app still has to work.
What's next
Filtering results by venue type, more domains such as books and food, a "bring a friend" mode that compares a newcomer's taste with a local's, and saving a shortlist.
Built With
- docker
- fastapi
- httpx
- jev
- lucide
- nemotron
- nextjs
- opencode
- pydantic
- python
- qloo
- qloo-api
- react
- render
- tailwindcss
- typesafe-ai
- typescript
- uvicorn
- vercel
Log in or sign up for Devpost to join the conversation.