Inspiration

Group plans fail in a predictable way: everyone's tastes get averaged, and the person with the most unusual taste gets steamrolled. Qloo knows how tastes relate across music, film, food and places, which is exactly what you need to reason about a group instead of one person. TasteBridge started as a two-person "common ground" agent. This version asks what changes at five people with real conflicts.

What it does

  • Seat 2 to 8 guests. Give each a few things they love (artists, films, shows, books, games, brands, foods, places, vibes) and hard no's. Mark a guest of honor.
  • The agent resolves each anchor to a real Qloo entity, asks Qloo what each person would enjoy at every stop, and measures where tastes conflict on five scales: loud vs quiet, spicy vs mild, nightlife vs family-friendly, experimental vs mainstream, expensive vs budget.
  • It builds a multi-stop plan (activity, dinner, drinks and dessert, wind-down, plus an encore if someone is left out), scored with 0.5 × group coverage + 0.3 × lowest individual fit + 0.2 × conflict-free.
  • Every stop shows why it fits, who it serves, the conflict it carries and how the plan handles it, and the Qloo entity IDs, tags and affinity scores behind it.
  • It shows its work: the venues it ruled out and why (a hard no, the guest of honor's veto, the budget, or closed at that hour per Qloo's listed hours), and what a plain "highest average" ranking would have picked instead.
  • One click rebalances a single stop while keeping everyone's win, and every change is logged as a revision.
  • A side-by-side view compares the same request planned with Qloo and with a generic recommender. The original two-person flow is still included.
  • It is also a CLI and an MCP server (plan_group_outing, rebalance_group_plan, find_common_ground, resolve_taste_anchors).

How Qloo powers it

Qloo is the only source of cultural knowledge in the product.

  1. /search resolves free text like "Mad Max" to real entities with tags.
  2. /v2/tags resolves foods and vibes and gives verified tag IDs for each kind of stop.
  3. /v2/insights with signal.interests.entities returns venues for each person's tastes, filtered by locality and price level.
  4. /v2/insights with filter.results.entities scores every pooled venue for every person in one call, and feature.explainability says which of a person's anchors drove each match.
  5. Qloo's tags on a person's anchors are what we place on the five conflict scales, so conflicts come from Qloo's taste graph and not from keywords the user typed.

Without Qloo there is no venue, no affinity number and no conflict to show. The comparison view demonstrates exactly that.

How we built it

TypeScript on Node 20 with no build step. A real agent loop (plan, resolve, retrieve, reflect and retry, score, synthesize) whose trace streams to the UI as it happens. Server-side caching with in-flight de-duplication, rate limiting, 429 and 5xx backoff, and stale-if-error. The Qloo key never reaches the browser, and without a key the app runs in a clearly labelled sample-data mode. The interface is drawn as engineering plans: the table is a plan view, conflicts are cables under tension that become truss spans when the plan bridges them, and the evening is a bridge elevation.

Challenges we ran into

  • Qloo scoring calls that use tag signals took about 14 seconds each, versus under one second for entity signals, so scoring uses entity anchors wherever a person has them.
  • Locality matching is fuzzy: an unknown city can resolve to a small town elsewhere. Every venue is checked against the requested city and the plan warns where Qloo actually placed it.
  • Live restaurants carry dozens of descriptive tags, which made every restaurant look like every kind of stop until classification used category tags only.
  • Qloo's listed hours are sometimes wrong, so ruled-out reasons say "per Qloo's listed hours".
  • A "personal win" was too easy to earn. Wins now need a real lead over the rest of the table, with an honestly labelled "closest fit" for guests who have none.

Accomplishments that we're proud of

  • A measured evaluation instead of claims. Across 60 random groups (sample data), an independently written checker found no broken hard rule, while a plain highest-average ranker broke one at about 8% of stops. Everyone had a win or a closest fit in every group, and the number of people sharing each "personal win" fell from about 2.4 to about 1.7.
  • A full plan for five people on live Qloo data in about 30 seconds cold, with no fallbacks.
  • Honest limits: average lowest-person fit is about level with a naive ranker (61.4% vs 61.7%). The gains are in rule-keeping, fewer badly served people, and visible reasoning.

What we learned

Fairness is less about a score than about what you refuse to do: ruling out a venue for a stated reason, showing what a naive ranking would have cost, and labelling a closest fit as a closest fit.

What's next for TasteBridge Groups

Reservations and map links, saved and shareable plans, a learned conflict model in place of keyword rules, real-user validation, and using Qloo trends and audiences to weight the group.

Built With

Share this project:

Updates

Submission history