Эксперименты. Или как понять, удачная ли была фича?

Kate

Administrator
Команда форума

А в чем, собственно проблема?​

За время работы с программными продуктами в различных сферах бизнеса мне не раз приходилось участвовать в принятии решений о том, какой функционал нужно выпустить в первую очередь и как он должен выглядеть. Мы использовали совершенно разные подходы для решения такой задачи, начиная с мнения разработчиков и заканчивая анализом поведения пользователей и его влияния на прибыль компании. В этой статье я хотел бы поделиться своим опытом в этой сфере и, возможно, помочь вам избежать ошибок.

Как делать не надо​

Мой самый негативный опыт принятия решений был в стартапе по аналитике цен на недвижимость, направленный на помощь в оценке помещений. Тогда мы не собирали никаких данных о поведении пользователей, а все наше логирование сводилось к исключительно техническим аспектам работы системы. Сперва мы пытались узнать(или скорее выпытать) у наших клиентов, какие функции они хотели бы видеть и за что готовы платить. Но практически никто не мог дать нам даже намек на то, в какую сторону смотреть, казалось бы, всех полностью устраивал наш продукт, однако количество клиентов не росло. Мы изучали бизнес настолько тщательно, насколько могли себе позволить, чтобы поставить самих себя на место клиентов. Это позволило нам придумывать и внедрять новый функционал. Иногда динамика роста клиентов менялась в лучшую сторону, а иногда клиенты начинали уходить. Но мы никак не могли наверняка сказать, какое именно изменения повлияло на это. Это выглядело и ощущалось как работа с черным ящиком. Работа в этом проекте научила меня, что ни пользователи, ни разработчики никогда не знают что нужно делать дальше, и успешному продукту обязательно требуется что-то еще.

Уже лучше​

Когда я начал работу в следующем проекте, там уже была практика отслеживания действий пользователей, хотя и на базовом уровне. Это был продукт в e-commerce сфере, и у нас было достаточно данных, чтобы определить среднее количество покупок в день и среднюю сумму чеку. Это уже лучше, чем просто количество клиентов, как в предыдущем проекте. Помимо базовых продуктовых метрик, в этом случае так же было внедрено множество практик непрямых опросов клиентов, то есть вместо того, чтобы спрашивать, чего нехватает, мы просили ответить клиентов на вопросы о существующем функционале. Это позволяло нам понимать слабые места и недовольства клиентов и концентрироваться на них. Мы так же имели отдельный источник задач в виде владельцев продукта, которые очень тесно работали с финансовым отделом. Со временем мы повышали все важные метрики внедряя различные фичи, но мы так и не могли сказать, какое конкретно изменение повлияло на метрики максимально эффективным образом.

Чтобы решить эту проблему, мы решили начать с изменения процесса: а именно релизиться чаще, но только с одним изменением. Таким образом мы смогли избавиться от конкуренции за метрики между разными улучшениями. Это позволило нам измерять влияние каждой конкретной идеи на пользователей и принимать решения о том, стоит ли продолжать двигаться в данном направлении, или лучше сменить вектор. Однако такой подход принес другие проблемы: скорость разработки значительно снизилось, новый код начал копиться в репозиториях, разработчики жаловаться на возросшее количество багов. Их к тому же стало сложнее исправлять, ведь пока проблема дойдет до продуктивной среды, ее авторы уже забывают контекст.

Правильный подход​

Долго это продолжаться не могло, и мы начали думать о том, как же исправить ситуацию и иметь возможность выпускать сразу несколько доработок, но при этом иметь возможность анализировать их по отдельности. В качестве решения было принято разработать отдельную библиотеку, позволяющую делить наших пользователей на отдельные группы, а затем включать разным группам разные фичи. При сборе аналитических метрик, мы бы знали, к какой группе относится каждое событие и имели бы возможность сравнивать их.

Это на первый взгляд простое изменение оказалось комплексным проектом, занявшим почти 3 месяца дизайна, разработки, тестирования и, конечно же, переделывания. Но даже после этого мы так и не успели сделать административную страницу, для конфигурирования экспериментов, поэтому любое изменение размера или принадлежности групп требовало помощи разработчика, который составит правильный SQL update.

Технические подробности​

Первая часть — распределение клиентов по группам. Основная идея очень простая: при запуске приложения отправляется запрос на сервер для получения списка всех активных экспериментов. Затем каждый раз при авторизации нового пользователя клиент отправляет запрос с идентификатором этого пользователя, а в ответ получает идентификатор группы, в которой этот пользователь находится для каждого эксперимента. Чтобы определить группу, сервер сначала делает запрос в базу данных, чтобы проверить, был ли данный клиент уже распределен для данного эксперимента, если нет, происходит распределение. Выглядит это следующим образом:

a1bf9f572cad03a46cc3cb5b2c136a78.png

На рисунке так же можно заметить кеш, в этом случае ничего интересного, он используется для оптимизации запросов к БД.

Вторая часть - возможность включения и отключения функционала основываясь на группе пользователя. Теперь обязательной частью любого нового функционала стал фича-флаг. В общем говоря - это условие, при котором функционал включается или выключается.

if (FeatureToggle.isEnabled(clientId, experimentId)) {
button.setColor(newColor);
}
В данном случае также можно добавить кеш, но небольшой, так как переключать эксперименты хочется побыстрее.

Теперь мы могли выпускать все по мере готовности и не бояться, что аналитические данные будут перемешаны и у нас не получится измерить полезность изменения.

Недостатки​

Однако как и любое решение, это не обошлось без крупных проблем, я бы сказал их оказалось две:

  1. Сложность реализации изменений увеличилась. Ведь это только в теоретическом примере разработчики перекрашивают кнопки и одного условия достаточно. На деле крупные проекты состоят из десятков, если не сотен классов, и реализуются на нескольких платформах одновременно, поэтому одним условием обойтись не получается. Множество условий в коде так же приводит к сложно анализируемым багам, затрагивающим интеграцию разных платформ.
  2. Мусор после экспериментов. После того как эксперимент закончился в большинстве случаев условие из кода никуда не девается, просто эксперимент конфигурируют таким образом, что 100%пользователей попадают в группу “включено”. Из-за этого сложность кода сильно растет со временем и приходится выделять отдельные спринты или релизы на вычистку старых, неиспользуемых условий.

Как жить дальше?​

Несмотря на эти проблемы, введение экспериментов позволило нам более осмысленно вводить новый функционал и оценивать его пользу. В планах сейчас остается создание отдельной административной панели для управления экспериментами, чтобы команды, ответственные за них могли без чьей либо помощи изменять вовлеченность пользователей простым кликом на сайте, но это уже совсем другая история.

 
Сверху