Inspiration

Most expensive decisions in entertainment get made before anyone has tested anything. A dev exec decides whether a spec gets a second draft, an A&R team decides whether a debut gets a tour, an indie studio decides what to spend the next eighteen months on. The evidence at that point is a logline and a handful of comps, and comps are just a shorthand for an audience nobody has looked at.

Test screenings and focus groups come much later and cost tens of thousands. In the meantime, more people are pasting their pitch into a chatbot and asking what an audience would think. We tried that. The same model, asked to play a test audience for a horror-comedy, invented four overlapping age groups and had almost all of them say they were in. It even listed one of the pitch's own comps as something the audience "loves".

Qloo has measured cross-domain taste for the people who love those comps. We wanted to sit that audience at a table and read them the pitch.

What it does

You paste a title, a format (film, series, comedy special or tour, album or tour, indie game), a logline and two to four comps. In about 35 seconds Table Read:

  1. Finds each comp in Qloo and shows which entity it matched.
  2. Reads the comps' audience demographics and seats a room of four or five weighted segments ("24 & under · men, 28% of the room").
  3. Fills every seat with that segment's real tastes across six domains (films, TV, artists, brands, podcasts, games) plus taste themes, each with its Qloo affinity and a receipt.
  4. Scores the logline itself. The model names existing titles that share the premise (never the comps), and Qloo ranks those "premise twins" for each segment against a fixed pool of well-known reference titles.
  5. Measures with Qloo how strongly each segment leans toward the pitch package, then lets each segment react to the logline in its own voice. Reactions can only cite the segment's own Qloo tastes, and each score is held within 15 points of Qloo's measurement.
  6. Runs a critic that proposes one change at a time from the audience's own tastes (a soundtrack artist, a brand partner, a new comp), re-measures it on Qloo, and keeps it only if Qloo's numbers rise.
  7. Maps the cities where the comps' audience concentrates, checks the comps' momentum, and prints a one-page GREENLIGHT / DEVELOP / PASS memo listing every Qloo request behind it.

The Audience Fit Index per segment is 25% comp resonance + 45% premise fit + 30% grounded panel. Because premise fit carries the most weight, the logline really moves the score: with the same three comps, a horror logline scored 74, a florist rom-com 49 and a retiree baking contest 45.

Plate 02, "Two readers, one pitch", puts the same model's blind guess (same segments, same premise twins, no Qloo numbers) beside the Qloo-grounded read. On our three pinned demos the model alone was more flattering every time: 79 vs 74 for the horror feature, 86 vs 70 for the UK album tour, and 85 GREENLIGHT vs 60 DEVELOP for the indie game, a different decision. In each demo 3 of 5 segment verdicts flip. For the horror pitch the model guessed Black Swan sits at the 90th percentile for women 24 and under; Qloo measured the 23rd.

In the indie-game demo, the critic proposed adding The Breadwinner as a comp; Qloo's resonance rose from 77 to 80 and the index from 58 to 60, so it was kept. An Omori tie-in lowered both and was thrown out. In the horror demo, Mitski on the soundtrack raised resonance but lowered the index, so it was rejected too. The LLM suggests; Qloo has the veto.

How we built it

The backend is a set of Vercel serverless functions in plain Node. A read streams to the browser as Server-Sent Events, one event per stage and one per Qloo call, so you watch the agent work and every request appears in a receipts drawer.

Qloo does all of the audience work, about 85 to 100 calls per read:

  • /search to resolve comps, with format-aware type preference, year and type hints, and popularity tie-breaks.
  • /v2/insights with filter.type=urn:demographics to get the comps' age and gender skew and build weighted segments.
  • /v2/insights once per domain per segment (movie, tv_show, artist, brand, podcast, videogame) with the comps as interest signals, the segment's age and gender as demographic signals, and the comps excluded: 30 calls that give each seat its own cross-domain taste.
  • /v2/insights with filter.type=urn:tag for each segment's taste themes.
  • /v2/insights with filter.results.entities to measure how each segment leans toward the exact package (comps plus any attachments). The critic re-runs this for every proposed change.
  • /v2/insights with filter.type=urn:heatmap for the launch map, scored per city as a popularity-weighted mean of nearby cells.
  • /v2/trending for weekly momentum of each comp.
  • /search again for the premise twins the model names from the logline (exact name match only, comps refused; the list is fixed per pitch).
  • /v2/insights with filter.results.entities set to the twins plus ~35-40 fixed reference titles, the comps as signal and each segment's age and gender: one call per segment. Each twin's percentile in the pool is its premise score. A second call without the comps gives the demographic baseline, so each receipt shows the lift.

A small client wraps Qloo with a rate limiter (hackathon keys allow about five requests a second), retries with backoff, a warm-instance cache, and a redacted trace of every call. Google Gemini only names premise twins (temperature 0, from the logline alone), makes the blind guess for Plate 02, names segments, voices reactions, proposes critic notes and drafts the memo, and code enforces the limits: twins must resolve to exact Qloo entities and can never be the comps, citations outside a segment's Qloo lists are stripped, panel scores are held within 15 points of Qloo's measured fit, critic proposals must already exist in the audience's tastes, and the verdict is computed from the index rather than chosen by the model.

The front end is hand-written HTML, CSS and ES modules styled like a riso-printed press proof, with a per-segment "taste fingerprint" glyph, a MapLibre map on OpenFreeMap tiles, and a print stylesheet that turns the memo into a one-sheet. Finished reads are stored in Vercel Blob so share links and the three demos load instantly.

Gaurang Kumar directed the project. The code, deployment, tests and write-up were done with Hark, an AI agent, working under his direction and reviewing itself against the judging criteria after every round.

Challenges we ran into

  • Our first score flattered everyone. Segments come from the comps' audience, so measuring them against those comps produced a comfortable 75 to 85 for any logline. We tried scoring the logline's concepts through Qloo tags three different ways and none separated a horror pitch from a rom-com with the same comps, so we didn't ship any of them. What worked was moving to the entity level, where Qloo is best calibrated: "premise twins", real titles that share the logline's premise, ranked per segment against a fixed reference pool so each group's baseline cancels out. Same comps, different loglines now score 74, 49 and 45.
  • Rate limits. The first live read lost 24 calls to 429s. We measured the limit (about five requests a second) and built a limiter; reads now complete with zero errors.
  • The dataset has quirks. Trending series came back flat week to week and returned 400 for video games; the heatmap returns thousands of cells for artists and a handful for some films, with affinity ranked inside each response. We changed the city metric to a weighted mean and flag flat momentum instead of pretending it means something.
  • Ambiguous comps. "What We Do in the Shadows" first resolved to the 2014 film rather than the series. We added format-aware type preference and hints like (TV), (2021) and (artist).
  • Model churn. Mid-build, the Gemini model we used was retired for new keys and the next one hit free-tier quota. The server now walks a chain of models and skips any that 404 or 429.

Accomplishments that we're proud of

  • An LLM-only switch that shows, on the same screen, what changes when the audience comes from Qloo: real segments with sizes, specific tastes with affinities, and receipts on every chip.
  • A critic whose ideas are tested by Qloo, not by the model's opinion of itself.
  • A score where the logline matters: same comps, three loglines, 74 / 49 / 45.
  • Real, pinned demo reads in three very different formats (a horror feature, a UK album tour, an indie roguelite), each with 86 to 101 Qloo calls and zero errors.
  • Being honest in the product about what it is: aggregate signals, synthetic voices, a tool for deciding what to take to a real test audience.

What we learned

  • Qloo's entity-level affinities are well calibrated and fast, and the cross-domain jump (what fans of a horror series listen to, wear and play) is the part no general model can fake.
  • A language model asked to simulate an audience is a people-pleaser. The fix is not a better prompt; it's taking the audience out of the model's hands and letting it only speak for data it was given.
  • Measuring something against itself is a trap. If the audience comes from the comps, scoring fit on the comps tells you very little about the pitch.
  • Reading the docs is not enough on a hackathon dataset; we probed every endpoint's real behaviour (limits, take caps, empty responses) before trusting it.

What's next for Table Read

  • Let users bring their own premise twins and reference pool (for example a studio's own slate) instead of the model's picks.
  • Compare two versions of a pitch side by side (two loglines, two casts, two soundtrack choices) and show which segments move.
  • Use /v2/analysis/compare to show where two comps' audiences split, so producers can see what each comp actually contributes.
  • Venue and city routing for album and comedy tours from Qloo place data, for the promoter side.
  • A shareable, password-protected read for a whole development team, and a pilot with a small production company, label or indie studio to compare Table Read's calls with their real test screenings.

Built With

Share this project:

Updates

Submission history