Inspiration
Planning a night out with friends usually ends in a long chat and the same old place. One person loves ramen and Radiohead, another loves Taylor Swift and natural wine, and nobody wants to be the one who decides. I wanted a helper that looks at everyone's taste at once and finds a place that works for the whole group, not just for one person.
What it does
You enter a city, an occasion (for example "Friday evening: dinner, then drinks") and a few words about each friend: artists, films, shows, books, food. The agent:
- plans 3–5 stops that fit the occasion, with at least one stop driven by each friend's own tastes,
- turns each friend's tastes into Qloo entities,
- builds a cross-domain Qloo taste profile for each friend: the kinds of places people with those music, film and book tastes over-index on (in our Kyiv run, Radiohead + Blade Runner 2049 gave live music bar, art gallery and museum; Taylor Swift + Pride and Prejudice gave winery and tea house),
- finds real venues in that city that match the group's combined taste,
- checks each venue against every friend separately,
- returns a short plan: one venue per stop, where Qloo ranked that venue for each friend on their own ("#1 of 49 for Anna", or "not in Olya's top 50"), a one-line reason for each friend, two alternatives, and map and website links,
- lets you share the plan or copy it as text for the group chat.
Every agent step and every API call is shown live on the page, so you can see how it reached the answer.
How we built it
- Next.js 14 on Vercel, with one server route that streams the agent's steps to the browser.
- An LLM (Google Gemini flash-lite first, Featherless Qwen2.5-14B-Instruct as a fallback, and a plain parser/template if both fail) does two jobs: planning the stops at the start and writing the reasons at the end. It may only pick venues that Qloo returned; any other venue id is ignored.
- All the taste matching is done by Qloo. The Qloo key stays on the server, and no Qloo data is stored.
How we use Qloo
/searchturns names like "Wes Anderson" or "Peaky Blinders" into entity IDs. We search with and without the guessed type and keep only results whose name really matches./v2/tags(withfilter.parents.types=urn:entity:place) turns a stop like "ramen" or "wine bar" into place tags./v2/insightswithfilter.type=urn:entity:place,filter.location.query,filter.tagsandsignal.interests.entities(everyone's IDs) gives venues ranked by group affinity./v2/insightsagain, once per friend with only that friend's entities (up to 50 venues in the same category), gives a personal ranking. We use it to prefer places that fit everybody and to show each friend's rank for the chosen venue. The rank comes straight from Qloo's order, not from the LLM./v2/insightswithfilter.type=urn:tagandfilter.tag.types=urn:tag:genre:place, signalled by each friend's entities, gives that friend's taste profile across domains. It is shown on the page, and the writer may only cite profile tags that Qloo actually returned. When a chosen venue carries one of those tags, the friend gets a "Qloo profile: …" badge.
Without Qloo the app has no venues, no rankings and no taste profiles. An LLM on its own would only guess.
Challenges we ran into
- Wrong parameters do not return an error, just an empty list. Some tags (for example one of the "coffee" tags) return nothing in a given city, so the agent tries several tags from
/v2/tagsand keeps the first one that returns real places. - Search is fuzzy. "Wes Anderson" first gave us a musician, and "Studio Ghibli" with a movie type gave unrelated films. We added name matching to avoid that.
- Bursts of parallel calls hit rate limits (HTTP 429), so we added a small queue with retries.
- Keeping the whole agent fast enough for a web request. Our first version took 10–45 seconds. Putting the faster LLM first brought a three-friend London plan to about 8 seconds in our runs on 23 October; the Qloo part is about 4 seconds of that.
- Honest scores. Our first per-friend score was "affinity divided by that friend's best venue", which put almost every venue at 90–100% for everyone. We switched to Qloo's own rank for each friend, which shows real differences (for example #1 of 49 for one friend and #14 for another).
Accomplishments that we're proud of
- It works with real data for real cities. We tested it with Kyiv and London.
- The answer is explainable: you see each API call, each friend's Qloo rank for every venue, and a reason for each friend.
- Every venue in the plan was returned by Qloo for that city. The LLM can't add a place of its own.
What we learned
Taste data is much better than the LLM alone at picking places. The LLM is good at planning and explaining, but the venues and the scores have to come from real data.
What's next
- Optional time and budget filters and opening hours.
- Sharing a plan link with the group so friends can vote.
- More stop types (concerts, events) using other Qloo entity types.
Built With
- next.js
- qloo-taste-ai-api
- vercel
Log in or sign up for Devpost to join the conversation.