38980-vm/app-9w9pd00g5j41/AI_RECOMMENDATION_FIX.md
2026-03-04 18:25:09 +00:00

6.3 KiB

AI Recommendation Type Fix

Problem Statement

The AI recommendation system was hardcoding recommended_type: 'daily_tour' for all recommendations, regardless of the actual service being matched. This caused inconsistencies where:

  • A private_guide service would be recommended but labeled as daily_tour
  • The UI couldn't properly distinguish between different service types
  • The system couldn't recommend driver_car or activity_bundle services

Solution Overview

The fix implements dynamic type derivation from the matched service slug, ensuring that:

  1. recommended_type is always derived from the actual service slug
  2. All three service types (private_guide, driver_car, daily_tour) are valid outputs
  3. The UI renders recommendations strictly based on AI output without assumptions

Changes Made

1. Edge Function: analyze-trip/index.ts

Rule-Based Matching (Lines 475-530)

// CRITICAL: Derive recommended_type from matched service slug
let recommendedType: 'daily_tour' | 'private_guide' | 'driver_car' | 'activity_bundle' = 'daily_tour';

if (matchedDailyTour.slug === 'private_guide') {
  recommendedType = 'private_guide';
} else if (matchedDailyTour.slug === 'driver_car') {
  recommendedType = 'driver_car';
} else if (matchedDailyTour.slug === 'activity_bundle') {
  recommendedType = 'activity_bundle';
} else {
  // All other slugs (red_tour, green_tour, blue_tour, balloon_day, etc.) are daily tours
  recommendedType = 'daily_tour';
}

Logic:

  • If slug is private_guide → type is private_guide
  • If slug is driver_car → type is driver_car
  • If slug is activity_bundle → type is activity_bundle
  • If slug is any tour (red_tour, green_tour, etc.) → type is daily_tour

AI Response Validation (Lines 756-778)

// CRITICAL: Validate and derive recommended_type from daily_tour_slug
if (analysis.daily_tour_slug) {
  if (analysis.daily_tour_slug === 'private_guide') {
    analysis.recommended_type = 'private_guide';
  } else if (analysis.daily_tour_slug === 'driver_car') {
    analysis.recommended_type = 'driver_car';
  } else if (analysis.daily_tour_slug === 'activity_bundle') {
    analysis.recommended_type = 'activity_bundle';
  } else if (['red_tour', 'green_tour', 'blue_tour', 'balloon_day', 'mixed_custom'].includes(analysis.daily_tour_slug)) {
    analysis.recommended_type = 'daily_tour';
  }
}

Purpose: Ensures AI responses are validated and corrected if the AI returns inconsistent type/slug combinations.

Updated AI Prompt (Lines 673-698)

Added clear instructions to the AI:

ÖNEMLİ KURAL: 
- recommended_type ve daily_tour_slug UYUMLU OLMALI!
- Eğer daily_tour_slug = "private_guide" ise, recommended_type = "private_guide"
- Eğer daily_tour_slug = "driver_car" ise, recommended_type = "driver_car"
- Eğer daily_tour_slug = "red_tour/green_tour/blue_tour/balloon_day/mixed_custom" ise, recommended_type = "daily_tour"

2. Database: Added Missing Service Types

Migration: add_driver_car_and_activity_bundle_services_fixed

Added two new service types to daily_tours table:

INSERT INTO daily_tours (slug, title, description, ...) VALUES
('driver_car', 'Şoförlü Araç Hizmeti', '...'),
('activity_bundle', 'Aktivite Paketi', '...');

Current Service Types:

  • red_tour → daily_tour
  • green_tour → daily_tour
  • blue_tour → daily_tour
  • balloon_day → daily_tour
  • private_guide → private_guide
  • driver_car → driver_car
  • activity_bundle → activity_bundle

3. UI Components

TourModal.tsx

Added type labels for better UX:

const typeLabels: Record<string, string> = {
  daily_tour: 'Günlük Tur',
  private_guide: 'Özel Rehber',
  driver_car: 'Şoförlü Araç',
  activity_bundle: 'Aktivite Paketi',
};

Updated dialog description to show Turkish labels:

{typeLabels[analysis.recommended_type] || analysis.recommended_type}

AITourRecommendation.tsx

Already had proper type labels and renders based on analysis.recommended_type without assumptions.

Type Mapping Rules

Service Slug Recommended Type Description
red_tour daily_tour Full-day Red Tour
green_tour daily_tour Full-day Green Tour
blue_tour daily_tour Full-day Blue Tour
balloon_day daily_tour Balloon + Light Tour
mixed_custom daily_tour Custom Mixed Tour
private_guide private_guide Private Guide Service
driver_car driver_car Driver with Car Service
activity_bundle activity_bundle Activity Package

Validation Flow

1. AI/Rule-Based Matching
   ↓
2. Match Service Slug (e.g., "private_guide")
   ↓
3. Derive Type from Slug
   ↓
4. Return Response with:
   - recommended_type: "private_guide"
   - daily_tour_slug: "private_guide"
   ↓
5. UI Renders Based on Type
   - Shows "Özel Rehber" label
   - Filters providers with private_guide service

Testing Checklist

  • Rule-based matching derives correct type
  • AI response validation corrects inconsistencies
  • All service types (daily_tour, private_guide, driver_car, activity_bundle) can be recommended
  • UI displays correct Turkish labels
  • search-tours edge function filters by daily_tour_slug
  • Database has all service types
  • Lint passes without errors

Debug Information

The system now includes detailed debug info in responses:

{
  "debug_info": {
    "recommendation_reasoning": "Matched service 'private_guide' (type: private_guide) with 75% confidence. ..."
  }
}

This helps track:

  • Which service was matched
  • What type was derived
  • Why the recommendation was made

Benefits

  1. Consistency: Type always matches the actual service being recommended
  2. Flexibility: All service types can be recommended based on trip characteristics
  3. Transparency: Debug info shows exactly how the type was derived
  4. Maintainability: Single source of truth for type derivation logic
  5. User Experience: Proper Turkish labels for all service types

Future Enhancements

  • Add more service types as needed (e.g., photography_tour, culinary_tour)
  • Implement confidence-based type selection (e.g., if confidence < 0.7, suggest driver_car instead of full tour)
  • Add A/B testing to compare recommendation accuracy