Skip to content

Latest commit

 

History

24 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Airbnb RAG + Analytics — Rome

A dual-pipeline conversational system over Inside Airbnb data for Rome. It combines Retrieval-Augmented Generation (RAG) on guest reviews with Text-to-SQL analytics on listings, exposed through a React web app backed by a FastAPI service. Storage, vector search, and analytics run on Databricks; only a local cross-encoder reranker runs on the machine hosting the API.

Main page

What it does

A single chat interface answers three kinds of questions, routed automatically by an LLM intent classifier:

  • Analytics (Text-to-SQL): "What is the average price per room type?", "How many listings are in the Eur district?". The question is translated to Spark SQL, executed on a Databricks SQL Warehouse over the listings_enriched view, and the result is summarised in natural language.
  • RAG (reviews): "Do guests complain about noise?", "What do reviews say about cleanliness?". The query hits a Databricks Vector Search index of review chunks, results are re-ranked locally with a cross-encoder, and an LLM produces a grounded answer that cites concrete guest feedback.
  • Conversational: greetings and meta questions.

The map on the left shows every listing that has reviews in the vector index, grouped by the 15 official municipi. Users can click a listing to scope the chat to that specific property, select a district from the dropdown to scope by neighbourhood, or ask a listing by name ("What do guests say about Santini Home?"). When a question is too broad for the whole city, the assistant asks the user to pick a district first.

Pipeline

Pipeline

Layer Technology
Batch ETL PySpark notebooks on Databricks (serverless)
Storage Unity Catalog Delta tables; UC Volume for raw files
Retrieval Databricks Vector Search (Delta Sync, server-side embeddings)
Analytics Databricks SQL Warehouse (Statement Execution API)
Reranker cross-encoder/mmarco-mMiniLMv2-L12-H384-v1 (local, MPS/CPU)
LLM + embeddings Databricks serving endpoints (databricks-gpt-oss-20b, databricks-qwen3-embedding-0-6b)
Backend FastAPI (REST + SSE streaming); serves the frontend build
Frontend React + Vite + Leaflet (map) + Recharts (metrics)
Config .env via pydantic-settings

How it works

Ingestion & preparation (databricks/ notebooks, run on Databricks):

  1. 01_ingest_clean — reads the raw CSVs from a UC Volume, casts columns by name (robust to schema drift), cleans prices (drops out-of-range outliers), and samples reviews with a stratified strategy per district (top K listings per municipio, N reviews each) so the map is balanced across neighbourhoods instead of dominated by the city centre. Writes bronze_* and silver_* Delta tables.
  2. 02_chunk — turns each review into one chunk with listing metadata; writes gold_review_chunks with Change Data Feed enabled (required by Vector Search Delta Sync).
  3. 03_analytics — builds the denormalised listings_enriched view used by Text-to-SQL.
  4. 04_vector_index — creates the Vector Search endpoint and a Delta Sync index; Databricks computes the embeddings server-side from chunk_text.

Serving (api/ + core/, run locally or anywhere with network access to Databricks):

  • intent_classifier routes the query. analytics_core generates SELECT-only SQL (validated against an allowlist) and runs it on the SQL Warehouse. rag_core queries Vector Search, re-ranks with the local cross-encoder, and builds a grounded prompt. llm_client streams the answer token by token (Server-Sent Events), skipping the reasoning tokens of the model.
  • Responses are cached per (query, scope); observability counters (intents, cache hit/miss, per-phase latency) are persisted to disk and shown on the metrics page.

Observability page

Repository layout

databricks/   Databricks notebooks (.ipynb): 01 ingest+clean, 02 chunk, 03 analytics, 04 vector index
core/         in-process libraries: config, llm_client (streaming), intent_classifier,
              reranker, vectorstore (Vector Search client), analytics_core (SQL), rag_core, observability
api/          FastAPI backend: main.py (routes + SSE + SPA hosting), services.py, assets/ (geojson)
web/          React + Vite frontend (Home map+chat, Observability dashboard)
scripts/      check_databricks.py — workspace connectivity check
evaluation/   retrieval (Recall/MRR/nDCG), generation (LLM-as-judge), latency benchmarks
docs/         screenshots

Setup

Requirements: Python 3.11+, Node 18+, Java 11+ (only for running the notebooks locally; on Databricks it is provided), a Databricks workspace with model-serving credits.

# backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env         # fill in DATABRICKS_HOST, DATABRICKS_TOKEN, SQL_WAREHOUSE_ID

# frontend
cd web && npm install && npm run build && cd ..

Run the app

uvicorn api.main:app --port 8000      # open http://localhost:8000

For frontend development with hot reload, run the backend and cd web && npm run dev (Vite proxies /api to port 8000).

evaluation/query_set.json contains 18 labelled queries built with a known-item methodology: each query paraphrases a real review (including distinctive details) and is labelled with the listing it comes from. Latest results on the synced index:

Metric @3 @5 @10
Recall 0.889 1.000 1.000
nDCG 0.862 0.929 0.983

MRR = 0.794 · LLM-as-judge (1–5): faithfulness = 4.83, relevance = 4.89

About

RAG + Text-to-SQL conversational analytics over Inside Airbnb data for Rome, powered by Databricks (Vector Search, SQL Warehouse, Delta Lake), FastAPI, and React.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages