Inspiration
In a care home, group activities almost always play to the majority. Put on a popular film and most residents enjoy it — but the person who only ever lit up for big-band music, or westerns, or baseball quietly gets another afternoon that isn't for them. Over a week, the same few people are served again and again, and the same few are left out.
We wanted to flip that. What if a week could be planned so the least-served resident is as well served as possible — and every choice was backed by real taste data, not a guess? Qloo's Taste API made that possible: it can take "loves Johnny Cash and I Love Lucy" and tell you, with an affinity score, how well The Sound of Music or Murder, She Wrote fits that specific person.
What it does
Fondly is a weekly activity planner for care homes. A coordinator lists their residents and the music, films, TV, books, games, sports and food each one loves. Fondly then:
- Builds a week of group sessions where every resident gets at least one session built around what they love.
- Scores every option for every resident on live Qloo affinity, then runs a fairness optimizer that maximizes how many residents get a strong match (fit ≥ 0.8) and lifts the least-served person.
- Proves it honestly — the same week is also planned two other ways and scored on the same residents: Qloo's most popular titles, and the same AI working with no Qloo data at all.
- Ships each session as a ready-to-run kit: Qloo facts, a 60-second read-aloud, conversation prompts, adaptation tips, a gentle quiz, large-print handouts, an
.icscalendar, and a one-page noticeboard poster. - Learns week to week — mark sessions loved or declined per resident, and "plan next week" uses loved titles as new taste signals and never repeats declined ones.
- Lets families fill in favorites through a private, time-limited link, so staff aren't guessing.
Names never leave the browser. The server, Qloo and the LLM only ever see aliases (r1, r2…) and public cultural favorites — no health data.
How we built it
The browser (React 19 + Vite) sends aliases only and streams the run over Server-Sent Events, so you watch the agent work in real time. On the server (Express 5, TypeScript):
- An LLM agent decides which steps to run and writes the human-facing briefs and newsletter — but it never picks the numbers.
- A deterministic pipeline makes every Qloo call:
/searchto resolve each favorite to a Qloo entity,/v2/tagsfor foods and genres, and/v2/insightsto build candidates and to score each resident's affinity for each candidate (with explainability). - A max-min scheduler assigns one candidate per slot — reach first, then the least-served fit — with no model involved.
- A safety net runs any step the agent skips, so a plan always finishes even if the LLM fails or times out.
The Qloo client runs four concurrent requests with retries, a shared 429 cooldown, and a disk cache. We run NVIDIA Nemotron as the primary model with Gemini as the fallback (a flag flips the order), and it's deployed on Render with a persistent disk.
Challenges we ran into
- The LLM must never invent facts. The hard rule became: the plan can only contain entities Qloo actually returned, and every fit is a Qloo number. That split — model for language, code for numbers — shaped the whole architecture.
- Fairness is a real optimization problem. "Reach the most people" and "help the least-served" conflict, so we built a greedy-plus-local-search max-min scheduler rather than letting the model choose.
- Flaky, slow LLMs under a deadline. Session kits fall back to a template if generation runs out of time. One slow primary call was eating the whole budget before the fallback got a turn, so we now reserve part of a fresh call's budget for the fallback — a change we verified end-to-end on the live site.
- Honest benchmarking. It's easy to claim a plan is good. Scoring two baselines on the same residents with the same metric keeps us honest, and it's usually where Fondly's lead shows.
What we learned
Taste data is a genuinely different input from popularity. The most popular titles reached 5 of 8 residents in our sample home; Fondly reached 8 of 8. We also learned to treat the LLM as a narrator and planner of steps, not a source of truth — everything a user sees as a fact traces back to a Qloo response or deterministic code.
What's next
Multi-home support, richer learning from week-to-week reactions, and accessibility passes with real assistive-technology testing.
Built With
- express.js
- google-gemini
- node.js
- nvidia-nemotron
- qloo
- qloo-taste-api
- react
- render
- server-sent-events
- typescript
- vite
- zod
Log in or sign up for Devpost to join the conversation.