⬡ 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:
# 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).
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.
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.
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.
# 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?
Capability Generic LLM (ChatGPT) This Engine
Knows your actual spaces ✗ No — hallucinates venue details ✓ Yes — reads live DB data
Real-time availability check ✗ No ✓ Yes — queries availability_status
Transformation logic ✗ No ✓ Yes — weather-aware boost + badge
Reproducible scoring ~ Inconsistent — varies per run ✓ Deterministic — same input = same score
Works offline / no API cost ✗ Requires OpenAI API ✓ Runs locally — all models on-device
Auditable reasoning ~ Black box ✓ Every score is inspectable
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