Inspiration

Planning an evening with friends always turns into a negotiation. Everyone has different favourite artists, films, shows, books and restaurants — and trying to pick something one person won't mind is a bad way to plan. We wanted the plan itself to be the fun part, where each person's taste is treated as real signal and the pick is genuinely something everyone is excited about. That's what Qloo's taste graph is built for: turn a list of things people love into a map of affinities, shared tags and "whys" — exactly the kind of overlap a group needs to find.

What it does

Each friend (2 to 5) enters their favourite artists, films, shows, books and restaurants into Common Ground. The agent turns that list into a plan for one evening — a movie to watch, a soundtrack artist to listen to and a dinner spot — with two alternates for each pick and a plain-language "why" that cites real Qloo affinity scores and shared tags, so the group can see exactly whose taste the pick connects to.

On a typical run the agent returns something like:

  • Watch: a film from Qloo's recommendations, with two alternates and a "why" citing affinity scores and shared tags across the group.
  • Soundtrack artist: an artist whose taste cluster overlaps with the friends, again with two alternates and an explainable "why".
  • Dinner: a restaurant recommended through Qloo's signal, with two alternates and a "why" tied to a restaurant tag the group shares.

How we built it

Common Ground is a FastAPI service (Python) with a vanilla JavaScript front-end, deployed on Render's free tier (Singapore). httpx is used for outgoing calls and pytest covers the backend with 26 mock tests.

The agent works in a fixed pipeline:

  1. Each friend's list of artists, films, shows, books and restaurants is resolved to Qloo entities with Qloo's /search endpoint.
  2. Every pair of friends is compared with Qloo's /v2/analysis/compare to learn how their tastes overlap and where they diverge.
  3. To turn "dinner" into something Qloo understands, the agent finds the right restaurant tag with Qloo's /v2/tags endpoint.
  4. Recommendations come from Qloo's /v2/insights endpoint. We read signal.interests.entities for the candidate picks, use explainability to get the "why" behind each one, and apply a location filter so the restaurant is actually reachable.

Gemini plans the tool calls. A scripted fallback is wired in so the agent can still return a grounded plan even when an upstream step is slow or partial — every pick still carries a real Qloo affinity score and the tags it shares with the group. The front-end shows a live step trace so you can watch the agent resolve tastes, compare friends, find the restaurant tag and pull recommendations as it runs.

Built with: Python, FastAPI, Qloo, Gemini, JavaScript, HTML, CSS, Render, httpx and pytest. Open source under the MIT license.

Challenges we ran into

  • Getting the "why" to be real. It's easy to return a recommendation with a generic sentence, and hard to make it actually traceable to scores and tags in Qloo's graph. We had to lean on explainability in /v2/insights and fold the real affinity numbers and shared tags back into the plain-language reason, so the "why" matches what the graph says.
  • Mapping friends to a restaurant pick. /v2/insights needs a restaurant tag, so the agent has to resolve "dinner" through /v2/tags and pick the tag that best reflects the group's combined taste. Getting that mapping stable — especially when the group's lists are short — took a few iterations.
  • Keeping the location filter useful. Adding a location filter to the recommendations call is what makes the dinner spot actually reachable, but it can also narrow the candidate set too much and drop the best overlap. We balanced filter strictness against coverage so every evening still gets a real dinner pick.
  • Making Gemini plan reliably. Gemini drives the tool-call sequence, but a planner can be creative in unhelpful ways. We had to constrain the tools it can call and the shape of the inputs it passes, and rely on the scripted fallback to keep the plan grounded when Gemini drifts.
  • Realistic evaluation. Since every pick carries a "why" and alternates, we wrote 26 mock tests in pytest that exercise the agent's decision points — resolution, comparison, tag selection and recommendation — so we could verify the "why" is real and the alternates are generated.

Accomplishments that we're proud of

  • Grounded "whys" that cite real Qloo affinity scores and shared tags, not a vague pitch.
  • A clean two-alternates-everything pattern (movie, artist, dinner, each with two alternates) that gives the group real choice instead of a single rigid pick.
  • Gemini planning the tool calls end-to-end with a scripted fallback, plus a live step trace in the UI so you can see exactly what the agent is doing at each stage.
  • A working stack that ships: FastAPI + vanilla JS + Render, with the Qloo endpoints (/search, /v2/tags, /v2/insights, /v2/analysis/compare) wired in and a 26-test mock suite in pytest.

What we learned

  • Qloo's taste graph is genuinely useful for group decisions. Pairwise /v2/analysis/compare plus /v2/insights with explainability gives you an overlap story and a defensible reason in one pass, which is much stronger than scoring each person independently and averaging.
  • The hardest part of an agent like this isn't calling the APIs — it's keeping the reason honest. Folding real scores and shared tags back into the "why" is what turns a recommendation engine into a planner the group trusts.
  • Constraints are a feature. Confining Gemini to a fixed tool set, a fixed output shape (pick + 2 alternates + "why") and a scripted fallback is what keeps the plan usable. Creativity belongs in the taste graph; the planner's job is to wire it together.

What's next for Common Ground

  • Bigger groups and richer taste: support more than 5 friends, deeper per-friend profiles and activity history so the taste graph has more to work with on repeat runs.
  • More kinds of picks: beyond "watch + soundtrack + dinner" — coffee spots, walks, exhibitions, games — each with the same grounded pick + alternates + "why" pattern.
  • Stronger location handling: neighbourhood-aware filtering, distance weighting and multi-city support so the dinner spot is a real overlap, not just an in-range fallback.
  • Better fallbacks and reliability: richer scripted fallbacks, tighter observability on the tool-call trace and automated smoke tests that run against Qloo's sandbox so grounded "whys" are verified in CI.
  • An open reference for Qloo's agentic use case: polish the live step trace and the explainability cards into a reusable demo that other builders can adapt for group recommendation agents on Qloo.

Built With

Share this project:

Updates

Submission history