-
The agent at work: every tool call streams live (SAMPLE mode screenshot)
-
24-guest conference dinner with requirements checklist (SAMPLE mode screenshot)
-
40-guest wedding: table map, conversation card and per-guest fit (screenshot from keyless SAMPLE mode; the live demo uses real Qloo data)
-
Mobile layout
Try it live: https://placecard-cxku.onrender.com · Code (MIT): https://github.com/mbabbu/placecard
Inspiration
Seating charts are the part of every wedding and conference dinner that organisers dread. They take hours, they are done blind, and the result is the table where two guests share nothing and the evening is a long silence. Qloo knows what people's favourite films, bands, books and restaurants say about the rest of their taste. That is exactly the signal a seating chart is missing.
What it does
The organiser pastes a guest list (or uploads a CSV): a name, two to four favourites from any domain, and optionally a group such as "Tan family". They add requirements in plain words: "keep the Tan family together", "Aisyah and Hafiz apart", "Grandma Rose at the head table". An AI agent then:
- builds a taste profile per guest from Qloo (resolves each favourite, then fetches the tags that characterise it);
- turns each requirement into a validated hard constraint (it rejects contradictions, such as together and apart, or five people together at tables of four);
- runs a seating optimiser that maximises the fit of the least-matched guest and the average table cohesion, and avoids leaving anyone with no close match;
- writes a conversation-starter card per table that may only mention what the table really shares in Qloo;
- asks the organiser one clarifying question when a third of the guests have no matched favourites, instead of guessing.
The result is a visual table map (round tables, seats coloured by fit, a dashed ring for any weak match), a card and a per-guest "fit and why" for every table, a requirements checklist, and a CSV download. You watch every agent step live.
Live results on real Qloo data: on the 40-guest wedding (Malaysian, Korean, Japanese, Indian, Chinese and Western tastes; 133 favourites, 100% resolved) the least-matched guest fits 0.25 against 0.08 for random seating (3.1x), average table cohesion is 0.46 against 0.32, nobody is isolated and all three requirements are met. On the 24-guest conference dinner the least-matched guest fits 0.22 against 0.05 (4.4x).
How we built it
- Agent: a provider-neutral LLM tool-calling loop in Python. The live demo runs on Google Gemini (
gemini-3.1-flash-lite); Anthropic Claude (claude-haiku-4-5) is supported by the same loop, and a keyless scripted mock exists for tests. The model chooses among seven tools:build_taste_profiles,apply_constraint,seat_guests,explain_table,table_card,ask_organizer,present_plan. Every step streams to the browser. - Qloo:
GET /searchresolves favourites across nine culture types (exact name, then subtitle, then closest spelling; venues discounted; ambiguous titles become stated assumptions).GET /v2/insightswithfilter.type=urn:tagandsignal.interests.entities(taste analysis) returns the tags that characterise each guest's favourites: one call per guest, cached, parallel and throttled under the key's rate limits. We drop the venue/price metadata tags the API mixes in and blend in each favourite's own Qloo tags, which raised ground-truth separation of guests from AUC 0.74 to 0.82. Guest names are never sent to Qloo. - Optimiser: pairwise compatibility is the cosine of IDF-weighted tag vectors. Together-groups are blocks that are never split; a greedy start is refined by swap/move local search (120 guests with constraints in about 0.5 s). Objective:
0.6 * min_fit + 0.4 * avg_cohesion - isolation penalty, so the worst-matched guest is protected, not just the average. Verified against brute force on small parties. - Trust: the model never produces a number. Every score comes from the optimiser over Qloo tags. The server rejects a table card that names a tag, favourite or guest that is not grounded in that table's own Qloo data, and seating is refused until every organiser requirement has been applied (anything not applied is reported, never hidden). Turn and Qloo-call caps plus a fallback that finishes the plan from the tools' results keep the public demo safe.
- Stack: Python standard-library server, framework-free mobile-first UI with an SVG table map, 202 unit and HTTP tests (including trimmed real Qloo responses as fixtures), Docker, Render.
Challenges
- Constraints versus quality: together groups, apart pairs, fixed tables and a head table cut the search space; we treat groups as blocks and validate every constraint as it is added.
- What counts as isolated: someone with a truly unusual taste is isolated anywhere, so we only penalise avoidable isolation and report the rest honestly.
- Keeping the LLM honest in prose: every tag, favourite and name in a card is checked against that table's Qloo data.
- What the live API really returns: taste-analysis affinities are almost all 0.99-1.0, a fifth of tags are venue metadata, and 19% of our first candidate favourites resolved to the wrong thing (Hades to a band, Kyoto to a restaurant in Israel). Typed search, subtitle matching, hints and tag blending fixed it: 194 of 194 final favourites resolve.
Accomplishments
- An agent whose every claim is traceable to Qloo tags, visible as it happens, with grounding enforced by the server.
- A seating optimiser with an isolation check and constraint validation, fast enough for 120 guests.
- Runs anywhere: with no keys the full experience works on clearly labelled sample data; with keys it uses live Qloo.
What we learned
Qloo's taste graph is most useful as a way to measure how much two strangers will have to talk about. Tag vectors turn a vague "mix people sensibly" into something an optimiser can maximise, and the same shared tags become the conversation starters.
What's next
- A guest RSVP link where each guest adds their own favourites from a phone.
- Seat-level constraints (aisle, accessibility, children) and drag-to-swap editing with live fit feedback.
- Printable place cards and table cards.
AI assistance
This project was built with AI coding assistance (Claude Code). Every number in the app comes from Qloo data and the optimiser, never from the language model.
Built With
- docker
- gemini
- javascript
- python
- qloo
- render
- svg
Log in or sign up for Devpost to join the conversation.