VELA Dhi Nakhon Phanom How the AI works
Proof of concept · synthetic data
How the AI works

From raw signals to one price, with the working shown

Every night, the engine runs this loop for 365 nights × 4 room types: 1,460 decisions. Pick a night and follow one decision through the pipeline. The numbers below are the engine's own working, not illustrations.

Night Fri, 23 Oct 2026 A · High
Room
  1. 1 Read the signals
  2. 2 Forecast demand
  3. 3 Estimate price response
  4. 4 Optimise contribution
  5. 5 Apply the guardrails
  6. 6 Explain and publish
  7. 7 Learn from what happened
Step 1 · data

Read the signals

Calendar
Tier A · High
Chulalongkorn Day long weekend
On the books (PMS)
49 / 50 rooms
2 days before arrival
Comp set (rate shopper)
Median THB 1,800
0 of 5 sold out
Costs (finance)
THB 380 / room
9.7% blended commission

Production adds weather, DMK–KOP flight seats, Thai–Lao bridge traffic and booking-engine searches. In the PoC these signals are synthetic.

Step 2 · machine learning

Forecast demand

The forecast predicts unconstrained demand: how many rooms we would sell with unlimited inventory. It blends two views and trusts the bookings more as the stay date gets closer.

What pace says
49.5 rooms
49 booked ÷ 99% of demand normally booked by 2 days out (tier-A curve, half-life 30 days)
What the season says
45.5 rooms
91% typical final occupancy for a tier-A night
Forecast demand
49.5 rooms
100% weight on pace · P10–P90 49–50 sellable · pace +9% · confidence high
PoC: a pickup model with seasonal priors, which needs no history to start. Production: gradient-boosted trees (LightGBM) trained on VELA's 3 years of PMS data plus the daily pace snapshots, with weather, events, flights and comp-set rates as features. Accuracy target: MAPE ≤ 10% at 30 days out, checked weekly.
Step 3 · machine learning

Estimate price response

How many fewer rooms do we sell if we charge more? That is price elasticity, and it differs by night. Festival guests barely react to price; a drive-in family on a rainy Tuesday reacts a lot.

For this night the engine uses sensitivity β = 1.12. Pace ahead of the curve reads as lower sensitivity. About 0.5 more rooms are expected at today's price.

5001,3412,192price → final rooms sold
PoC: sensitivity per tier is a hand-set starting assumption (industry priors). Production: a Bayesian model per segment × tier, updated weekly from small controlled price tests on low-risk C/D nights and from comp-set gaps. It starts from the same priors and gets sharper as VELA's own data comes in.
Step 4 · optimisation

Optimise contribution

The optimizer scores every price on the ladder: expected extra rooms × (price − 9.7% commission − THB 380). It maximises contribution, not occupancy or ADR alone.

StepPriceExtraContribution
-21,4900.5512
-1published1,6100.5527
0chosen1,7400.5538
+11,8800.4544
+22,0300.4544
PoC and production: the same search over discrete ladder steps. Searching 6 room types × 365 nights × 15 steps takes seconds. Production adds a displacement (bid-price) check for multi-night stays and groups.
Step 5 · business rules

Apply the guardrails

The optimizer proposes; the GM's rules decide what is allowed. These rules are signed by people, and you can change them in the Strategy studio.

  • Stay inside the tier band (THB 1,490–2,030)
    Checked, not binding
  • Move at most 1 step a day
    Applied to this decision
  • No price drop inside 14 days on A/A+ nights
    Checked, not binding
  • A/A+ moves inside 7 days need the revenue manager
    Applied to this decision
  • Keep room categories ≥ 8% apart
    Checked, not binding
Step 6 · generative AI

Explain and publish

Decision
Superior: THB 1,610 → THB 1,740
Waits for the revenue manager to approve. Contribution +THB 11 vs holding.
  • Chulalongkorn Day long weekend sets this night to tier A.
  • On the books: 49 of 50 rooms, +9% vs the tier-A booking curve at 2 days out.
  • One step up to THB 1,740 adds about THB 11 expected contribution.
Where a large language model (Claude) fits
  • Explains each move in one plain sentence for the RM, in Thai or English.
  • Maps messy PMS export columns during upload.
  • Drafts candidate local events (fairs, seminars) for the GM to confirm.
  • Never sets the price. Prices come from the forecast, optimizer and rules, so they are repeatable and auditable.

In the PoC the reasons are generated from templates.

Step 7 · feedback loop

Learn from what happened

Actual pickup
Retrains the demand forecast weekly
Price tests on C/D nights
Sharpen the price-response model
Package bookings
A Thompson-sampling bandit shifts offers to the winners
RM overrides + reason codes
Show where the model misses local knowledge

Stop-rules keep it safe: if forecast error goes above 10% for two weeks, or the RevPAR index drops under 95, every decision goes back to "recommend only" until people re-sign the rules.

PoC today vs production

ComponentIn this PoCIn production
DataSynthetic hotel, deterministicPMS, channel manager, POS, rate shopper, events, weather
Demand forecastPickup model + seasonal priorGradient-boosted trees, P10/P50/P90, retrained weekly
Price responseHand-set sensitivity per tierBayesian elasticity per segment × tier, learned from price tests
OptimizerContribution search over the ladderSame, plus multi-night displacement
PackagesRanking from prior acceptance ratesContextual bandit learning from bookings
ExplanationsTemplate textClaude, Thai and English
PublishingNothing is sentChannel-manager push (OpenTravel XML)
See this night's full detail and booking replay