404 lines
12 KiB
Markdown
404 lines
12 KiB
Markdown
# Fallback Recommendation System
|
|
|
|
## Overview
|
|
|
|
The AI recommendation system now implements a **tiered fallback strategy** that ensures meaningful service recommendations for almost all trips, instead of simply returning `recommend: false`.
|
|
|
|
## Philosophy
|
|
|
|
**Old Approach (Rejected):**
|
|
- Binary decision: recommend tour OR reject
|
|
- Strict criteria: 2+ days, 3+ places, qualified activities
|
|
- Result: Many viable trips got no recommendations
|
|
|
|
**New Approach (Implemented):**
|
|
- Tiered recommendations: Best match → Fallback services → Only reject trivial trips
|
|
- Flexible criteria: Consider trip characteristics holistically
|
|
- Result: Almost all trips get helpful service suggestions
|
|
|
|
## Recommendation Tiers
|
|
|
|
### Tier 1: Matched Daily Tours (Confidence: 0.70-0.95)
|
|
**Trigger:** Place types match existing tour routes with ≥50% overlap
|
|
|
|
**Services:**
|
|
- `red_tour` - Museums, valleys, Göreme area
|
|
- `green_tour` - Underground cities, Ihlara Valley, nature
|
|
- `blue_tour` - Off-beaten path, quiet villages
|
|
- `balloon_day` - Balloon flight + light tour
|
|
|
|
**Example:**
|
|
```
|
|
Trip: 3 days, 12 places (museums, valleys, underground cities)
|
|
Density: 42 (HIGH)
|
|
→ Recommendation: red_tour (daily_tour type)
|
|
→ Confidence: 0.85
|
|
→ Reason: "Your plan matches Red Tour route with 75% overlap"
|
|
```
|
|
|
|
### Tier 2: Fallback Services (Confidence: 0.55-0.70)
|
|
**Trigger:** No perfect tour match, but trip has characteristics that benefit from professional services
|
|
|
|
#### Fallback 2A: Short Dense Trips
|
|
**Criteria:** 1 day + density ≥30
|
|
|
|
**Logic:**
|
|
- If travelers ≥4 → `private_guide` (confidence: 0.65)
|
|
- If travelers <4 → `driver_car` (confidence: 0.60)
|
|
|
|
**Example:**
|
|
```
|
|
Trip: 1 day, 5 places, density: 35
|
|
Travelers: 2
|
|
→ Recommendation: driver_car
|
|
→ Confidence: 0.60
|
|
→ Reason: "A driver service would help you maximize your limited time"
|
|
```
|
|
|
|
#### Fallback 2B: Long Distance Trips
|
|
**Criteria:** Total distance ≥50km
|
|
|
|
**Service:** `driver_car` (confidence: 0.65)
|
|
|
|
**Example:**
|
|
```
|
|
Trip: 2 days, 4 places, distance: 85km
|
|
→ Recommendation: driver_car
|
|
→ Confidence: 0.65
|
|
→ Reason: "The distances between your destinations make a driver service valuable"
|
|
```
|
|
|
|
#### Fallback 2C: Multiple Destinations
|
|
**Criteria:** 3+ places (no tour match)
|
|
|
|
**Service:** `private_guide` (confidence: 0.55)
|
|
|
|
**Example:**
|
|
```
|
|
Trip: 2 days, 4 places, density: 25
|
|
→ Recommendation: private_guide
|
|
→ Confidence: 0.55
|
|
→ Reason: "A private guide could enhance your experience across multiple sites"
|
|
```
|
|
|
|
#### Fallback 2D: Large Groups
|
|
**Criteria:** 4+ travelers
|
|
|
|
**Service:** `private_guide` (confidence: 0.60)
|
|
|
|
**Example:**
|
|
```
|
|
Trip: 2 days, 3 places
|
|
Travelers: 5
|
|
→ Recommendation: private_guide
|
|
→ Confidence: 0.60
|
|
→ Reason: "Your group size makes a private guide service worthwhile"
|
|
```
|
|
|
|
### Tier 3: AI Fallback (Confidence: 0.35-0.55)
|
|
**Trigger:** Rule-based fallbacks don't match, but AI finds value
|
|
|
|
**Services:** Any service type based on AI analysis
|
|
|
|
**Example:**
|
|
```
|
|
Trip: 1 day, 2 places, density: 18
|
|
But: Historical sites requiring expert knowledge
|
|
→ AI Recommendation: private_guide
|
|
→ Confidence: 0.45
|
|
→ Reason: "Historical context would significantly enhance your experience"
|
|
```
|
|
|
|
### Tier 4: No Recommendation (Confidence: <0.35)
|
|
**Trigger:** Trip is truly trivial
|
|
|
|
**Criteria:**
|
|
- 1 place OR
|
|
- <5km total distance AND <2 hours total time
|
|
|
|
**Example:**
|
|
```
|
|
Trip: 1 place, 2km, 1 hour
|
|
→ Recommendation: None (recommend: false)
|
|
→ Reason: "Your trip is simple enough to manage independently"
|
|
```
|
|
|
|
## Decision Flow
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ TRIP ANALYSIS │
|
|
│ Calculate: density, distance, time, place count │
|
|
└────────────────────────┬────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ TIER 1: MATCHED DAILY TOUR? │
|
|
│ Query database for tours matching place types │
|
|
└────────────┬────────────────────────────┬───────────────────┘
|
|
│ YES (confidence ≥0.5) │ NO
|
|
▼ ▼
|
|
┌────────────────────┐ ┌──────────────────────────────┐
|
|
│ Return Tour │ │ TIER 2: FALLBACK SERVICES? │
|
|
│ (red/green/blue) │ │ Check trip characteristics │
|
|
└────────────────────┘ └──────┬───────────────────┬───┘
|
|
│ YES │ NO
|
|
▼ ▼
|
|
┌──────────────────┐ ┌────────────────┐
|
|
│ Return Fallback │ │ TIER 3: AI │
|
|
│ (private_guide/ │ │ Analysis │
|
|
│ driver_car) │ └────┬───────┬───┘
|
|
└──────────────────┘ │ YES │ NO
|
|
▼ ▼
|
|
┌──────────────┐ ┌────────┐
|
|
│ Return AI │ │ TIER 4 │
|
|
│ Suggestion │ │ Reject │
|
|
└──────────────┘ └────────┘
|
|
```
|
|
|
|
## Fallback Logic Implementation
|
|
|
|
### Rule-Based Fallbacks (Lines 534-710)
|
|
|
|
```typescript
|
|
// Check if trip is truly trivial
|
|
const isTrivialTrip = totalPlaces <= 1 && totalDistanceKm < 5 && totalTimeHours < 2;
|
|
|
|
if (isTrivialTrip) {
|
|
return { recommend: false, ... };
|
|
}
|
|
|
|
// Fallback 1: Short but dense trips
|
|
if (totalDays === 1 && maxDensityScore >= 30) {
|
|
if (travelers >= 4) {
|
|
return { recommend: true, slug: 'private_guide', confidence: 0.65, ... };
|
|
} else {
|
|
return { recommend: true, slug: 'driver_car', confidence: 0.60, ... };
|
|
}
|
|
}
|
|
|
|
// Fallback 2: Long distances
|
|
if (totalDistanceKm >= 50) {
|
|
return { recommend: true, slug: 'driver_car', confidence: 0.65, ... };
|
|
}
|
|
|
|
// Fallback 3: Multiple places
|
|
if (totalPlaces >= 3) {
|
|
return { recommend: true, slug: 'private_guide', confidence: 0.55, ... };
|
|
}
|
|
|
|
// Fallback 4: Large groups
|
|
if (travelers >= 4) {
|
|
return { recommend: true, slug: 'private_guide', confidence: 0.60, ... };
|
|
}
|
|
```
|
|
|
|
### AI Fallback (Lines 774-940)
|
|
|
|
Updated AI prompt with fallback instructions:
|
|
```
|
|
FALLBACK STRATEGY: Even if no perfect tour match, consider:
|
|
- Short but dense trips (1 day, density ≥30) → private_guide or driver_car
|
|
- Long distances (≥50km) → driver_car
|
|
- Large groups (≥4 people) → private_guide
|
|
- Multiple places (≥3) → private_guide
|
|
|
|
ONLY return recommend:false if trip is truly trivial (1 place, <5km, <2 hours).
|
|
```
|
|
|
|
Adjusted confidence threshold:
|
|
```typescript
|
|
// Old: if (analysis.confidence < 0.6) analysis.recommend = false;
|
|
// New: if (analysis.confidence < 0.35) analysis.recommend = false;
|
|
```
|
|
|
|
## Benefits of Fallback System
|
|
|
|
### 1. Better User Experience
|
|
- Users get helpful suggestions even for non-standard trips
|
|
- No frustrating "no recommendations" messages
|
|
- More opportunities for service providers
|
|
|
|
### 2. Increased Conversion
|
|
- More trips trigger recommendations
|
|
- Lower confidence recommendations still provide value
|
|
- Users can make informed decisions
|
|
|
|
### 3. Flexible Service Matching
|
|
- Not limited to predefined tour routes
|
|
- Can recommend services based on trip characteristics
|
|
- Adapts to various trip types
|
|
|
|
### 4. Transparent Confidence Levels
|
|
- Users see confidence scores
|
|
- Can judge recommendation quality
|
|
- Debug info explains reasoning
|
|
|
|
## Confidence Level Interpretation
|
|
|
|
| Confidence | Meaning | User Action |
|
|
|-----------|---------|-------------|
|
|
| 0.85-1.00 | Highly Recommended | Strong match, definitely consider |
|
|
| 0.70-0.84 | Recommended | Good match, worth exploring |
|
|
| 0.55-0.69 | Suggested | Helpful but optional |
|
|
| 0.40-0.54 | Optional | Consider if interested |
|
|
| 0.35-0.39 | Marginal | Minimal benefit |
|
|
| <0.35 | Not Recommended | Self-planning sufficient |
|
|
|
|
## Examples
|
|
|
|
### Example 1: Short Dense Trip (Fallback 2A)
|
|
```json
|
|
{
|
|
"trip": {
|
|
"days": 1,
|
|
"places": 5,
|
|
"density": 35,
|
|
"travelers": 2
|
|
},
|
|
"recommendation": {
|
|
"recommend": true,
|
|
"recommended_type": "driver_car",
|
|
"daily_tour_slug": "driver_car",
|
|
"confidence": 0.60,
|
|
"reason": "A driver service would help you maximize your limited time",
|
|
"why_better_than_self": [
|
|
"Comfortable transportation between sites",
|
|
"No parking hassles",
|
|
"More time at attractions",
|
|
"Local driver knows best routes"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Example 2: Long Distance Trip (Fallback 2B)
|
|
```json
|
|
{
|
|
"trip": {
|
|
"days": 2,
|
|
"places": 4,
|
|
"distance": 85,
|
|
"travelers": 3
|
|
},
|
|
"recommendation": {
|
|
"recommend": true,
|
|
"recommended_type": "driver_car",
|
|
"daily_tour_slug": "driver_car",
|
|
"confidence": 0.65,
|
|
"reason": "The distances between your destinations make a driver service valuable",
|
|
"why_better_than_self": [
|
|
"Comfortable long-distance travel",
|
|
"No navigation stress",
|
|
"Flexible stops along the way",
|
|
"Arrive refreshed at each destination"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Example 3: Large Group (Fallback 2D)
|
|
```json
|
|
{
|
|
"trip": {
|
|
"days": 2,
|
|
"places": 3,
|
|
"travelers": 5
|
|
},
|
|
"recommendation": {
|
|
"recommend": true,
|
|
"recommended_type": "private_guide",
|
|
"daily_tour_slug": "private_guide",
|
|
"confidence": 0.60,
|
|
"reason": "Your group size makes a private guide service worthwhile",
|
|
"why_better_than_self": [
|
|
"Keep everyone together",
|
|
"Customized to group interests",
|
|
"Better group coordination",
|
|
"Shared cost makes it economical"
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Example 4: Trivial Trip (Tier 4 - Rejected)
|
|
```json
|
|
{
|
|
"trip": {
|
|
"days": 1,
|
|
"places": 1,
|
|
"distance": 2,
|
|
"time": 1
|
|
},
|
|
"recommendation": {
|
|
"recommend": false,
|
|
"reason": "Your trip is simple enough to manage independently",
|
|
"confidence": 0
|
|
}
|
|
}
|
|
```
|
|
|
|
## Testing Scenarios
|
|
|
|
### Scenario 1: One Day, High Density
|
|
- **Input:** 1 day, 6 places, density: 40, 2 travelers
|
|
- **Expected:** driver_car, confidence: 0.60
|
|
- **Reason:** Short but dense trip fallback
|
|
|
|
### Scenario 2: Two Days, Long Distance
|
|
- **Input:** 2 days, 3 places, 95km, 3 travelers
|
|
- **Expected:** driver_car, confidence: 0.65
|
|
- **Reason:** Long distance fallback
|
|
|
|
### Scenario 3: Small Trip, Large Group
|
|
- **Input:** 1 day, 2 places, 4 travelers
|
|
- **Expected:** private_guide, confidence: 0.60
|
|
- **Reason:** Large group fallback
|
|
|
|
### Scenario 4: Multiple Places, No Match
|
|
- **Input:** 2 days, 4 places, no tour match
|
|
- **Expected:** private_guide, confidence: 0.55
|
|
- **Reason:** Multiple destinations fallback
|
|
|
|
### Scenario 5: Truly Trivial
|
|
- **Input:** 1 place, 2km, 1 hour
|
|
- **Expected:** recommend: false
|
|
- **Reason:** Trip is trivial
|
|
|
|
## Migration Notes
|
|
|
|
### Breaking Changes
|
|
- None - API response format unchanged
|
|
- Confidence thresholds adjusted (0.6 → 0.35)
|
|
|
|
### Behavioral Changes
|
|
- More trips now receive recommendations
|
|
- Lower confidence recommendations are now valid
|
|
- `recommend: false` is much rarer
|
|
|
|
### UI Impact
|
|
- No changes required
|
|
- Confidence badges already display properly
|
|
- Lower confidence recommendations show appropriately
|
|
|
|
## Future Enhancements
|
|
|
|
1. **Dynamic Confidence Thresholds**
|
|
- Adjust based on user feedback
|
|
- A/B test different thresholds
|
|
|
|
2. **More Fallback Types**
|
|
- Photography tours for scenic trips
|
|
- Culinary tours for food-focused trips
|
|
- Adventure tours for active trips
|
|
|
|
3. **Personalized Fallbacks**
|
|
- Consider user history
|
|
- Learn from past bookings
|
|
- Adapt to user preferences
|
|
|
|
4. **Seasonal Adjustments**
|
|
- Higher confidence for peak season
|
|
- Different services for off-season
|
|
- Weather-based recommendations
|