Story points и почему не часы
Разбираемся, почему команды перестали оценивать задачи в часах и перешли к безразмерным «попугаям».
Story point (стори-поинт) — безразмерная единица оценки, которая показывает сложность задачи относительно других задач той же команды, а не время на её выполнение.
Первая реакция человека, который слышит про story points, обычно одинаковая: «Зачем эта эзотерика? Скажите просто — сколько часов». Реакция честная. Но за ней стоит допущение, которое разваливается на первой же неделе работы: что человек умеет предсказывать, сколько времени займёт то, чего он ещё не делал.
Почему часы врут
Разработчик говорит: «Три дня». Проходит неделя, задача не готова. Он не врал и не ленился. Просто он оценивал ту версию задачи, которую держал в голове — идеальную, без сюрпризов. А в реальной вылезло: библиотека не поддерживает нужный формат, тесты падают на CI по другой причине, дизайнер отдал макет только на второй день, а на код-ревью попросили переписать половину.
У оценки в часах есть три встроенные ловушки.
- Мы оцениваем счастливый путь. Голова считает время на работу, а не на препятствия. Психологи называют это ошибкой планирования: люди устойчиво недооценивают срок, даже когда прекрасно помнят, что в прошлый раз ошиблись.
- Часы у всех разные. Одну и ту же форму сеньор сделает за 4 часа, джуниор — за 12. Значит, оценка перестаёт быть свойством задачи и становится свойством исполнителя. Задача переехала к другому — оценка недействительна.
- Часы читаются как обещание. «6 часов» в глазах менеджера превращается в «к обеду завтра». Оценка мгновенно становится дедлайном, а промах — поводом для разговора. После пары таких разговоров команда начинает закладывать втрое, и оценки перестают значить хоть что-то.
Story points ломают все три ловушки: они не про время, они не привязаны к конкретному человеку, и их невозможно поставить в календарь напрямую.
Что вообще значит «сложность»
Story point — это не «сколько работы». Это смесь трёх вещей:
| Составляющая | Вопрос, на который она отвечает |
| Объём | Сколько всего нужно сделать? Один экран или двенадцать? |
| Неопределённость | Мы вообще понимаем, как это делать? Делали похожее? |
| Риск | Что может пойти не так? Внешний API, легаси-модуль, миграция данных? |
Отсюда неочевидное следствие: маленькая по объёму задача может стоить дорого. «Поменять сортировку в отчёте» звучит на полчаса — но если отчёт собирается в древнем хранимом SQL-процедурном коде, который никто не трогал три года, это честная восьмёрка. И наоборот: сверстать двадцать однотипных карточек — много рутины, ноль неизвестности, поэтому недорого, хотя и долго.
Относительная оценка: сравнивать, а не измерять
Люди чудовищно плохо оценивают абсолютные величины и на удивление хорошо — относительные. Спросите, сколько метров до соседнего дома, — ошибётесь вдвое. Спросите, до какого дома дальше, до соседнего или до того, что через дорогу, — ответите мгновенно и правильно.
Story points эксплуатируют именно это. Команда не измеряет задачу — она сравнивает её с эталоном.
Эталонная задача (reference story) — маленькая, всем понятная, уже сделанная история, которой команда договорилась присвоить, скажем, 2 поинта. Дальше всё меряется от неё: «эта примерно как эталон — 2», «эта явно вдвое муторнее — 5», «а тут мы вообще не знаем, что внутри — 13».
Так выглядит живая шкала одной команды. Её обычно записывают и вешают на видное место:
Шкала команды «Платёжки» (эталон = 2)
1 — поправить текст ошибки, добавить поле в существующую форму
2 — ЭТАЛОН: новый эндпоинт CRUD по готовой модели + тесты
3 — экран из готовых компонентов, данные уже есть в API
5 — новая сущность: модель + миграция + API + экран
8 — интеграция с внешним сервисом, который мы уже подключали
13 — интеграция с сервисом, документацию которого мы ещё не читали
20 — «переехать на новый платёжный шлюз» → это не история, это эпик, дробить
Обратите внимание на последнюю строку. Шкала работает ещё и как детектор: если задача не влезает, значит, она сформулирована слишком крупно.
Почему Фибоначчи, а не 1, 2, 3, 4, 5
В покере используют ряд с растущими промежутками — 1, 2, 3, 5, 8, 13, 20, 40, 100. Причина простая и очень человеческая: чем больше задача, тем грубее мы её различаем.
Разницу между 1 и 2 команда чувствует: вдвое. Разницу между 2 и 3 — ещё различает. А теперь попробуйте всерьёз поспорить, задача на 21 или на 22. Спор будет ровно ни о чём: точности такой оценки просто не существует, погрешность там плюс-минус десятка.
Растущие промежутки честно признают этот факт. Они запрещают ложную точность. Либо задача 13, либо 20 — промежуточных вариантов нет, и не надо. А заодно ряд подталкивает дробить: как только оценка улетает в 20 и выше, разрыв до следующего значения становится таким огромным, что команда сама говорит «давайте это разобьём».
Как это работает на практике
Команда берёт спринтовый бэклог и проходит по историям. Оценивают только те, кто будет делать работу: разработчики, тестировщики, дизайнер. Product Owner объясняет смысл истории и отвечает на вопросы, но карту не показывает — иначе он невольно навязывает свою цифру.
Выглядит результат примерно так:
Спринт 14 — оценённый бэклог
[3] Фильтр по статусу в списке заказов
[5] Экспорт заказов в CSV
[2] Починить пагинацию на последней странице
[8] Отправка чека на email после оплаты
[13] Возвраты через платёжный шлюз ← дробим на 3 истории
[1] Заменить иконку в шапке
Итого без «возвратов»: 19 поинтов
Ни в одной строке нет часов. И это не мешает планировать: команда знает, что за прошлые спринты она вывозила 20–25 поинтов, значит, такой набор реалистичен, а «возвраты» в текущий спринт брать нельзя, пока их не разобрали на части.
Частые ошибки
- Тайный курс обмена. Команда решает: «1 поинт = 1 день». Поздравляю, вы изобрели часы с лишним шагом. Все ловушки времени вернулись, только теперь их прикрывает модное слово.
- Оценивает не тот, кто делает. Тимлид или менеджер расставляет поинты «за команду». Оценка тут же перестаёт быть оценкой и становится нормативом, который спускают сверху.
- Поинты как обязательство. «Вы сказали 5, а сделали за 13, будем разбираться». После первого такого разговора команда начинает ставить 13 везде. Оценка — прогноз, а не подпись под договором.
- Сравнение с другой командой. Восьмёрка команды А и восьмёрка команды Б — разные величины, как рубль и юань. Шкала имеет смысл только внутри одной команды.
- Оценивают всё подряд, включая эпики. Ставить оценку задаче «сделать личный кабинет» бессмысленно. Сначала дробим до размера истории, потом оцениваем.
- Пересчёт оценок задним числом. Задача оказалась вдвое тяжелее — и команда «исправляет» оценку с 5 на 13. Не надо: тогда velocity перестанет отражать реальность, а история промахов исчезнет вместе с возможностью учиться на ней.
Итоги
- Story point — безразмерная единица сложности: объём плюс неопределённость плюс риск.
- Часы врут: мы оцениваем счастливый путь, часы зависят от исполнителя, а руководство читает их как дедлайн.
- Оценка относительная: задачу сравнивают с эталонной историей, а не измеряют в вакууме.
- Ряд с растущими промежутками (1, 2, 3, 5, 8, 13, 20) запрещает ложную точность и подталкивает дробить крупное.
- Оценивают только исполнители. Поинты одной команды несопоставимы с поинтами другой.
- Оценка — прогноз, а не обещание. Как только за неё начинают наказывать, она умирает.