Skip to content

Runtime Decide

Decision API — это тот самый момент, когда продукт спрашивает: “какой вариант показать этому пользователю прямо сейчас?”. Платформа должна предоставлять продукту механизм получения актуальных значений флагов для конкретного пользователя/устройства в момент показа UI.

Смысл запроса со стороны продукта:

“Вот субъект (пользователь или устройство) и его атрибуты.
Дай значения для этих флагов так, как будто мы показываем интерфейс прямо сейчас”.

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

  • идентификатор субъекта — стабильный идентификатор субъекта (например, идентификатор пользователя или устройства), по которому обеспечиваются:
    • предсказуемая раздача трафика,
    • «липкость» к варианту (stickiness) в рамках эксперимента.
  • атрибуты субъекта — набор атрибутов (страна, версия приложения и т.п.), которые используются для таргетинга («правило участия»).
  • список запрошенных флагов — список ключей флагов, значения которых нужны продукту для рендера.

В истории: в ответ продукт получает «вот твой вариант + служебный «идентификатор решения»». Этот «идентификатор решения» потом связывает показ и события (клики/покупки) в одну цепочку. Для каждого запрошенного флага возвращается решение «что применить»:

  • итоговое значение, которое продукт должен использовать;
  • служебный идентификатор решения, чтобы связать показ и последующие события;
  • если значение выдано экспериментом: идентификатор эксперимента и выбранный вариант.

3.4 Правила принятия решения

Section titled “3.4 Правила принятия решения”

Здесь важно, чтобы правила были простыми и прозрачными: продакт должен понимать, почему пользователь попал в вариант B, а не в A. Для каждого «ключ флага» платформа должна определить итоговое значение так:

  1. Если нет применимого активного эксперимента (эксперимент не запущен/на паузе или не применился) — вернуть значение по умолчанию флага.

  2. Если есть активный эксперимент на этом флаге и он применим к субъекту:

  • применить таргетинг
  • выбрать вариант согласно весам вариантов
  • вернуть значение выбранного варианта и метаданные эксперимента.

3.5 Требуемые свойства качества

Section titled “3.5 Требуемые свойства качества”

В истории: это тот самый “не прыгать между вариантами”. Если пользователь вчера видел B, а сегодня внезапно увидел A — эксперимент превращается в шум.

Одинаковый запрос при неизменной конфигурации (флаги/эксперименты/статусы/правила) должен возвращать одинаковый результат.

Цель: предсказуемость UI, корректная аналитика и воспроизводимость.

Один и тот же «идентификатор субъекта» не должен “прыгать” между вариантами в рамках одного эксперимента, пока конфигурация эксперимента не меняется.

Цель: честное сравнение, пользовательский опыт без дерганий, чистая статистика.

Сеть — штука капризная: запросы и события могут теряться или дублироваться. Поэтому идемпотентность и дедупликация — обязательны.

3.6 Защита пользователя от постоянного участия в экспериментах

Section titled “3.6 Защита пользователя от постоянного участия в экспериментах”

В истории: пользователь не должен быть «вечным подопытным кроликом», который постоянно живёт в тестовых вариантах.

Платформа должна поддерживать политику участия пользователя в экспериментах:

  • ограничение интенсивности участия (сколько активных экспериментов одновременно может влиять на одного субъекта);
  • периоды «отдыха» (cooldown), когда после серии экспериментов пользователь чаще видит базовое поведение;
  • прозрачные правила приоритезации, если на пользователя претендуют несколько экспериментов.

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

3.7 Технические проверки живости и готовности

Section titled “3.7 Технические проверки живости и готовности”

Проблема, которую закрывает этот раздел: без разделения живости и готовности невозможно понять, сервис уже обслуживает запросы или только запущен как процесс.

  • /health отвечает 200, когда процесс приложения жив и может обрабатывать базовые служебные проверки.
  • /ready отвечает 200, когда приложение готово принимать запросы.
  • Пока критичные зависимости не готовы, /ready должен отвечать не-200.
  • После старта системы /ready должен перейти в 200 не позднее чем за 180 секунд; если этого не произошло, жюри вправе запускать проверки в текущем состоянии системы.
  • Поведение health/readiness должно быть отражено в инструкции запуска и в сценарии демонстрации.