Реклама
Селектел, перетяжка, 22.06
Селектел, перетяжка, 22.06
Селектел, перетяжка, 22.06

Декомпозиция с AI и без. Едим слона по кускам

Разбираем искусство декомпозиции в Agile: от INVEST до метода WAHZUR. Узнайте, как нарезать фичи на ценные итерации и почему современные AI-инструменты пока не могут полностью заменить командную работу в этом процессе.

Обложка: Декомпозиция с AI и без. Едим слона по кускам

В нашей практике мы часто сталкиваемся с задачами вроде «вывести ещё одну метрику на дашборд». Звучит как что-то простое — но за этой фразой прячется интеграция с новым сервисом, хранение новых данных, автоматические процедуры расчёта, обработка ошибок, вывод на UI, пересчёт при фильтрации и ещё десяток сценариев.

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

Немного про нас, чтобы были понятны примеры, которые я использую. Мы развиваем FinOps продукт Клаудмастер. FinOps — фреймворк, который изначально развивался с целью поставить под контролироль облачные расходы и связать их с бизнес-показателями, такими как юнит-экономика. Сейчас FinOps охватывает в том числе затраты на SaaS, он-прем и AI инструменты. Главное, что мы делаем в нашем продукте — это ищем ресурсы, которые потребляются неоптимально. Сделать это нам помогают метрики мониторинга.

Что такое декомпозиция и зачем она нужна

Декомпозиция — это разбивка большой задачи на маленькие части. Звучит очевидно, но в Agile есть важный нюанс: части должны быть значимы для пользователя, а не только для разработчика.

Это отличает Agile-декомпозицию от обычного технического планирования. Недостаточно разделить задачу на «бэкенд», «фронтенд» и «тесты» — нужно нарезать её так, чтобы каждый кусочек давал реальную ценность и его можно было показать пользователю или стейкхолдеру.

Для этого существует понятие пользовательской истории (User Story) — концепция, которую ввели Кент Бек и Рон Джеффрис в конце 1990-х, чтобы сблизить языки разработчиков и пользователей. Вместо спецификации — обсуждение реальной потребности. Классический шаблон выглядит так:

Я как [роль пользователя], хочу [действие], чтобы [получить результат].

Например: «Я как новый пользователь хочу зарегистрироваться через email, чтобы получить доступ к личному кабинету».

Хорошая пользовательская история соответствует критериям INVEST:

  • Independent — независима от других историй
  • Negotiable — открыта к обсуждению
  • Valuable — несёт ценность пользователю
  • Estimable — её можно оценить
  • Small — небольшая (выполняется за 1–3 дня)
  • Testable — её можно проверить

Почему маленькие задачи лучше больших?

  • Вы быстрее получаете обратную связь от пользователей и можете менять курс
  • Легче отслеживать прогресс — видно, что сделано, а что нет
  • Маленькие задачи реже «зависают» в процессе
  • Проще расставлять приоритеты: что важно прямо сейчас, а что подождёт
  • Бонус для тех, кто работает с ИИ-инструментами: небольшие чётко описанные задачи значительно лучше обрабатываются языковыми моделями

С чего начинается декомпозиция: эпики и истории

Новая функциональность почти всегда приходит в виде эпика — крупной логически завершённой фичи. Например, «Регистрация пользователя» или «Корзина товаров», у нас это обычно рекомендация по оптимизации облачного объекта или ресурса в новом облаке. При этом внешне выглядеть фича может не отличаться от другой на UI, а вот «под капотом» там будет все другое.

Эпик состоит из пользовательских историй, а истории — из технических подзадач (сабтасков). Важно понимать разницу:

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

Паттерны декомпозиции

На мой взгляд, один из самых удобных наборов инструментов для декомпозиции предложил Agile сoach из Канады Вибхор Чандел. Один метод наиболее универсальный — T-сплит. Он работает в двух направлениях: ширина и глубина.

В ширину (горизонталь) — разбивка по вариантам реализации одной функции.

Выписываете все возможные варианты и превращаете каждый в отдельную историю. Например, история «Добавление новой финопс метрики» разбивается по облачным сервисам:

  • Виртуальные машины
  • Диски
  • Облачные хранилища

В глубину (вертикаль) — разбивка по уровню детализации внутри одного варианта.

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

  • История 1: Метрика на базе 95% процентиля за 3 рабочих дня
  • История 2: Метрика за пользовательский период
  • История 3: Метрика на основе выбранной функции агрегации (среднее, максимум, медиана)

T-сплит хорош тем, что работает почти для любой задачи, когда не знаешь, с какого паттерна начать.

Если Т-сплит по какой-то причине не подходит, можно воспользоваться одним из шести базовых паттернов, большинство других методов представляют собой вариации этих шести. У набора есть аббревиатура, но, честно говоря, она не очень помогает запоминанию: WAHZUR.

<b>WAHZUR с примерами</b>

W — Workflow steps (Шаги процесса)

Применяется, когда история описывает последовательность действий.

Каждый шаг процесса становится отдельной историей.

Пример. История «Оплата товаров в корзине» разбивается на:

- Просмотр итоговой суммы и состава заказа

- Выбор способа доставки

- Ввод платёжных данных

- Подтверждение и получение email-уведомления

Совет. Начните с самого простого сквозного пути — от первого шага до последнего, пусть и в минимальном виде. Промежуточные детали добавите потом.

A — Acceptance criteria (Критерии приёмки)

Применяется, когда у одной истории много условий приемки.

Каждый критерий приёмки потенциально можно превратить в отдельную историю.

Пример. История «Использование бонусных баллов» делится на:

- Просмотр текущего баланса баллов

- Выбор количества баллов для списания при оплате

- Проверка остатка баллов после покупки

H — Happy / Unhappy path (Счастливый и несчастливые пути)

Применяется для разделения основного сценария и обработки ошибок.

Сначала реализуется «счастливый путь»: то, что происходит когда всё идёт по плану. Потом отдельными историями: исключения и ошибки.

Пример. Вход в систему: 

Happy path: успешная авторизация по логину и паролю

- Unhappy paths: сброс забытого пароля, блокировка после трёх неудачных попыток

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

Z — Zero / One / Many (Ноль / Один / Много)

Применяется для функций, работающих с наборами данных.

История делится на три части: пустой набор (0), один элемент (1), много элементов (много).

Пример. Просмотр корзины: 

- Пустая корзина с призывом добавить товары (0)

- Корзина с одним товаром (1)

- Корзина с множеством позиций, постраничная навигация (много)

U — User roles / Personas (Роли пользователей)

Применяется, когда функциональность отличается в зависимости от типа пользователя.

История разбивается на части — по одной для каждой роли.

Пример. Бронирование столика в ресторане: 

- Для обычного гостя: выбор даты, времени, количества мест

- Для постоянного члена клуба: те же шаги плюс доступ к приоритетным столикам и возможность бронировать в кредит

R — Rules (Бизнес-правила)

Применяется, когда история содержит сложную бизнес-логику или ограничения.

Каждое явное или неявное бизнес-правило выделяется в отдельную историю.

Пример. Обработка заказов: 

- Отклонение заказов на сумму меньше 1 000 рублей

- Отказ в доставке за пределы города

- Автоматическая отмена неоплаченного заказа через 48 часов

Как выбрать нужный паттерн

Задайте себе один вопрос: в чём основная сложность этой задачи?

  • Много шагов → W (Workflow)
  • Много условий проверки → A (Acceptance criteria)
  • Основной сценарий и куча исключений → H (Happy/Unhappy)
  • Работа с наборами данных → Z (Zero/One/Many)
  • Разные роли с разным поведением → U (User roles)
  • Запутанная бизнес-логика → R (Rules)

На практике одну историю можно декомпозировать сразу несколькими паттернами. Например, взять шаги процесса (W), а внутри одного шага отделить счастливый путь от несчастливого (H).

Два вопроса, которые решают всё

После того как вы применили паттерны, остаётся отобрать то, что пойдёт в спринт, а что — в «отвал» или в следующие итерации.

Стив Адольф, Шейн Хасти и Райлан Лейтон из IIBA описывают процесс работы с бэклогом через метафору камнедробилки: всё, что вошло в систему, должно из неё выйти — либо в виде ценности для пользователя, либо в «отвал». Хороший признак качественной декомпозиции — часть историй осознанно уходит в «отложенные», потому что команда решила: это не критично для ближайшего релиза.

Источник: The Rock Crusher https://therockcrusher.org

Найти, что можно «отложить» помогают два вопроса:

1. В чём основная сложность этой задачи? Ответ покажет, что нужно реализовать в первую очередь, а что является украшением.

2. Все ли условия задачи необходимы прямо сейчас? Большинство историй содержат требования, которые кажутся обязательными, но на деле могут подождать.

Что делать, если задача совсем непонятна

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

В Agile для таких случаев существует спайк (spike), короткий период на эксперименты и исследования. Стандартная схема:

  1. Выделяете 2–3 дня на исследование
  2. Формулируете 3 конкретных вопроса, на которые хотите ответить
  3. Результат фиксируете в виде прототипа, схемы или короткого документа
  4. После спайка возвращаетесь к декомпозиции — теперь с пониманием

Спайк — это не провал планирования или не неподготовленность. Это признание, что некоторые вещи нельзя оценить, не изучив их.


«Карпаччо из слона»: упражнение для команды

Если команда привыкла работать с большими задачами и воспринимает декомпозицию как лишнюю бюрократию, попробуйте упражнение Алистера Кокберна — «Карпаччо из слона».

Идея: научить команду нарезать задачу на тончайшие, но полностью рабочие «ломтики». Каждый ломтик должен проходить через все слои системы: от UI до базы данных, и давать в результате что-то работающее.

Признаки хорошего «ломтика»:

  • Затрагивает все слои системы
  • Достаточно мал, чтобы быстро закончить
  • Достаточно работоспособен, чтобы его можно было проверить
  • Его можно оценить и улучшить

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

Кокберн подчёркивает: тонкая нарезка на истории — это не хитрость планирования. Это работа с собственным «эго». Она требует принять временную неэлегантность решения и отказаться от желания сразу сделать всё по-взрослому, по всем архитектурным канонам. Гораздо проще улучшить работающий код, чем предугадать идеальную архитектуру для системы, которой ещё не существует.

Декомпозиция: время и место

В Scrum декомпозиция происходит в рамках PBR (Product Backlog Refinement), регулярных встреч команды для проработки задач.

Джефф Паттон, автор метода User Story Mapping, советует несколько простых вещей, чтобы сделать процесс более эффективным и комфортным:

Встречайтесь чаще, но короче. Один большой рефайнмент раз в две недели работает хуже, чем две короткие встречи в неделю по 30-45 минут.

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

Минимум три роли в комнате: понимающий предметную область, разработчик, тестировщик. Без любого из них обсуждение будет неполным.

Декомпозиция и ИИ

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

Гойко Аджич, автор методики Impact Mapping и концепции Specification by Example, заметная фигура в мире BDD и TDD, со своей командой протестировал spec-kit — инструмент для спецификации на основе ИИ. Вывод такой: очень интересно, но пока не очень полезно. ИИ неплохо справляется на высоком уровне абстракции, но сразу начинает писать много документов (в основном для самого себя) и кучу кода. Контролировать и проверять это человеческими силами не представляется возможным. Подробнее в его статье Spec Driven разработка: месть вотерфола или новый уровень BDD?

Я также познакомилась с несколькими ИИ-агентами, которых предлагают использовать в роли бизнес-аналитика, системного аналитика, архитектора. Их код и промпты лежат в открытом доступе на GitHub, можно посмотреть, как они устроены и какие вводные промпты получают.

Чтобы вы могли быстро составить представление, процитирую инструкцию агенту из GSD (Get Shit Done 😊 ) промпт-фреймворка:

			Для этапа планирования (roadmap):
Изучи контекст: прочитай файлы context.md, research.md и .gsd/decisions.md, если они существуют.
Декомпозиция: разбей общее видение проекта на 4–10 вертикальных срезов (vertical slices), каждый из которых можно продемонстрировать как рабочую функцию.
Приоритезация по рискам: расставь задачи в порядке убывания риска (сначала самые сложные и неопределенные, чтобы как можно раньше подтвердить техническую возможность реализации).
Создание плана: напиши файл roadmap.md с чек-листами, уровнями риска, зависимостями и описанием того, что именно будет показано на демо.
Карта границ (Boundary Map): для каждого «среза» четко определи границы — что он производит (функции, типы, интерфейсы, эндпоинты) и что он потребляет из предыдущих этапов. Это заставляет продумать архитектуру интерфейсов еще до начала написания кода и позволяет гарантированно проверить, что все части системы стыкуются друг с другом.

		

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

Вместо заключения

Шпаргалка для быстрого старта:

  1. Получили эпик → спросите: «В чём основная сложность?»
  2. Непонятно, что внутри → запустите спайк на 2-3 дня
  3. Понятно, что внутри → примените T-сплит или WAHZUR
  4. Получился список историй → спросите: «Всё ли нужно прямо сейчас?»
  5. Осталось только необходимое → берёте в спринт

И ещё один аргумент в пользу декомпозиции, который становится всё актуальнее. ИИ-инструменты берут на себя всё больше рутинной разработки — но роль пользователя пока остаётся за человеком. Декомпозиция по пользовательским функциям — это и есть тот инструмент, который помогает удерживать этот фокус: не «что мы можем реализовать», а «что действительно нужно пользователю прямо сейчас».

Полезные ссылки

Рекомендуем