Inspiration

Wine people say a place has a taste. I wanted to dig for it in culture. Most taste tools answer "where do fans of X go?" I wanted the inverse: start from a street's bars, venues and galleries, and work back to the books, films and music their audiences love, layer by layer, like an archaeologist reading strata.

What it does

You give Terroir a neighborhood and a city. An agent then:

  1. Surveys the places that neighborhood itself favors.
  2. Chooses anchors, four to six places that hold the scene, and records what it rejected and why (hotels, parks, a market, places from another part of town).
  3. Core-samples books, film and music with the anchors as Qloo signals. Qloo's explainability shows how much each anchor contributed to each result; the page draws it as threads on a radar.
  4. Digs deeper strata by narrowing to the two least popular anchors. Strata come from the popularity percentiles Qloo returns: surface, subculture, underground.
  5. Takes a control core. Qloo's rank scores the block's own finds against the whole city in one call, so Terroir can say which finds are local and which the city shares.
  6. Finds sister sites. The signature finds become signals for places in another city, and Qloo's own geocode names the neighborhood where they cluster.
  7. Files field notes in which every claim cites the Qloo calls it rests on.

Recorded digs replay instantly with the agent's full trace. A live dig streams in one to three minutes and costs about $0.50 in model usage.

How I built it

  • Qloo only through the official harness. The agent's Qloo tools are @qloo/qloo-harness 0.1.26's own tool definitions (names, descriptions, usage guidelines and JSON Schemas, from createQlooToolsFromEnvironment), run by its direct workflow executor, the validated layer behind qloo exec. Workflows used: recommend, rank, and describe. The exact /v2/insights request the harness sent for each call is stored and shown in the page's ledger.
  • The agent loop is an AI SDK 7 ToolLoopAgent running Claude Sonnet 5.5 through Vercel AI Gateway, with Anthropic prompt caching across steps.
  • The agent commits; the server checks. Anchors, layers, the control core, sister sites and notes are committed through tools that the server validates against the ledger of Qloo calls. A commit is refused, with a reason the agent can act on, if it cites an entity no Qloo call returned, calls a find local when the city rank says otherwise, names a sister site by putting the answer in the filter, or cites a ledger entry that doesn't exist. Strata, attribution shares and local/citywide labels are computed by the server, never by the model.
  • Interface: Next.js 16 on Vercel. A dig streams as newline-delimited JSON into a live trace, a strata figure, a thread radar, find cards, the control core, sister sites, field notes and the full ledger.

Qloo workflows and why they fit

  • recommend with place type and the neighborhood as both signal and filter location: surveys what the neighborhood itself favors.
  • recommend with anchors as signal.interests.entities and feature.explainability: turns places into culture, with per-anchor attribution.
  • rank with the block's finds as filter.results.entities and the city as signal location: the control core.
  • recommend for places filtered to another whole city: sister sites, with the neighborhood read from Qloo's geocode.

Request to result (one dig, redacted — Lower East Side, New York)

  • #1 recommend → GET /v2/insights?filter.type=urn:entity:place&signal.location.query=Lower East Side, New York&filter.location.query=Lower East Side, New York&feature.explainability=true → 20 places. Anchors chosen: The Bowery Ballroom, Arlene's Grocery, Metrograph, Abrons Arts Center, Nurse Bettie, Home Sweet Home. Rejected: Pier 36, Essex Market, a hotel, a park, a hotel rooftop bar, and others.
  • #2–#4 recommend → artists, books and film, with the six anchors as signals, 20 results each.
  • #5–#6 recommend → artists and books again, with only two anchors, to reach lower-popularity finds.
  • #7–#9 rank → ten of the block's finds per domain against signal.location.query=New York. Qloo scored five artists, two books and two films.
  • #10–#11 recommend → places filtered to Berlin, Germany and London, United Kingdom, signalled by the signature finds.
  • Result: music leans avant-pop, noise and improvised (Kim Gordon, U.S. Girls, Circuit des Yeux, Arthur Russell); books lean contemporary Black cultural criticism; films are small independents. Against New York as a whole, the less popular finds (Lolina, William Brittelle, Friday Black, Leave No Trace) read as local; Kim Gordon, U.S. Girls and Electric Arches read as citywide. Sister sites: Mitte in Berlin, and a three-way near-tie in London.

One dig is 11 Qloo calls, 13 agent steps, about $0.52.

Challenges

  • No popularity filter and uneven coverage. Strata come from returned percentiles, and the underground needs narrower digs. The API refuses single-entity signals, so narrow digs use pairs. Qloo's city-level scoring covers only part of a block's finds; Terroir leaves unscored finds unlabeled and says so.
  • Some places aren't covered. For Shimokitazawa, three narrow digs were refused and the books and film didn't match the scene; Terroir reports that instead of filling the gap. For Peckham, London, Qloo returned no places at all, and the agent ended the dig with an honest coverage-gap notice.
  • Keeping a language model honest. In development the model tried to commit an ID it had made up and anchors it knew from memory but Qloo hadn't returned. The ledger checks refused each, and the agent corrected course.

Accomplishments

  • An agent with real decisions to make (which places count, how deep to dig, what is local), checked against evidence at every commit.
  • Findings a single API call can't give: the local-versus-citywide split and the sister-site neighborhoods.
  • The page shows the agent's trace, its refused commits and the full request ledger. Nothing is hidden behind the finished view.

What I learned

Qloo's explainability turns recommendations into attribution, and that changes what you can claim. The most interesting results often contradict a neighborhood's reputation: Silver Lake's audiences lean toward rap and policy nonfiction, not the indie-rock canon the neighborhood is known for, and Terroir reports that as a finding.

What's next

Click-to-dig on a map, comparing two neighborhoods' strata side by side, and time-sliced digs with Qloo's trends.

Known limitations

  • Qloo results describe aggregate audience affinities, not facts about residents. Terroir never infers who lives somewhere.
  • Location is a neighborhood name, not a radius around a point.
  • The city rank covers only the finds Qloo can score for that city, and some cities have thin coverage.
  • Notes, readings and anchor roles are the agent's interpretation and are labeled that way on the page.

Setup (from a clean environment)

Node 24 and a Qloo hackathon key.

npm install
cp .env.example .env.local   # add QLOO_API_KEY and a model credential
npm run dev

No setup is needed to try it: the live site runs recorded digs instantly and starts live ones on request, with no login.

Built With

Share this project:

Updates

Submission history