Логика подбора тренировок - ME AI Club

Логика подбора тренировок

Демонстрация гибридного подхода к выбору тренировок: комбинация правил на основе анкеты и интеллектуального выбора через ChatGPT для максимально точного подбора.

Общая схема работы

1. Анкета перед тренировкой
Сбор данных о состоянии пользователя
2. Выбор блока (правила)
RecommendationService.suggest_block_by_state()
3. Проверка противопоказаний
Безопасность превыше всего
4. Выбор конкретного видео (ChatGPT)
AIService.recommend_video_from_block()
5. Результат
Персонализированная тренировка

Шаг 1: Анкета перед тренировкой

1
Сбор данных о состоянии
Перед каждой тренировкой пользователь заполняет короткую анкету из 4 вопросов, которая помогает понять его текущее состояние и настроение.
Настроение: Отлично / Нормально / Уставший(ая) / Свой вариант
Уровень энергии: Высокий / Средний / Низкий
Качество сна: Отлично / Нормально / Очень плохо
Ограничения: Нет / Лёгкое недомогание / Плохо себя чувствую
Пример ответов пользователя
{
  "pre_mood": "Нормально",
  "pre_energy": "Средний",
  "pre_sleep": "Нормально",
  "pre_limits": "Нет"
}
???? Эти данные сохраняются в состоянии FSM и передаются в RecommendationService

Шаг 2: Выбор блока тренировок

2
Правила выбора блока
На основе данных анкеты система выбирает подходящий блок тренировок по эвристическим правилам.

Логика выбора блока:

Плохое самочувствие или усталость → Блок 2 (мобильность, растяжка)
Низкая энергия → Блок 1 (восстановление) или Блок 2
Высокая энергия + отличное настроение → Блок 5 (Табата) или Блок 3
Средняя энергия → Блок 3 (функциональные тренировки)
По умолчанию → Блок 2 (универсальный)
Код: RecommendationService.suggest_block_by_state()
def suggest_block_by_state(mood, energy, sleep, limits, user_level):
    # Плохое самочувствие → Блок 2
    if limits in ("Лёгкое недомогание", "Плохо себя чувствую") 
       or sleep == "Очень плохо":
        return 2
    
    # Низкая энергия → Блок 1 или 2
    if energy == "Низкий" or "Устав" in mood:
        return 1 if user_level <= 2 else 2
    
    # Высокая энергия → Блок 5 или 3
    if energy == "Высокий" and mood == "Отлично":
        return 5 if user_level >= 4 else 3
    
    # Средняя энергия → Блок 3
    if energy == "Средний":
        return 3
    
    # По умолчанию → Блок 2
    return 2
Пример работы
Входные данные:
  mood = "Нормально"
  energy = "Средний"
  sleep = "Нормально"
  limits = "Нет"
  user_level = 3

Результат: Блок 3 (функциональные тренировки)

Шаг 3: Проверка противопоказаний

3
Безопасность превыше всего
Перед финальным выбором система проверяет, нет ли у пользователя противопоказаний для выбранного блока.
Блок 1 Противопоказания: грыжи, недавние операции
Блок 2 Противопоказания: недавние операции, беременность
Блок 3 Противопоказания: беременность, операции, диастаз
Блок 4 Противопоказания: диастаз, беременность, операции
Блок 5 Противопоказания: беременность, травмы коленей, диастаз
Блок 6 Противопоказания: операции нижних конечностей, травмы
Пример проверки
Рекомендованный блок: 1
Ограничения пользователя: "грыжа поясничного отдела"

Результат проверки: ❌ Блок 1 не подходит
Fallback: Блок 2 (мобильность - самый безопасный)
Важно
Если рекомендованный блок имеет противопоказания, система автоматически переключается на Блок 2 (мобильность) - самый безопасный вариант.

Шаг 4: Выбор конкретного видео через ChatGPT

4
Интеллектуальный выбор
После выбора блока система получает список всех доступных видео из этого блока и использует ChatGPT для выбора наиболее подходящего конкретного видео.

Что передается в ChatGPT:

Данные анкеты: mood, energy, sleep, limits
Информация о пользователе: level, goals, restrictions
Метаданные блока: описание, противопоказания, инвентарь
Список видео: title, duration, area, inventory, description
Пример промпта для ChatGPT
Ты помогаешь выбрать конкретную тренировку из блока 3 для пользователя.

ОПИСАНИЕ БЛОКА 3:
Функциональные тренировки на все тело с собственным весом 
или небольшим отягощением. Разнообразные упражнения на баланс, 
координацию, силу и стабилизацию.

ДАННЫЕ АНКЕТЫ ПОЛЬЗОВАТЕЛЯ:
- Настроение: Нормально
- Уровень энергии: Средний
- Качество сна: Нормально
- Ограничения/самочувствие: Нет

ИНФОРМАЦИЯ О ПОЛЬЗОВАТЕЛЕ:
- Уровень подготовки: 3/7
- Цели: улучшение осанки, укрепление корсета
- Ограничения/противопоказания: нет

ДОСТУПНЫЕ ТРЕНИРОВКИ В БЛОКЕ:
1. ID: 45, Название: Блок 3 Тренировка 1, 
   Длительность: 25 мин, Уровень: 3, 
   Зона: core, full_body, glutes, Инвентарь: не требуется

2. ID: 46, Название: Блок 3 Тренировка 2, 
   Длительность: 30 мин, Уровень: 3, 
   Зона: legs, core, balance, full_body, Инвентарь: не требуется

3. ID: 47, Название: Блок 3 Тренировка 3, 
   Длительность: 28 мин, Уровень: 3, 
   Зона: core, balance, full_body, mobility, Инвентарь: не требуется

ТВОЯ ЗАДАЧА:
Выбери ОДНУ наиболее подходящую тренировку на основе:
1. Состояния пользователя (настроение, энергия, сон, ограничения)
2. Уровня подготовки пользователя
3. Целей пользователя
4. Безопасности (учитывай ограничения)

Верни ответ ТОЛЬКО в формате JSON:
{"video_id": <число>, "video_title": "<точное название>"}
Ответ ChatGPT
{
  "video_id": 47,
  "video_title": "Блок 3 Тренировка 3"
}
???? ChatGPT анализирует все данные и выбирает наиболее подходящую тренировку, учитывая текущее состояние пользователя, его цели и безопасность.

Полный пример работы системы

Сценарий: Пользователь устал, но хочет тренироваться
Настроение: Уставшая
Энергия: Низкий
Сон: Нормально
Ограничения: Нет
Уровень пользователя: 2/7
Цели: восстановление, мобильность
Шаг 1: Анкета заполнена
mood="Уставшая", energy="Низкий"
Шаг 2: Выбор блока
suggest_block_by_state() → Блок 1
(Низкая энергия + уровень ≤ 2)
Шаг 3: Проверка противопоказаний
✅ Блок 1 подходит
Шаг 4: Получение видео из БД
get_videos_by_block(1) → 10 видео
Шаг 5: Фильтрация по уровню
Уровень ±1 → 5 видео подходят
Шаг 6: ChatGPT выбирает видео
recommend_video_from_block()
Учитывает: усталость, низкая энергия, цели восстановления
Результат: Видео выбрано
video_id: 12
"Блок 1 Тренировка 5 Нижние конечности (ролл)"
Мягкая восстановительная тренировка на ноги

Механизм Fallback

Что происходит при ошибках
Система имеет несколько уровней защиты на случай, если что-то пойдет не так.
ChatGPT недоступен → Случайный выбор из блока
Блок не подходит → Fallback на Блок 2 (мобильность)
Нет видео в блоке → Fallback на старый метод get_next_video_no_repeat()
ChatGPT вернул неверный ID → Случайный выбор из доступных видео
Гарантия работы
Система всегда вернет какое-то видео, даже если ChatGPT недоступен или произошла ошибка. Пользователь никогда не останется без тренировки.

Технические детали реализации

Файлы и методы

services/recommendation_service.py get_recommended_video() - основной метод
services/ai_service.py recommend_video_from_block() - выбор через ChatGPT
handlers/main_menu.py pre_finish() - обработчик завершения анкеты
services/video_metadata_service.py get_block(), get_block_workouts() - метаданные
Основной вызов в коде
# handlers/main_menu.py, функция pre_finish()

video = rec_service.get_recommended_video(
    mood=mood,
    energy=energy,
    sleep=sleep,
    limits=limits,
    user_level=user.level,
    user_goals=user.goals or "",
    user_restrictions=user.restrictions or "",
    video_service=video_service,
    ai_service=ai_service
)

# Fallback на старый метод, если не удалось подобрать
if not video:
    video = video_service.get_next_video_no_repeat(user.id, user.level)

Преимущества гибридного подхода

✅ Точность ChatGPT учитывает множество факторов одновременно
✅ Безопасность Правила гарантируют выбор безопасного блока
✅ Надежность Множественные уровни fallback
✅ Персонализация Учитываются цели, ограничения, текущее состояние
✅ Масштабируемость Легко добавить новые блоки и тренировки
ME AI Club - Система подбора тренировок
Демонстрация логики работы
Made on
Tilda