Прототип веб-сервиса, который генерирует персональные туристические маршруты по Нижнему Новгороду на основе интересов пользователя, доступного времени и местоположения.
Туристы часто сталкиваются с проблемой планирования маршрутов в новом городе. Стандартные путеводители предлагают однотипные маршруты, которые не учитывают индивидуальные интересы и временные ограничения. Это приводит к тому, что туристы тратят много времени на поиск информации и не всегда получают от прогулки максимум удовольствия.
AI-помощник туриста решает эту проблему, предлагая пользователю ответить на три простых вопроса:
- Интересы: Что бы вы хотели увидеть? (например, стрит-арт, кофейни, панорамы)
- Время: Сколько у вас есть свободного времени?
- Местоположение: Где вы сейчас находитесь?
На основе этих данных, с помощью AI, сервис генерирует уникальный маршрут, который включает в себя:
- 3-5 релевантных мест.
- Объяснение, почему стоит посетить каждое место.
- Оптимальный порядок посещения и таймлайн.
Проект состоит из двух основных частей:
backend/: Backend-сервис на FastAPI (Python), который отвечает за всю логику.app/main.py: Основной файл FastAPI приложения с эндпоинтами.app/services/: Модули, отвечающие за геокодинг, подбор мест, построение маршрута и генерацию описаний.app/data/: Датасет с информацией о достопримечательностях.
frontend/: Простой и интуитивно понятный фронтенд.index.html: Основная страница.static/app.js: Логика фронтенда для взаимодействия с API.static/styles.css: Стили.
- Персонализация: Маршруты строятся на основе семантического анализа интересов пользователя.
- Оптимизация: Алгоритм построения маршрута (решение задачи коммивояжера для небольшого количества точек) находит оптимальный порядок посещения мест для минимизации времени в пути.
- Интерактивность: На карте отображается маршрут, начальная точка и все остановки.
- Обратная связь: Пользователи могут оставить отзыв о предложенном маршруте, что позволяет в будущем улучшать сервис.
-
Клонируйте репозиторий:
git clone <repository-url> cd GorkyCode-Demo
-
Настройте бэкенд:
- Перейдите в директорию
backend:cd backend - Создайте и активируйте виртуальное окружение:
python -m venv .venv source .venv/bin/activate # для Linux/macOS .venv\Scripts\activate # для Windows
- Установите зависимости:
pip install -r requirements.txt
- Создайте файл
.envна основе.env.exampleи укажите вашMISTRAL_API_KEY:cp .env.example .env # Откройте .env и вставьте ваш API ключ
- Перейдите в директорию
-
Запустите бэкенд:
- Находясь в директории
backend, выполните команду:uvicorn app.main:app --reload
- Сервер будет доступен по адресу
http://127.0.0.1:8000.
- Находясь в директории
-
Откройте фронтенд:
- Откройте в браузере
http://127.0.0.1:8000. - Фронтенд будет автоматически загружен.
- Откройте в браузере
Теперь вы можете использовать AI-помощник туриста!
Алгоритм состоит из двух основных этапов:
- Оценка кандидатов (_score_candidates): Каждому месту в датасете присваивается балл (match_score), который отражает, насколько оно релевантно запросу пользователя.
- Построение маршрута (_build_route): Из лучших кандидатов строится оптимальный маршрут с учетом времени и логистики.
Балл для каждого места рассчитывается по формуле:
match_score = base_score + interest_boost - distance_penalty + diversity_boost + semantic_boost
Где:
-
base_score(Базовый балл):1.0, если теги места совпадают с интересами пользователя.0.4, если прямого совпадения по тегам нет. Это позволяет включать в выборку популярные места, даже если они не соответствуют интересам напрямую.
-
interest_boost(Бонус за интересы):+1.5за каждый совпавший тег. Чем больше совпадений, тем выше балл.
-
distance_penalty(Штраф за расстояние):- (расстояние в км * 0.1). Чем дальше место от пользователя, тем ниже будет итоговый балл.
-
diversity_boost(Бонус за разнообразие):+0.2, если у места есть ID категории. Это помогает разнообразить маршрут, включая в него места разных типов.
-
semantic_boost(Семантический бонус):сходство * 2.6. Это самый важный компонент. С помощью embedding-модели (Mistral Embed) мы получаем векторное представление интересов пользователя и описания каждого места. Этот бонус основан на косинусном сходстве этих векторов. Он позволяет находить неочевидные, но семантически близкие места, даже если нет прямого совпадения по тегам. Коэффициент2.6усиливает влияние семантического поиска.
После подсчета баллов все места сортируются по убыванию match_score.
Простой жадный алгоритм (выбирать всегда следующую лучшую точку) может приводить к нелогичным маршрутам (как в примере с "кофе"). Чтобы этого избежать, мы используем более продвинутый подход, основанный на решении задачи коммивояжера (TSP) для небольшого набора точек:
- Выбор пула кандидатов: Берутся 7 лучших мест по
match_score. - Поиск оптимальной перестановки: Алгоритм перебирает все возможные комбинации и порядки посещения этих мест (от 5 до 3 остановок).
- Расчет времени: Для каждой комбинации рассчитывается общее время (время в пути + время на посещение).
- Выбор лучшего маршрута: Выбирается тот маршрут, который укладывается в доступное время пользователя и имеет минимальное общее время в пути.
Этот подход гарантирует, что маршрут будет не только интересным, но и логистически оптимальным.