Кросс-функцио­нальные команды в Еде

  • Александр Швец
    Александр Швец

    Александр Швец

    Руководитель разработки ритейла Яндекс Еды

Всем привет! Меня зовут Саша Швец, я CTO Вертикалей Яндекс Еды, отвечаю за основные вертикали — Ритейл, Ресторанный продукт, Рекламу. В статье расскажу историю о том, как я переводил разработку из функциональной структуры в кросс-функциональную и зачем я это делал. Статья будет полезна CTO и другим руководителям, которые столкнулись с проблемами взаимодействия и роста внутри своей технической команды.

Интро

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

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

Это теория. Перейдем к нашей истории.

Проблемы функциональной команды

На старте всё было плохо…

В Яндекс я пришел в 2019 году в Суперчек — был в Яндекс Маркете такой проект про каталоги крупнейших ритейлеров. До близкого знакомства с компанией я пребывал в иллюзии, что в Яндексе всегда всё суперпередовое, и уж там-то точно сделаны кросс-команды…

Но в Суперчеке Android-разработка жила отдельно от iOS, бэкенд жил в стороне от них обоих, и все они почти не общались. Со временем людей приходило всё больше — боль становилась совсем невыносимой. Мне же как СТО эту боль приходилось гасить.

В Маркете, где я работал после Суперчека, было получше: использовалось деление на стримы и v-teams. В 2022 году я перешел из Маркета в Еду и, по ощущениям, вернулся в Суперчек, но в гораздо более запущенном виде.

Летом 2022 года устройство Еды выглядело как на картинке. Во главе стоял СТО, отвечавший за всю Еду, и уже прорастали зачатки вертикалей: отдельно рестораны, отдельно ритейл, отдельно логистика. Я пришел как CTO Ритейла (колонка слева) и управлял двумя командами бэкенда. Виртуально у меня были еще команды веб-, iOS- и Android-разработчиков (справа). Из схемы понятно, что они не подчинялись мне напрямую, а велись своими функциональными лидами.

Основные проблемы организации, которые стали видны почти сразу:

  • Распределение ресурсов на проекты шло в формате еженедельного рубилова. Основные заказчики — продакты — еженедельно ссыпали всю разработку в общий котел, а потом забирали оттуда людей на конкретные проекты. Преимуществом для продактов было хорошее горло: чем громче кричишь про важность своего проекта — тем больше шансов заполучить разработчиков. Хаотичное перекидывание людей шло непрерывно, и это негативно влияло на атмосферу в командах.
  • Команды не всегда понимали, кто их руководитель. Во время моих визитов разработчики смотрели на меня как на левого персонажа, который вылез непонятно откуда и чего-то от них добивается. Это была лично моя боль.
  • Под каждый новый проект формировалась новая команда, и каждый раз требовалась своя система процессов: дейлики, чатики, синки — а это накладные расходы.
  • Мало кто понимал, что происходило в команде глобально. Продакты были заняты выбиванием ресурсов, а разработчики наоборот — вообще не были вовлечены в эти процессы и из-за еженедельных изменений перемещались с одного проекта на другой.

…а потом стало хуже

В Еду я пришел летом 2022-го, а уже осенью Яндекс совершил сделку с VK: от нас ушли Новости и Дзен, а к нам перешел Деливери. Я зову этот период «Черная осень двадцать второго», потому что весь Деливери надо было переварить, объединить с Едой и перевести всю пользовательскую базу на технологии Яндекса.

Сложность заключалась в том, что под капотом у нас были совершенно разные стеки. В нативной разработке всё было еще достаточно понятно: iOS есть iOS, а Android есть Android, даже в ЮАР. Но на бэкенде в Еде всё сделано на C++, а в Деливери — на Go (что забавно, и там, и там был монолитик на PHP). Веб же в Еде был написан на React, а в Деливери — на Vue, причем был заметно слабее развит.

И вот — два огромных бизнеса с разными стеками. Now kiss!

Рассказ об объединении достоин отдельной статьи. В контексте этого материала важно то, что приход Деливери усугубил все проблемы: число людей удвоилось, и появился отдельный сектор разработчиков Go, как будто до этого разобщенности было мало. Единственное светлое пятно — и нативные команды, и веб-команда полностью перешли под меня.

Нулевое улучшение: «Планнер»

На старте мы попробовали упорядочить хаос, внедрив инструмент под названием «Планнер», который я принес из Маркета. «Планнер» родился из подручных инструментов: поначалу я размечал, кто чем занимается, в эксельках, а потом мы сделали веб-интерфейс.

Выглядит «Планнер» как диаграмма Ганта, но строчки здесь — не проекты, а люди. Из диаграммы видно и то, каким проектом занят каждый конкретный разработчик, и общая картина занятости. Когда нужно быстро перебросить человека с одного проекта на другой — можно сразу прогнозировать, что из-за этого поедет.

Но «Планнер» это подорожник: добавляет прозрачности, а остальных проблем не решает.

Первое улучшение: кросс-функциональность

Поэтому мы затеяли глобальную реформу и придумали новую структуру с опорой на продуктовые предпосылки.

Во-первых, весь Ритейл разбили на два домена: работу с покупателями (витрину, слева) и работу с магазинами-партнерами (справа).

Во-вторых, в каждом из этих доменов выделили свои стримы. Например, в домене покупателей это:

  • OX — Order Experience, опыт заказа;
  • CX — Customer Experience, опыт покупки;
  • Growth — стрим роста;
  • Search — стрим поиска, всё, что касается поисковой выдачи.

При этом в каждом стриме есть полный набор специализаций разработки. В партнерском домене похожее деление.

Если раньше все общались как попало — были отдельные синки бэкенда, отдельные команды iOS, то теперь получились сплоченные команды, которые не нужно менять каждую неделю, они работают постоянно в одном направлении.

В чём мы выиграли

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

В чём проиграли

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

Второе улучшение: гильдии

Мы решили эти проблемы матричной структурой, а именно — вводом гильдий. На схеме видно, что продуктовые команды лежат по горизонтали, а вертикально их прошивают гильдии специальностей. У каждой гильдии в этой системе свои лиды: лид гильдии C++, лид гильдии Android и так далее.

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

  • Онбординг новичков. Если, например, бэкенд-специалист пришел в команду мобильного тимлида, то за его бэкенд-скилы отвечает гильдия. Гильдия может назначить ментора — мы прописали инструкции, как правильно принимать человека на борт.
  • Развитие старичков. Лиды гильдий знают, как тянуть вообще всех, независимо от стажа: делятся опытом, подсказывают на код-ревью. Вместе с лидом гильдии в этом процессе участвует и непосредственный руководитель продуктовой команды.
  • Общие процессы типа релиза нативного приложения. Понятно, что продуктовый стрим не решает, как залить конкретное приложение в конкретный стор, это определяет гильдия.
  • Архитектура и техдолг. Гильдия отвечает за общее качество кода и следит, что мы не копим технический долг, а только уменьшаем его. Наша условная техноквота — 20%, за ее распределением следит гильдия.
  • Обмен знаниями. Банальная, но важная штука.

Третье улучшение: платформа и вечность

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

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

Платформа — уже не кросс-функциональная команда, в ней выделены бэкенд, веб и QA. Но, как вы видите на схеме, мобильной платформы отдельно в Ритейле не появилось, мы используем общую мобильную платформу Еды.

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

Что произошло по мере роста у нас:

  • от Customer Experience отделилось направление Distribution, и они оба вместе теперь называются Monetization;
  • Growth вырос в Strategic Growth, и внутри возникли свои два направления;
  • Order Experience с Search объединились в единый сектор ответственности Core.

Структура супермасштабируема: можно идти глубже, почковаться внутри секторов и внутри команд. Растите бизнес, растите продукт, набирайте людей — система умеет работать с этим гладко.

Итоги

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

Иногда кросс-функциональность действительно не нужна — например, если ваша команда занимается отдельной платформой. У нас есть команда интеграций, упрощенно она пишет на Python или Go адаптеры, которые просто заняты трансформингом данных. У таких команд кросс-функциональность только с менеджерами и QA, это нормально.

Для продуктовой же разработки кросс-функциональность — мастхэв. Такая система всегда более слаженна, эффективна и прозрачна, чем функциональная.

Напомню три хинта, которые вам пригодятся, если вы возьметесь за кросс-функциональность:

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

Другие публикации