⬡ Under The Hood
How the AI Engine Works
A technical walkthrough of every step — from natural language input to a contextually ranked list of spaces. Built on semantic embeddings, graph-based orchestration, and multi-factor scoring.
The Big Picture
When you submit an event request, your text travels through a 5-node AI pipeline built with LangGraph. Each node does one job: extract intent, apply constraints, match semantically, score dynamically, and generate an explanation. The whole thing runs in under 2 seconds.
1
Node 1 of 5
Intent Extraction
The engine reads your plain-English description and extracts structured intent:
What type of event is this? What atmosphere do you want? How important is luxury?
How much noise is acceptable? Is this social or professional?
This is done by a language model prompt that outputs a JSON object. For example, "outdoor rooftop wedding for VIP guests at sunset" becomes:
This is done by a language model prompt that outputs a JSON object. For example, "outdoor rooftop wedding for VIP guests at sunset" becomes:
# Input (your text)
"Outdoor rooftop wedding reception for 100 guests, ultra-luxury VIP experience at sunset"
# Output (structured intent JSON)
{
"event_type": "wedding",
"atmosphere": "romantic",
"luxury_expectation": 0.92,
"noise_tolerance": 0.5,
"social_context": "celebration",
"indoor_preference": false
}
LangGraph Node
Prompt Engineering
JSON Schema Output
2
Node 2 of 5
Constraint Analysis
Now the engine applies hard filters — rules that eliminate spaces that simply can't work.
If you need 100 guests, a 22-seat boardroom is out, regardless of how good the AI match score is.
Constraints checked include: guest count vs. capacity, indoor/outdoor preference, availability status, and weather compatibility (e.g., outdoor spaces get flagged on rainy days).
Constraints checked include: guest count vs. capacity, indoor/outdoor preference, availability status, and weather compatibility (e.g., outdoor spaces get flagged on rainy days).
Hard Filters
Weather Logic
Capacity Check
3
Node 3 of 5
Semantic Matching via Embeddings
This is the core of the ML system. Each space in the database has been pre-converted into a
384-dimensional vector (called an embedding) that represents its meaning.
Your query is also converted into a vector — then we find the spaces with the most similar vectors.
Think of it like converting words into coordinates in 384-dimensional space. "Rooftop wedding" lands close to "Infinity Pool Deck" and "Skyline Rooftop" because their descriptions share semantic meaning, even if the exact words differ.
Think of it like converting words into coordinates in 384-dimensional space. "Rooftop wedding" lands close to "Infinity Pool Deck" and "Skyline Rooftop" because their descriptions share semantic meaning, even if the exact words differ.
Cosine Similarity Formula
similarity(query, space) = (query · space) / (|query| × |space|)
Range: 0.0 (no match) → 1.0 (perfect match)
# Your description → embedding vector (384 numbers)
query_vec = model.encode("outdoor rooftop wedding...")
# [0.021, -0.143, 0.087, 0.312, ... 384 values total]
# Compare against all space vectors using FAISS
scores = faiss_index.search(query_vec, top_k=20)
# Returns top 20 most similar spaces instantly
Example embedding vector (first 32 of 384 dimensions):
Each color cell = one number. Blue = positive, red = negative, intensity = magnitude.
sentence-transformers
all-MiniLM-L6-v2 model
FAISS vector index
384 dimensions
4
Node 4 of 5
Dynamic Contextual Scoring
Semantic similarity alone isn't enough. A ballroom might match "elegant wedding" well semantically,
but if you need 300 guests and it only fits 80, that's a problem.
Node 4 blends the semantic score with contextual factors — luxury level, noise tolerance, weather suitability, and capacity fit — into a single Final Score. It also detects whether a space has a SpaceTransformation available (e.g., Pool Deck → Covered Cocktail Reception on rainy days) and boosts its score accordingly.
Node 4 blends the semantic score with contextual factors — luxury level, noise tolerance, weather suitability, and capacity fit — into a single Final Score. It also detects whether a space has a SpaceTransformation available (e.g., Pool Deck → Covered Cocktail Reception on rainy days) and boosts its score accordingly.
Final Score Formula
final = (semantic × 0.50) + (luxury_fit × 0.20) + (capacity_fit × 0.15) + (noise_fit × 0.10) + (weather_fit × 0.05)
+ 0.15 bonus if transformation available on rainy/windy day
Semantic
50%
How well the description matches the space's meaning
Luxury Fit
20%
Does the space's luxury level match your VIP expectation?
Capacity Fit
15%
How well guest count fits (penalty if over or under)
Noise Fit
10%
Match between space noise level and event type
Weather Fit
5%
Is the space suitable for the reported weather?
Weighted Scoring
SpaceTransformation detection
Weather boost logic
5
Node 5 of 5
Explanation Generation
The final node generates a plain-English explanation for why each space was recommended.
It references the specific factors that drove the score: semantic match, luxury level,
capacity fit, and any active transformation.
If weather is rainy or windy and the space has a transformation available, the explanation specifically calls out the conversion option and how long setup takes.
If weather is rainy or windy and the space has a transformation available, the explanation specifically calls out the conversion option and how long setup takes.
# Example output for Skyline Rooftop on a rainy day
"Skyline Rooftop scores highly for an outdoor wedding with panoramic views
and a luxury score of 10/10. Note: current weather is rainy — this space
can be converted to Enclosed Sky Pavilion in 240 min (8 staff required),
maintaining full skyline views with complete weather protection."
Template-based NLG
Transformation-aware
Per-space explanation
Why Not Just Use ChatGPT?
Technology Stack
🐍
Django 4.2
v4.2.13
Web framework, ORM, admin panel, and URL routing
🔗
LangGraph
v0.2.28
5-node stateful AI workflow — orchestrates every step of the pipeline
🧠
sentence-transformers
all-MiniLM-L6-v2
Converts text descriptions into 384-dimensional semantic vectors
⚡
FAISS
faiss-cpu
Facebook AI Similarity Search — instant nearest-neighbor lookup over all space embeddings
🗺
Leaflet.js
v1.9.4
Interactive map showing building locations with CartoDB dark tiles
🗄
SQLite
Built-in
Local database storing buildings, spaces, transformations, and recommendation history