Разработка бота Menteora — учёт стресса в тренировках спортсменов
КодингЯ полгода учил бота предсказывать мой тонус завтрашним утром. Потом выключил весь ИИ — и бот снова стал полезным
В марте я сделал Telegram-бота для бегунов, который учитывает стресс. К июлю у него было четыре модели машинного обучения, языковая модель-коуч, прогноз на завтра, корреляции, недельные AI-отчёты и 160 зарегистрированных пользователей. В сентябре я понял, что сам не верю в продукт. Для меня он стал бесполезным.
Это история о том, как Menteora выросла в сложную систему и сжалась обратно до одной функции. И почему одна функция оказалась полезнее всех остальных вместе взятых.
Часы говорили «тренируйся на максимум», а я знал, что сегодня точно нельзя этого делать. Кого слушать?
Я пробежал 365 полумарафонов подряд и пытаюсь научиться верить тому, что Garmin показывает по утрам. Сон, пульс покоя, вариабельность пульса, готовность к тренировке.
Регулярно случалось так, что часы показывали полную батарейку, а я уже в кроссовках понимал, что интервалы сегодня закончатся плохо. У меня горел проект. Я нервничал и стрессовал. Куча проблем прибивает.
Часы показывают физиологию. Они не знают, что у вас дедлайн, и не знают, что вы на взводе. А организм тратит на стресс тот же ресурс восстановления, что и на темповую тренировку.
Идея заключалась в том, чтобы бот спрашивал меня о стрессе и клал вердикт по текущему фону стресса рядом с цифрами часов. Чтобы в тренировке учесть стресс.
Первая версия: пять вопросов и одно число
9 марта я набросал первые идеи. Выбрал проверенные психологические шкалы: короткий опрос утром и вечером, тест воспринимаемого стресса PSS-10 раз в месяц, шкалу жизненных событий Холмса-Рея при старте. Вечером — оценку тяжести тренировки по шкале Борга.
Утром бот задавал пять вопросов: самочувствие, сон, мотивация, внешний стресс, боль в мышцах. Из ответов складывалось одно число от 1 до 10 — индекс ментальной готовности, MRI. Веса я назначил сам: сон и самочувствие по 30%, мотивация 20%, стресс и боль по 10%. Цвет зоны подсказывал интенсивность: зелёный, жёлтый, красный.
Через неделю к этому добавились данные Garmin: Body Battery и готовность к тренировке. 13 марта я впервые увидел их под своим MRI. Бот работал как часы.
Первым пользователем был я сам. Когда появился второй юзер, выяснилось, что он видит в боте мои данные Garmin: клиент был один на всех. Это был первый из многих уроков о том, что «работает у меня» — не значит «работает».
Как я подсел на искусственный интеллект
13 марта я задал себе вопрос: а что, если модель будет учиться на каждом бегуне отдельно? Тогда каждый получит к отчёту Garmin свой личный ментальный слой. За два дня план превратился в дорожную карту из пяти этапов.
К июню в боте появились новые функции:
- Корреляции. Бот искал связи между ответами и данными часов: «когда у тебя падает вариабельность пульса, на следующий день MRI ниже».
- Персональные веса. Модель градиентного бустинга подбирала, какой фактор важнее именно для вас. У одного решает сон, у другого стресс.
- Прогноз на завтра. Вечером бот говорил, каким будет ваше утро, и подсказывал, планировать ли интенсивную тренировку.
- Общая модель на всех пользователях. Чтобы новичок получал прогноз с первого дня, а не через три недели.
- Коуч на языковой модели. После утреннего опроса — короткий живой совет с учётом сна, часов и вчерашней тренировки.
- AI-разбор недели по воскресеньям.
За это отвечали модели машинного обучения на деревьях решений плюс одна языковая модель. Звучало мощно, выглядело убедительно. Модели каждую ночь переобучались, прогноз показывал уверенность, отчёт писал тёплым тоном спортивного психолога.
Тревожный звонок прозвенел уже в апреле: оказалось, что прогноз на самом деле не учится, а стоит на скользящем среднем за неделю. Я выяснил это не измерением, а ещё одной ИИ-моделью.
И получил бан от Garmin
Параллельно продукт учился зарабатывать — но в основном учился я сам.
Garmin. Официального доступа к данным для частного лица нет: в апреле Garmin отказал в API, потому что у меня не было юрлица и корпоративного домена. Неофициальный доступ банил сервер. Сначала бот заново входил в аккаунт при каждой ошибке и сжёг три IP-адреса. Потом даже один запрос в сутки с облачного сервера получал отказ. Решение — отдельный сервер, через который ходят только запросы к Garmin.
Оплата. Сначала подписка за Telegram Stars, 250 звёзд в месяц. Ни одной оплаты. Выяснилось, что из России звёзды почти не купить. Подключили оплату картой и СБП через Tribute. В мае раздали 15-дневный пробный период 47 пользователям и построили лестницу напоминаний. Первое напоминание ушло людям с технической заглушкой вместо текста — пришлось извиняться рассылкой.
Люди. К июлю в базе было 148 пользователей, но 64% уже заблокировали бота. Половина уходила на первом-втором опросе. В августе выяснилось, что реальных пользователей не 201, как показывала база, а 82. Все мои проценты удержания были посчитаны по базе, раздутой в 2,4 раза.
В июле я прогнал продукт через методику Next Move Theory Ивана Замесина. Вывод был неприятный: «ментальная готовность для бегунов» проигрывает бесплатной готовности в часах. Человек платит не за ещё одно число, а за решение, что делать с тренировкой.
Июль: четыре дня, которые разобрали все модели
В конце июля я заметил странное: у одного пользователя вес сна в персональной модели был равен нулю. Человеку каждое утро задают вопрос о сне, а модель решила, что сон на него не влияет. Мы начали проверять каждую модель на живых данных. За четыре дня ни одна не выдержала проверку.
Персональные веса. Модель училась на ответе «была ли рекомендация полезной». Но рекомендация зависела только от цвета зоны, а зона считалась из тех же пяти ответов. Модель училась воспроизводить собственную формулу. На новых данных она обыгрывала константу на 3% при нашей планке в 10%. У одного человека два дня с одинаковыми ответами дали MRI 6,8 и 7,7.
Главное открытие было не в коде. У «ментальной готовности» нет прибора, с которым можно сверить веса. MRI — не измерение, а наше определение. Учить веса определения не на чем, сколько данных ни собери.
Прогноз на завтра. Модель проигрывала простой арифметике: средняя ошибка 1,24 балла против 1,11 у личного среднего за месяц. Значит, ни данные часов, ни вечерние ответы, ни паттерны ничего не добавляли к обычному «завтра вы будете примерно таким, как обычно».
Тяжесть тренировки по утренним ответам. Хуже наивной догадки на 5,5%.
Красная зона. Попутно нашёлся баг: 278 ложных красных зон у 69 пользователей. Люди четыре месяца подряд сообщали нам об этом ответом «рекомендация бесполезна». А мы отправляли этот сигнал в обучение модели вместо того, чтобы просто его прочитать.
26 июля я выключил подачу всех моделей. Прогноз стал формулой из двух чисел: четверть — сегодняшнее состояние, три четверти — ваша личная норма за 28 дней. Ночное обучение остановили через три дня.
Месяц честной арифметики, которая говорила одно и то же
После отключения моделей бот стал считать честно. И каждый день говорил мне: «Обычный для тебя фон, тренировка не выше средней».
Новая проблема. Формула, где три четверти веса у нормы, почти не двигается. Разброс прогноза получался около 0,36 балла при ширине цветной зоны в 3 балла. Формула была точной и при этом бесполезной: она почти всегда угадывала, потому что почти всегда говорила «как обычно».
В этом месяце я узнал разницу между точностью и пользой на собственной шкуре:
- Вечером после темповой на 8 из 10 бот обещал: «Можно планировать высокую интенсивность». Вечерний прогноз физически не мог знать, восстановлюсь ли я.
- После одной из самых тяжёлых тренировок в жизни, с Body Battery 25, бот ждал от меня «обычного уровня 6,5». Формула вообще не видела сегодняшнюю тренировку.
- Коуч на языковой модели спорил с расчётом на одном экране в каждом четвёртом обычном дне. Расчёт говорил «обычный день», коуч писал «организму нужно восстановление». А ещё сам назначал «5 серий по 800 метров» человеку, которому ядро советовало середину.
- Новичкам первые три дня бот на любые ответы выдавал один и тот же совет «лёгкая тренировка». Половина уходила, так и не увидев ни одного личного числа.
Я всё это чинил. Каждый фикс был правильным. Но сумма правильных фиксов не превращалась в продукт, которым хочется пользоваться.
Сентябрь: «Я не верю в продукт»
13 сентября я честно сформулировал, что получилось: кривой прогноз на завтра, вечерний анализатор, утренняя диагностика и лишняя кнопка. А вообще-то он должен был учитывать стресс в дополнение к данным часов. Поднял данные за полгода, и они показали четыре вещи.
Прогноз на завтра никому не нужен. Его нельзя проверить в момент получения и нельзя по нему ничего сделать сегодня. Завтра утром человек получает новое число, а старое забывает.
Garmin действительно не видит то, о чём мы спрашиваем. Связь наших ответов о стрессе, боли и мотивации с готовностью и Body Battery оказалась на уровне случайного шума — на 545–664 днях. Тезис, с которого всё началось, впервые подтвердился числом.
Шкала не ловила стресс. Ответ «сильный стресс» выбирали в 3% дней, в дни тренировок — в 1,6%. Бот, построенный на такой шкале, молчал бы примерно 60 тренировок подряд.
Люди отличаются в этом плане в восемь раз. Средний фон одного пользователя в восемь раз выше, чем у другого. Один общий порог для всех не работает: одному он не сработает никогда, другому — через день.
И ещё одно: люди с болью и стрессом сами выбирают тренировку легче. Средняя тяжесть тренировки — 5,2 из 10 в дни без боли и 3,4 в дни сильного стресса. Значит, ценность бота не в том, чтобы сказать «тебе плохо» — человек это знает. Ценность в точной дозе: насколько именно сбавить сегодня.
Мы выбросили прогноз, индекс MRI, утренний и вечерний опросы. Оставили одну функцию.
Что такое Menteora сейчас
Один замер за 15 секунд перед тренировкой. Не утром по расписанию, а за час до того времени, когда вы обычно бегаете.
Три вопроса по шкале от 1 до 7. Шкала взята из индекса Хупера, которым спортивная наука десятилетиями измеряет готовность в командных видах спорта:
- Мышцы. Насколько они дают о себе знать прямо сейчас.
- Голова. Стресс в моменте.
- Дела. Сколько всего на вас навалилось в эти дни.
Вопрос о сне мы выбросили сознательно: часы знают сон точнее вас. Спрашиваем только то, чего сенсор снять не может.
На выходе — не число, а уровень ограничения от 0 до 5 и что с ним делать:
| Уровень | Что делать с тренировкой |
|---|---|
| 0 · без ограничений | По плану, решают план и часы |
| 1 · под контролем | План целиком, темп по ощущению, не дожимать |
| 2 · лёгкая коррекция | Минус один отрезок, без добавок |
| 3 · урезанное качество | Интенсивная часть на треть короче |
| 4 · только база | Интервалы перенести, лёгкий бег |
| 5 · восстановление | Отдых или прогулка |
Любой ответ от 3 уже ограничивает. Если давят сразу несколько факторов, уровень на ступень строже. Мышцы считаются отдельно: забитые ноги — повод убрать ускорения и спуски, а не всю тренировку.
Первые 10 замеров бот работает по общей шкале и честно пишет об этом. С десятого шкала становится вашей: бот знает, какой фон для вас обычный, и добавляет ступень, если сегодня хуже, чем у вас бывает. Рядом — Body Battery и готовность с часов, каждое число со временем, когда часы его сняли.
Мой день с ответами 4, 4 и 5 раньше получал вердикт «стресс не мешает». Теперь он получает «только база: интервалы перенеси, сегодня лёгкий бег в разговорном темпе». Раньше, чтобы бот сбавил, мне приходилось ему врать.
Чему я научился за семь месяцев
Сложность не равна ценности. Четыре модели выглядели как технологичный продукт. Пользу человеку принёс ответ на один вопрос, который он задаёт себе в кроссовках у двери.
Модели нужна правда, с которой можно сверяться. Если истину нельзя измерить, модель обучится на шуме или выдумает собственную формулу. И это будет выглядеть чертовски умно.
Точность и польза — разные вещи. Бот, который всегда говорит «как обычно», почти всегда прав и почти бесполезен.
Цифра обязана значить одно и то же в марте и в июле. Модели, переобучаясь ночью, меняли линейку. Человек видел, что ему стало хуже, хотя изменился алгоритм, а не его ощущение.
Пользователи говорят правду раньше метрик. О сломанной красной зоне нам сообщали четыре месяца. О том, что бот бесполезен, сказал я сам — как самый внимательный и дисциплинированный юзер собственного продукта.
Я по-прежнему использую языковую модель — она пишет человеческий текст поверх посчитанных чисел. Но ни одно число в Menteora больше не придумывает алгоритм, который нельзя проверить.
Если вы бегаете с Garmin и хотите знать, что сегодня делать с тренировкой с учётом вашего стресса, попробуйте: @menteora_bot.