-
Landing: what Sondo is and how it differs from a plain model
-
Without Qloo: the same brief to a plain model, matched against Qloo results by code
-
Audience lift vs market baseline and distinctiveness (Sondo heuristics)
-
A concept with evidence tiers: directly supported, contextual, hypothesis
-
Click any E# chip to open the Qloo result behind a claim
-
Report cover: how many Qloo results across how many categories ground the report
Inspiration
Every brand launch needs cultural partners: the artist, the show, the podcast, the venue or the co-brand that makes a campaign feel native to its audience. Big brands pay insights teams and research panels for that answer. Everyone else guesses.
AI has made that guessing faster without making it better. Ask a general-purpose model which podcasts a 25-to-34-year-old in Austin loves and you get a fluent, confident list drawn from training-data stereotypes. It's the same list your competitors get, there's no evidence behind it, and nothing tells you how this audience differs from everyone else in the city. You can't defend it in a client meeting.
We wanted the opposite: an agent that does the research, shows its sources, and says plainly when it can't support a claim.
What it does
You give Sondo a brief: a brand, an audience, a market, an objective and, optionally, a few things that audience already loves. Sondo's agent then researches Qloo's taste graph live, and you can watch it work: the stages, the real Qloo queries, the budget and the evidence coming in.
A few minutes later you have a report with three different campaign concepts: a mainstream anchor, a distinctive niche and a cross-category bridge. Each claim is marked with its evidence tier:
- Directly supported: the sentence names the Qloo result it cites.
- Contextual support: the cited result is related (same category or taste theme).
- Hypothesis or creative idea: strategic judgement, styled differently, never dressed up as a finding.
Click any E# chip and the Qloo result behind the claim opens: its category, its rank within its query, popularity, tags and the query that produced it. The report also shows:
- what Sondo could and couldn't model from the brief;
- key findings written by code;
- audience-lift and distinctiveness charts;
- the full evidence ledger and the Qloo trace (with no keys);
- a "how to validate" test plan for every concept;
- a Without Qloo panel: the same brief given to the same model with no data access, matched against Qloo's results.
Reports are permanent, shareable links that unfurl with their own preview image. Any finished report can replay its research in about 20 seconds.
How we built it
- App: Next.js 16 (App Router, Node runtime), React 19 and TypeScript in strict mode, deployed on Vercel in
fra1next to the database. - Agent: AI SDK 7 through the Vercel AI Gateway. The production model is
nvidia/nemotron-3.5-lightning-free, a free model; that was a deliberate constraint, and the reason the validation layer had to be strong. - Data: Neon Postgres for runs, the event log, reports and a private Qloo response cache. Zod validates every boundary: briefs, Qloo responses, model output and database rows.
- Agent design: a bounded state machine in
lib/agent/. Code owns control flow, entity ids, every number, budgets and run status; the model plans, picks research moves and writes copy. Steps:- Plan. The model turns the brief into categories and questions, and code clamps the plan to the brief: ages, market and anchors stay authoritative, and anything Qloo can't model (income, values) is listed as not modeled.
- Research (code). Resolve the brand and anchors, then run paired target and baseline queries per category, plus taste themes and anchor demographics.
- Adapt (up to 2 rounds). The model chooses follow-ups from a fixed tool menu: explore a category, add a niche lens, bridge from an
E#, fetch taste themes, or stop. Code checks each proposal against the ledger and the budget before anything runs. - Critique (code). Writes findings (
F#) on lift, distinctiveness, cross-category intersections, conflicts and gaps. - Strategize (model). Three concepts that may cite only ledger ids.
- Validate (code), with one repair call. Every citation must exist and must relate to the sentence that cites it. Evidence claims with no relevant citation become hypotheses. Invented numbers and performance claims are removed. Concepts must differ.
- Integrity gate. A run is stored
completedonly if all three concepts are grounded (at least 3 relevant citations across at least 2 categories) and the stored report re-validates. Otherwise it's stored aspartial,failed,cancelledorinterrupted, with the reason shown.
- Runs outlive the request. A run executes under Next.js
after(), streams public events as NDJSON, writes each event to Postgres, and resumes on reload. Public events never carry Qloo params, ids, error text, token counts or model-written reasoning. - Guardrails per run: 24 Qloo calls, 4 model calls, 2 adaptive rounds, a 180 s hard limit and Qloo concurrency of 3. Across visitors: a per-IP daily limit (IPs stored only as HMACs), a global daily cap, a concurrency cap, idempotent submits and a kill switch that serves featured reports only.
How Qloo powers Sondo
Qloo is the only evidence source. If you remove it, the ledger is empty, the validator has nothing to accept, and every claim is downgraded to a hypothesis. Sondo would still write, but it couldn't prove anything.
All calls go through a typed, allowlisted, budgeted client for hackathon.api.qloo.com:
- Entity resolution (
/search). Brand and anchor names become Qloo entities. Only trusted matches seed research, and a fictional brand is reported as "not in Qloo" rather than guessed. - Cultural affinities (
/v2/insightsacross artists, film, TV, podcasts, books, brands and places). Each category is queried twice: once with the audience's signals (age buckets, gender if stated, anchors, market) and once as a market baseline. Comparing the two ranks gives audience lift: what over-indexes for this audience rather than for everyone in the city. - Taste themes (
filter.type=urn:tag) behind the signal set, and demographics (filter.type=urn:demographics) of the anchors. - Distinctiveness. Qloo popularity crossed with in-query rank finds strong-fit entities that aren't mainstream.
- Cross-domain discovery. The agent can take a strong result in one category (a brand) and use it as the seed for another (podcasts), following Qloo's graph across domains.
- Provenance. Every
E#is a row parsed from a real Qloo response: query, rank, popularity and tags. The model can reference an id but can never write one, and it never writes a number.
Lift and distinctiveness are labelled as Sondo heuristics. Qloo affinity is never presented as purchase intent, audience share or ROI.
The measured difference. For the three featured briefs we asked the same model for cultural partners with no data access. Of its 32 suggestions, 1 appeared among the Qloo results collected for that audience. Sondo's concepts cite 23 partners the plain model never named. The report shows both lists, matched by code.
Challenges we ran into
- A free model that doesn't always follow the format. It sometimes answered in prose instead of structured output, or timed out. We forced structured output through a tool call, added a compact-digest retry that runs only when the deadline allows, applied deterministic fixes when repair fails, and kept whichever of draft or repair is better grounded. All of it runs through the same validator.
- Real citations on the wrong sentence. Early runs attached genuine
E#ids to unrelated claims. Checking that an id exists wasn't enough, so we built a deterministic relevance check (names, tags, category words) and a downgrade-to-hypothesis rule. - Ids and numbers leaking into prose. The model wrote "(E11)" into sentences, and the no-invented-numbers rule then withheld whole insights. Inline ids are now stripped before validation, with a regression test.
- A 200 that ignores you. Qloo silently ignores parameters a type doesn't support. We verified each type's parameters with a live probe and drop anything off the allowlist in code instead of trusting the status code.
- Serverless runs that outlive the request. Postgres is the only coordination point: conditional status updates, backoff on the final write, and stale rows marked
interruptedinstead of left "running" forever.
Accomplishments that we're proud of
- 0 invalid citations in every recorded live eval (Oct 19, both Oct 27 runs and Oct 29). In the Oct 29 eval, against live Qloo with no cache, the 5 fixed briefs produced 176 citations. All were valid, every evidence claim had a relevant citation, and all 5 runs stayed within budget.
- Honest status. A run that can't ground all three concepts is stored and shown as
partialwith the reason, never promoted tocompleted. The integrity gate makes that structural. - The model never writes a number. Every rank, score and count in the UI is rendered from parsed Qloo responses.
- A product, not a notebook: live research view, permalinks, replay, the evidence drawer, charts with table fallbacks, link previews, and real 404s for unknown reports. Lighthouse accessibility scores 100 on the landing, composer and report pages in production.
- Tested like it matters: 272 unit tests (including in-process Postgres via PGlite) and a Playwright suite at 1280 and 375 px that also runs against production.
What we learned
- Grounding is a pipeline property, not a prompt. Asking the model to "cite sources" produced plausible ids on the wrong sentences. What worked was making ids unforgeable (code assigns them), checking relevance in code, and letting the run fail honestly.
- A baseline is what makes cultural data useful. A single affinity list mostly shows what's popular. The paired audience-vs-market query is what surfaces the non-obvious partner.
- Bounded agency beats open-ended agency for trust. A typed menu of research moves, each validated before it runs, gave us an agent that adapts, stays within budget, and leaves a trace a person can audit.
- Say "partial" out loud. Labelling unsupported concepts made the output more credible, not less.
What's next for Sondo
- The paying user: brand and growth teams at DTC, CPG and hospitality companies without an insights department, and agency strategists who need a defensible first-pass cultural brief before a client workshop.
- The product path:
- Team workspaces with saved briefs and report history.
- Exports to slides and docs, so a report drops straight into a pitch.
- Brief-to-brief comparison: the same audience across two cities, or two audiences in one city.
- A stronger paid model behind the same validator, to cut the partial rate.
- Closing the loop. Each concept already ships with a "how to validate" plan. The next step is recording the test outcome against the concept, so teams build their own evidence over time.
- Business model: a per-seat subscription for in-house teams, plus agency plans priced per client workspace. Sondo is a first-pass research tool, not a replacement for a full study.
Demo instructions for judges
No login, payment or setup. Everything below runs on the live site.
- Open https://sondo.xylolabs.space and scroll to Featured reports.
- Open Stride Loop · New York City:
- The cover shows how many Qloo results across how many categories ground the report.
- Switch between the three concept tabs.
- Click any
E#chip to open the Qloo result behind that claim, and note the three evidence tiers. - Read Without Qloo, by contrast: what a plain model suggests for the same brief, next to the partners only Sondo found.
- Press Watch the research to replay the agent's run in about 20 seconds.
- Scroll to the lift and distinctiveness charts, the evidence ledger and Run details and Qloo trace.
- Click New brief, pick an example (or write your own) and submit. The live view shows the real Qloo queries, the budget and the evidence per category. A run takes about 2–3 minutes, and it keeps running if you leave.
- When it finishes, copy the report link and open it in a private window. The report is stored and shareable.
A run can finish as partial: the agent couldn't ground all three concepts, and the report says why. That's by design. Each visitor gets a few live runs a day to protect the shared Qloo quota; the featured reports are always available.
Built With
- ai-sdk
- neon
- next.js
- playwright
- postgresql
- qloo
- react
- typescript
- vercel
- vercel-ai-gateway
- vitest
- zod
Log in or sign up for Devpost to join the conversation.