Inspiration
Millions of visitors come to Korea for its culture, yet travel guides rank places by popularity, so everyone ends up in the same five spots. A fan of Bill Evans and Parasite wants something very different from a fan of idol pop. An LLM alone can only guess at that link between taste and place. Qloo's taste graph is built to know it.
What it does
You type a few things you love: artists, films, shows, books. The agent resolves each one to a Qloo entity, then asks Qloo's Insights API which places in each of eight Seoul districts (Seongsu, Hongdae, Itaewon, Jongno, Gangnam, Yeonnam, Euljiro, Hannam) best match that combined taste. It ranks the districts by mean affinity and composes a morning-to-late-night route from the top two. The UI shows the route, the neighborhood scores and the complete tool-call trace so users can see exactly what Qloo returned. Without Qloo the agent has nothing to rank with: the matching itself is the Qloo call.
How we built it
Python standard library plus the official Qloo harness (@qloo/qloo-harness). For each of eight Seoul districts the agent runs the recommend workflow (qloo exec recommend: target_type=place, the traveller's tastes as signals, filter_location set to the district, explainability on) against the hackathon Qloo API. Qloo resolves the names to entities; ambiguous names (e.g. "Radiohead" = artist, person, album) come back as needs_input with candidates, and the agent pins the best-fitting entity by its Qloo ID and retries. The hosted demo calls the same documented endpoints over REST (GET /search, GET /v2/insights, X-Api-Key, hackathon base URL) because Node cold starts are too slow on a free host; the harness path is the default in the repo. Districts are ranked by mean affinity and the top two fill a morning-to-late-night route. A thin HTTP server keeps the key server-side with per-IP rate limiting, and a single-page frontend shows the route, scores and the full tool-call trace. An optional LLM parses free text and writes the narrative; a deterministic fallback keeps the app working without one. Unit tests run against an offline simulation that is clearly labelled as non-Qloo data.
Challenges we ran into
Keeping the credential out of the browser while still offering a public live demo; protecting a monthly quota from public traffic; matching free-text names to the right entity type; treating affinities as aggregate signals rather than claims about individuals.
Accomplishments that we're proud of
A complete product flow in under 500 lines, a transparent agent trace, and a privacy posture that sends no personal data to Qloo.
What's next
Add tag-based filters (dining, nightlife), multi-day itineraries, group mode that blends several travellers' tastes and finds the overlap, and Korean-language input.
Example (live call, redacted)
Input: Bill Evans, Parasite, Haruki Murakami
Request (key sent only in the X-Api-Key header, server-side):
GET https://hackathon.api.qloo.com/search?query=Bill Evans -> EE57C132-... (urn:entity:artist)
GET https://hackathon.api.qloo.com/search?query=Parasite -> 6D3EA76D-... (movie)
GET https://hackathon.api.qloo.com/search?query=Haruki Murakami -> 99EE4D7C-... (author)
GET https://hackathon.api.qloo.com/v2/insights?filter.type=urn:entity:place
&signal.interests.entities=<3 ids>&filter.location.query=Seongsu-dong, Seoul
&feature.explainability=true&take=4 (repeated for 8 districts)
Result (excerpt): district scores Seongsu 0.672, Hongdae 0.671, Itaewon 0.663 ... Hannam 0.648, Euljiro 0.645, Yeonnam 0.643. Route: Morning, Seongsu, Club Sharp (affinity 0.677); Afternoon, Seongsu, Seoul Community Radio (0.673); Evening, Hongdae, Club Steel Face (0.672). Each stop shows Qloo's explainability: which of the three tastes drove it. Total latency about 7 s.
Links
- Live demo: https://seoul-taste-agent.onrender.com (free tier, first load may take ~30 s)
- Code (MIT): https://github.com/ilovecodingma/seoul-taste-agent
Built With
- docker
- html5
- javascript
- python
- qloo
- render
Log in or sign up for Devpost to join the conversation.