Restaurant DNA Agent avatar

Restaurant DNA Agent

Pricing

from $20.00 / 1,000 enriched pois

Go to Apify Store
Restaurant DNA Agent

Restaurant DNA Agent

Point it at a city or a list of places and get Restaurant DNA: scored, explainable traits (family-friendly, romantic, quiet, value, hidden-gem…) with confidence and cited evidence. The agent finds factual gaps, browses each venue's site to fill them, and returns provenance-tagged POI intelligence.

Pricing

from $20.00 / 1,000 enriched pois

Rating

0.0

(0)

Developer

Jinq

Jinq

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

20 days ago

Last modified

Categories

Share

Restaurant DNA in action — a map of places, each with scored, confidence-rated traits

Point it at a city, or a list of places, and get back Restaurant DNA: scored, explainable traits that exist in no dataset. For every place the agent infers traits like family-friendly, romantic, quiet, digital-nomad-friendly, value, veg-friendly, hidden-gem, accessibility, authenticity, each with a confidence score and cited evidence. It then decides what factual gaps remain, browses the venue's own website to fill them, reconciles conflicting sources with provenance, and loops until a completeness target is met.

Google Places gives you a name, an address, maybe a rating. This agent gives you manufactured intelligence that a human (or another agent) can act on: the Restaurant DNA, plus a summary, dietary suitability, the live menu, opening hours, review sentiment, and a completeness score that tells you how much it could verify.


Why this is an agent, not a scraper

A scraper runs a fixed plan. This one makes decisions, per place:

DecisionWhat the agent does
Gap detectionInspects each seed record and works out which useful fields are missing or weak (hours, menu, dietary, contact). Different places → different gaps.
Source routingDecides whether browsing the restaurant's own website is worth it, and shapes the browse goal to chase only the gaps it found: menu, and hours/phone when those are missing.
ReconciliationFills empty fields from the site; when the site's phone disagrees with Google it keeps Google's value but records the conflict (both numbers) in provenance instead of silently overwriting. Google Places is treated as ground truth for scalar fields.
Loop-to-goalKeeps filling gaps until a weighted completeness score crosses its target or no untried source remains.

The completeness score is the agent's objective function. It is optimising, not just extracting.


Restaurant DNA: the headline output

Each place gets a restaurant_dna object: the traits it holds, each with a confidence and cited evidence.

"restaurant_dna": {
"top_traits": ["veg_friendly", "family_friendly", "value", "romantic"],
"traits": {
"family_friendly": { "label": "Strong", "score": 1.0, "confidence": 0.92, "present": true,
"citations": [{ "source": "attribute", "observation": "Google: Trẻ em — Ghế cao cho bé" }] },
"quiet": { "label": "Low evidence", "present": false, "conflict": false }
},
"evidence_count": 28, "mode": "deterministic"
}

How it works: the engine fuses multi-source evidence (Google's structured attributes, review text, popular-times, price percentiles) into each trait. Confidence is agreement × coverage over the weighted evidence, not an LLM guess, and the engine abstains ("Low evidence") when sources are thin or conflicting. Set dnaUseLlm to also mine review text with your LLM and lift the review-driven traits (quiet, romantic, authenticity).

The trait catalog + language live in a swappable profile: restaurants/Vietnamese by default; point it at another profile for cafés, hotels, or English.


Input

FieldTypeNotes
searchQuerystringe.g. "restaurants in District 1, Ho Chi Minh City". Omit if you pass placeNames.
placeNamesstring[]Enrich these specific places instead of a query.
maxPlacesintegerHow many to discover + enrich (default 5).
languagestringISO code for Places + the AI summary (vi, en, …).
includeDnaboolInfer Restaurant DNA (scored, cited traits). On by default; it's the headline output. Pulls reviews as evidence.
dnaUseLlmboolAlso mine review text with your LLM to lift review-driven traits (quiet, romantic, authenticity). Costs more; structured attributes work without it.
llmProviderenumopenai (any OpenAI-compatible endpoint), bedrock-openai (Amazon Bedrock open models), or anthropic.
llmApiKeysecretYour own LLM key. Used only for the run, never stored.
llmModel / llmBaseUrlstringOptional overrides (e.g. OpenRouter, a Bedrock region, a specific model id).
useTinyFish + tinyFishApiKeybool + secretBrowse each site with the TinyFish web agent (handles JS menus a plain fetch can't). Optional; falls back to HTTP.
demoboolTry it with zero keys. Returns a bundled, pre-enriched Vietnamese example so you can see the output shape instantly.

No Apify token needed for discovery. The agent calls the Google Places crawler from inside its own run under limited permissions.

Bring your own model

This Actor runs on your Apify account, so it uses your LLM key, with no vendor lock-in. Cheapest sensible default is openai + gpt-4o-mini; for open-weight models point bedrock-openai (or llmBaseUrl) at Bedrock / OpenRouter / Together. Want to look before committing a key? Flip on demo.


Output

One dataset row per POI:

{
"title": "Phở Lệ",
"address": "413-415 Nguyễn Trãi, Quận 5, Hồ Chí Minh",
"phone": "+84 28 3923 8952",
"opening_hours": "06:00–01:00 hằng ngày",
"rating": 4.3,
"live_menu": [{ "dish_name": "Phở chay", "price_vnd": 65000, "dietary_tags": "chay" }],
"summary": "Quán phở lâu đời ở Quận 5, mở tới 1 giờ sáng — có cả phở chay.",
"dietary_tags": ["chay"],
"review_sentiment": "positive — khách khen nước dùng và giờ mở cửa khuya…",
"recommended_segments": ["families", "late-night", "vegetarian"],
"quality_score": 0.86,
"completeness_score": 1.0,
"sources_used": ["google_places", "website"],
"provenance": [
{ "field": "live_menu", "value": "3 items", "source": "website", "conflict": false }
],
"confidence": 0.87
}

Every enriched field is traceable back to its source in provenance.


Measured, not vibes

The engine is validated, not asserted — with numbers you can reproduce:

  • Restaurant DNA traits — on places where Google confirms a trait, the deterministic engine recovers it at veg-friendly recall 0.83 / F1 0.71, macro recall 0.38 / precision 0.56 across traits. Precision is a lower bound (a missing Google attribute isn't proof the trait is absent). Reproduce with python3 -m tasco.intel.eval_traitsno API key needed.
  • Menu extraction — on held-out menu photos: dish precision 0.99 · recall 0.985 · price accuracy 0.99.
  • Dish recognitiontop-1 0.80 (0.84 including near-misses) over held-out dish photos.

The same rigor backs the completeness score (a defined weighted formula over target fields, not a mood). Confidence on every trait is agreement × coverage over the evidence — never an LLM self-report.


Pricing (pay per event)

  • poi-enriched: charged once per fully enriched POI.
  • website-fetch: charged only when the agent chooses to browse a venue's site.

Pay-per-event + limited permissions means this Actor is discoverable and runnable by autonomous AI agents (allowsAgenticUsers).


Use cases

  • Maps / discovery apps filling sparse local listings (built for Vietnamese POIs; works anywhere).
  • Delivery & reservation platforms needing live menus and verified hours.
  • Market research on a city's dining scene with dietary and segment breakdowns.
  • Agent pipelines that need clean, provenance-tagged place data as a tool call.

Limitations (honest ones)

  • v1's plain-HTTP site fetch reads static HTML; JS-only menus need useTinyFish.
  • Menu extraction from a homepage can occasionally over-read; each item carries a confidence, and menu is weighted so low-confidence pulls don't inflate completeness.
  • Only what a source actually states is recorded; the agent won't invent hours or dishes.