В каждом развертывании Asana есть консоль администратора. Именно здесь ИТ-администраторы настраивают параметры использования Asana в своей компании, например требования к паролям, роли и разрешения, возможность прикрепления файлов из Dropbox, а также то, кто по умолчанию может видеть новый проект.
По мере развития Asana в консоли администратора накапливались многолетние пользовательские логические схемы и разовые решения, что делало создание и поддержку элементов управления всё более дорогостоящими. Возьмём, к примеру, одну из настроек администрирования — конфиденциальность по умолчанию для новых проектов. Администратор выбирает, будет ли новый проект изначально доступен всей организации, своей команде или только приглашённым участникам. Описать это просто, но за этим скрывается множество сложностей:
Входит ли эта функция в тарифный план клиента?
Платил ли клиент за неё раньше, перестал платить и застрял на настройке, которую больше не может изменить?
Является ли клиент организацией, подпадающей под действие HIPAA или FedRAMP, где только пользователи с повышенными полномочиями могут вносить изменения?
Становится ли один из вариантов недоступным из-за какого-либо другого параметра?
Следует ли показывать информационный баннер с описанием нынешних ограничений?
Любая команда, желающая добавить настройку администратора, должна была учесть все эти моменты. Большинство решало, что игра не стоит свеч, и со временем разрыв между тем, что могла делать Asana, и тем, что мог контролировать администратор, увеличивался. Это проявляется в том, что некоторые элементы управления можно настроить только на уровне всей компании, что затрудняет для ИТ-администраторов применение элемента управления только к определённой группе пользователей.
Вот фрагмент диалогового окна настройки конфиденциальности проекта, используемый для определения того, следует ли её отключать и следует ли отображать баннер:
Здесь нужно проанализировать множество логических аспектов: лицензирование функций, управление, переопределение настроек в связи со структурой развертывания и роли пользователей, особенно аналитиков. Чтобы всё сделать правильно, вам пришлось бы мысленно перестроить матрицу тестов, чтобы определить, верна ли она.
И это только диалоговое окно. Вопрос о том, будет ли строка вообще отображаться на странице настроек, решался в другом месте, причём непоследовательно:
Три строки, три механизма, и условия не всегда находятся в одном и том же файле. Итак, чтобы ответить на вопрос «Какие настройки на самом деле видит этот клиент?», вам нужно было не только прочитать каждую строку, но и просмотреть каждый компонент. Этот вопрос возникает довольно часто: служба поддержки пытается объяснить, почему у клиента исчезла настройка, менеджер проекта хочет получить четкий ответ на вопрос, можно ли внести изменение в новый элемент управления быстро или на это уйдет две недели, а новый сотрудник пытается найти то единственное место, где решается, что может видеть конкретный пользователь.
Если говорить в целом, то работа в консоли администратора была трудоёмкой по четырём причинам:
Дорогостоящая проверка. Логика находилась там, куда её помещал автор, поэтому запрос на внесение изменений мог привести к появлению особого поведения, которое не было бы очевидным для проверяющего, а правильность нельзя было легко проверить простым прочтением.
Отсутствие стандартизации скрывало ошибки. У нас были давние ошибки, которые было сложно обнаружить. Многие из них были связаны с расхождениями между спецификацией продукта и его реализацией, вызванными обилием индивидуальных решений. Команды принимали произвольные решения, в результате чего каждый элемент управления имел свои особенности.
Дороговизна внесения изменений. Чтобы внести одно изменение для конечного пользователя, нужно было найти все места, где было прописано правило, и редко когда существовала единая точка определения.
Дорогое тестирование. Настройка тестирования требовала глубокого знания состояний серверной части, а комплексное ручное тестирование конечных развертываний было неосуществимо из-за количества взаимодействующих параметров.
Мы создали декларативный фреймворк для элементов управления администратора, который служит источником достоверной информации в кодовой базе. Теперь элемент управления указывает, что он собой представляет:
Каждое поле здесь сопоставляется с ветвью из диалогового окна выше: requiredAdminRole — это проверка на соответствие требованиям HIPAA/наличие роли супер-администратора, upsellBehavior — это две ветви, связанные с дополнительными продажами, а churnBehavior — это случай с ушедшим клиентом, позволяющий ему восстановить настройки по умолчанию и ничего больше.
В рамках этого фреймворк предоставляет хуки, которые инженеры используют для получения вычисленного состояния элемента управления. Посмотрите, как теперь выглядит то же диалоговое окно настроек конфиденциальности проекта:
Цепочка условных операторов в баннере была сведена к одному общему компоненту, управляемому централизованным хуком. Фреймворк обрабатывает комбинаторную логику всех различных сценариев, а профильные специалисты, ответственные за его поддержку и глубоко разбирающиеся в продукте для администрирования, могут уверенно вносить масштабные изменения. Теперь мы используем строгую типизацию, чтобы помочь разработчикам заполнить обязательную информацию, необходимую для правильного отображения их настройки во всех возможных сценариях. Важно отметить, что им не нужно разбираться в тонкостях этих сценариев или в том, как они взаимодействуют друг с другом.
Эти настройки доступны через строки в пользовательском интерфейсе консоли администратора. К видимости этих строк был применён тот же подход, и здесь в игру вступает второй фреймворк. Строка в реестре настроек не описывает собственные правила видимости, а привязывает их к элементам управления, которые её представляют:
Массив элементов управления — это дополнительная ценность. Он содержит тот же объект ProjectDefaultPrivacy, который диалоговое окно передаёт функции useAdminConsoleControl, а реестр пропускает его через тот же единый источник достоверной информации, поэтому страница и диалоговое окно не могут расходиться. Раньше он вычислялся отдельно, поэтому расхождения могли приводить к двум видам сбоев: строка была видима, но открывала диалоговое окно, которым нельзя было воспользоваться, или клиент платил за настройку, но не было строки, через которую можно было бы до неё добраться. Централизация устранила эту категорию ошибок.
Тесты, в которых использовались централизованные фреймворки, значительно улучшили работу рецензентов PR. Например, возьмём тестирование видимости строк, которое отвечает на вопрос «Какие настройки на самом деле видит этот клиент?» вопрос, который мы задавали ранее. Вместо тестового кода сценарий представляет собой просто данные: персонаж, состояние домена и страницы, на которых он отображается.
А в строке просто перечисляются сценарии, в которых она должна отображаться:
Нет необходимости писать вызов рендеринга или утверждение. Динамический набор тестов считывает каталог и проверяет каждую строку по каждому сценарию, в котором она указана. Теперь каталог — это единственное место, где указано, что видит клиент, и где всё проверяется машиной. Больше не нужно полагаться на тщательность рецензента кода или автора, чтобы правильно определить и написать собственные тестовые сценарии.
Мы начали эту работу в конце 2025 года, поскольку предвидели необходимость дать возможность инженерам, не являющимся экспертами в предметной области, уверенно работать в консоли администратора. В то время целью не была оптимизация производительности LLM, но, как оказалось, стандартизация и упрощение работы для инженеров дают тот же результат и для агентов ИИ.
Прежде чем создавать эти фреймворки, мы действительно применили ИИ к этой проблеме миграции, и технически это сработало. Проблема заключалась в том, что ни агент, ни рецензент не могли определить, действительно ли тесты были правильными, что приводило к ложной уверенности и незаметным пробелам. ИИ не устраняет отсутствие структуры, а просто генерирует больше кода быстрее, независимо от того, какая структура уже существует. Google привел аналогичный аргумент в пользу системы типов Go при разработке с использованием ИИ: статические типы действуют как автоматическая система защиты, поскольку LLM склонны к галлюцинациям в отношении свойств и несоответствию типов в разных файлах. TypeScript не является статически строгим, как Go, но фреймворк может обеспечить такую же гарантию на его основе: достаточно один раз определить тип элемента управления на уровне фреймворка, и каждая реализация должна соответствовать ему в месте использования.
Когда фреймворки были готовы, мы начали готовиться к делегированию и параллелизации. Я использовал наш новый инструмент разработки на основе спецификаций [заполнитель ссылки: публикация в блоге на английском языке о разработке на основе спецификаций: Блог разработчиков Asana — Разработка на основе спецификаций: лучшие аспекты], чтобы создать навык, который выполняет работу от начала до конца. Он кодирует всю конвертацию: определяет элемент управления, вызывает хук, заменяет баннеры, обновляет фрагменты, добавляет новые декларативные тесты, а также самообновляющийся список дел и журнал пограничных случаев из предыдущих конвертаций. Из примерно 150 миграций 91 % не потребовали доработки после проверки.
Запуск агента для создания запроса на внесение изменений не требует особых усилий, как и проверка такого запроса. Поскольку всё объявляется предсказуемым образом, проверяющим не нужно быть экспертами в области администрирования, чтобы проверить, соответствует ли реализация спецификации продукта. Что особенно важно, это открывает доступ к пулу рецензентов для гораздо более широкой группы инженеров, что повышает скорость работы больше, чем просто расширение воронки на верхнем уровне, где создаются запросы на внесение изменений. Мы не единственные, кто переосмысливает процесс ревью в современную эпоху: GitHub перестроил собственный агент ревью Copilot на основе структурированных данных о пул-реквестах, чтобы помочь рецензентам-людям быстрее находить нужные вопросы, что позволило сократить затраты на ревью примерно на 20%.
Первоначальная миграция ~150 элементов, охватывающих несколько фреймворков, была определена как ручная, одноразовая инженерная работа от начала до конца. Сначала мы создали фреймворки, а затем поручили миграцию инженерам, которые впоследствии контролировали агентов. Это позволило нам завершить всю работу более чем на месяц раньше, чем предусматривал первоначальный план.
Создание этих фреймворков никогда не было самоцелью. Оно возникло из необходимости, из плана действий, который требовал параллелизации и масштабирования, с ограниченным и меняющимся составом персонала на протяжении всего процесса и без требования, чтобы каждый участник сначала стал экспертом в своей области. Мы уже видели, как он работает за пределами команды, которая его создала: 18 из 66 элементов управления во фреймворке на сегодняшний день были разработаны инженерами из 8 разных команд.
Теперь мы ищем следующую сферу, в которую можно было бы сделать такие инвестиции. Во всяком случае, сейчас аргументы в пользу этого решения еще весомее, чем до того, как мы начали: хорошо продуманный декларативный фреймворк не просто упрощает ревью, но и определяет, создает ли агент что-то надежное или просто что-то быстрое. Это также то, что может сделать автономную проверку возможной: Cloudflare создала систему, в которой рецензент на базе ИИ самостоятельно одобряет чистый код и блокирует реальные проблемы, и это работает только потому, что их точки входа достаточно структурированы, чтобы рецензент мог им доверять. Достаточно ли структурированы наши данные, чтобы попробовать сделать то же самое — это хороший следующий вопрос.
Лео Чжан — инженер-программист команды Admin Foundations, которая помогает ИТ-администраторам управлять своими организациями. В настоящее время он улучшает процесс разработки для других инженеров продукта в консоли администратора, инвестируя в технические фреймворки, лежащие в основе нашего продукта.
Разработка, внедрение, тестирование и внедрение этих изменений потребовали огромных усилий всей команды. Это стало возможным благодаря вкладу других инженеров команды Admin Foundations: Юнуса Рахбара, Марьям Бушехриан, Саверио Кастелли, Бронвин Дамм, Синди Ю, Кэлвина Нортона и Джаксуна Маккарти Хаггана. Уолтер Ли из команды Agent Success Tiger оказал огромную помощь в настройке подходящих инструментов ИИ для этих переносов.
Лан Чэн, Эмерсон Мерфи-Хилл, Марк Каннинг, Сиера Джаспан, Коллин Грин, Андреа Найт, Нань Чжан и Элизабет Каммер, «Что повышает производительность разработчиков в Google? Code Quality», ESEC/FSE '22, ноябрь 2022 г. https://doi.org/10.1145/3540250.3558940
«Организация проверки кода с помощью ИИ в масштабе», блог Cloudflare, апрель 2026 г. https://blog.cloudflare.com/ai-code-review/
Напалис Клициус, «Более совершенные инструменты ухудшили качество проверки кода Copilot. Вот как мы действительно улучшили его», блог GitHub, июль 2026 г. https://github.blog/ai-and-ml/github-copilot/better-tools-made-copilot-code-review-worse-heres-how-we-actually-improved-it/
«Why Go is an Ideal Language for AI-Assisted Software Engineering» (Почему Go — идеальный язык для разработки ПО с помощью ИИ), блог Google Developers, август 2026 г. https://developers.googleblog.com/why-go-is-an-ideal-language-for-ai-assisted-software-engineering/