-
Hero: recorded stress preset by default, plus paste-your-own Lisbon/NYC list with optional taste seeds.
-
Recorded FAIL: Paris (~1,452 km), Cascais (~29 km), an invented name, and Prado failing on taste (24th percentile).
-
After closed-set repair: 6/6 ALLOW — keepers preserved, failed slots replaced from the Qloo-validated pool.
-
Same three places, Radiohead seeds: Prado REWRITE (24%), Taberna and Cevicheria ALLOW.
-
Same list, Kendrick / Uncut Gems / Nike: Prado ALLOW (~56%), Taberna REWRITE (20%) — only Qloo’s taste graph flips the verdict.
-
Judges paste their own agent list (Lisbon or New York) and optionally set up to 3 cross-domain taste seeds.
Inspiration
Travel and dining agents sound confident while recommending a restaurant in the wrong city, inventing a venue, or ignoring the diner's taste. Traditional agent evals check latency and JSON shape, not cultural fit. TasteGuard is a quality gate an agent calls before it shows a list to a user.
What it does
Same restaurant, two tastes. Prado fails for a Radiohead fan (~25th percentile) and passes for a Kendrick Lamar fan (~55–60th). Taberna da Rua das Flores flips the other way (100th vs ~23rd). Same city, same places: only Qloo's cross-domain taste graph changes the verdict.
TasteGuard takes a dinner list for a persona and city (a built-in preset, or paste your own Lisbon / New York list with optional taste seeds), then:
- Verifies the place: resolves each name in Qloo, in-city first, and flags wrong-city or unverified picks with the real distance and locality (e.g. a Paris bistro "in Chiado", 1,452 km away).
- Verifies the taste: scores each verified restaurant against the persona's seeds (artist, film, book, brand) alongside a city-specific set of reference restaurants. A pick is ALLOWED only if it beats 40% of them, and each card shows per-seed contributions.
- Repairs on FAIL: keeps every ALLOW and replaces only the failed slots from a pool Qloo has already validated. Gemini may only choose pool entity IDs; any ID outside the pool is discarded in favour of the top-affinity pick. PASS requires every item to be ALLOW, and repair runs at most 3 rounds.
Other agents can call the same service as MCP tools (tasteguard_evaluate, tasteguard_repair, tasteguard_list_presets).
Try it in 60 seconds
- Open the demo and press Play recorded run (instant). This replays a live Qloo stress run: a Paris venue (~1,452 km) and a Cascais venue (~29 km) claiming Lisbon neighbourhoods, an invented name, and Prado failing on taste. Closed-set repair takes it to 6/6 PASS in one round.
- Under Try your own agent list, choose Lisbon and paste:
Prado | Baixa Taberna da Rua das Flores | Chiado A Cevicheria | Príncipe RealLeave the seeds blank (Radiohead taste) and press Evaluate pasted list. - Paste the same list again with the seeds Kendrick Lamar (artist), Uncut Gems (movie) and Nike (brand). Prado and Taberna swap verdicts.
- Optional: Radiohead · Lisbon dinner (live) runs a list Gemini actually proposed through the same gate. New York is supported but slower.
MCP (e.g. Cursor):
{ "mcpServers": { "tasteguard": { "url": "https://tasteguard-342276031814.us-central1.run.app/mcp/sse" } } }
What makes it Qloo-powered
Qloo makes both decisions; Gemini never does.
- Search (
/search) resolves each name with location, so wrong-city and invented places are caught with distances. - Insights (
/v2/insights) scores the candidates together with city reference restaurants (filter.results.entities) against cross-domain taste seeds (signal.interests.entities: a band, a film, a novel, a brand). - Explainability (
feature.explainability) shows how much each seed contributed to each score. - Without Qloo, the Prado flip is impossible: the restaurant exists and is in Lisbon either way. Only the taste graph says it fits one persona and not the other.
How I built it
- Python / FastAPI: two-stage resolver (in-city first, name normalisation, category and distance checks), shared-set Insights scoring, and a surgical repair loop.
- FastMCP at
/mcp/sse, so agents call evaluate and repair without the UI. Client-supplied entity IDs and pins are ignored, so callers can't skip verification. - React / Vite single-page app with staged propose → evaluate → repair, and paste-your-own-list with optional seeds.
- Terraform + Cloud Build deploying to a public Cloud Run service, with per-IP and daily rate limits to protect the shared Qloo quota.
Challenges I ran into
Live repair used to shrink the list, or re-search pool names and turn good venues into unknowns. I now pin replacements by entity ID, keep the anchor set fixed across repair rounds, and gate the pool by dinner category so cafés and bars stay out. Anchor-relative percentiles also meant the injected keepers had to genuinely clear 40%, so I changed the test list rather than adding a soft affinity floor.
Accomplishments that I'm proud of
- End-to-end FAIL → PASS repair that preserves every ALLOW, in both the recorded and live stress runs.
- One stress list that shows every failure type: wrong city, invented name, and taste miss.
- The two-way taste flip (Prado / Taberna) under Radiohead vs Kendrick seeds.
- Paste-your-own-list for Lisbon or New York with custom multi-type seeds.
- A fail-closed PASS policy, strict input validation, and retries for transient upstream errors.
What I learned
Qloo Insights affinity is set-dependent: scoring candidates together with a popularity-sampled anchor set gives a fairer baseline than comparing against a top-N list. And agentic repair only works when the pool is already category- and geo-clean. Gemini should choose among valid options, not invent dinner.
What's next for TasteGuard
Wire TasteGuard behind real concierge and booking agents, add cached per-city anchor packs for more cities, and add optional Maps grounding for names Qloo can't resolve.
Honest notes for judges
- The stress list is labelled Injected test list (not Gemini); it deliberately simulates a careless agent.
- Live percentiles and replacement names vary between runs. Top pool restaurants often repeat across personas because they're broadly loved.
- Scores are relative to the set Qloo scores together, so a keeper's percentile can shift slightly between the original and repaired lists.
- If Qloo lacks a place's in-city entry, a same-name venue elsewhere can be flagged as wrong-city.
- The 40th-percentile cutoff against city reference restaurants is our product policy, not an official Qloo recommendation.
Built With
- artifact-registry
- fastapi
- fastmcp
- google-cloud
- google-cloud-build
- google-cloud-run
- google-gemini
- mcp
- python
- qloo
- react
- terraform
- vite
Log in or sign up for Devpost to join the conversation.