Как маленькая проблема превратилась в многомиллионную проблему в масштабах Google

В соавторстве с Бабу Прасад и Видхи Гупта

Я работаю в Google около трёх с половиной лет. Еще в 2021 году мы столкнулись с небольшой проблемой. У команды, с которой мы работали, было слишком много повторяющихся ошибок.

Как они оказались в такой ситуации?

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

Автоматические системы регистрации ошибок хороши тем, что они сокращают объем работы и гарантируют, что сбои не будут проигнорированы. Но в конечном итоге необходимо участие человека, и именно здесь процесс может стать узким местом. Кто-то должен посмотреть на ошибки и решить, являются ли они настоящей проблемой или нет. Другими словами, мы создали ботов, которые экономят человеческий труд, который генерирует человеческий труд на сервере!

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

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

Итак, мы начали думать: есть ли в Google другие команды, сталкивающиеся с подобными трудностями из-за повторяющихся ошибок?

Что нас осенило, так это то, что, хотя трудозатраты были относительно небольшими для каждой отдельной команды (в основном просто раздражали), в масштабах Google они могли составить очень большую сумму. Инженер, тративший 5 минут на исследование ошибки, которая была дубликатом, умноженная на тысячи дублированных ошибок, добавилась к годам тяжелого труда.

Но можем ли мы оценить это количественно, чтобы решить, есть ли веское экономическое обоснование для решения этой проблемы?

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

Как мы можем воспользоваться этой возможностью? Мы могли бы воспроизвести (в программном обеспечении) некоторые процессы и рассуждения, через которые на самом деле проходят люди, чтобы сравнить две ошибки и решить, повторяются они или нет. По большей части люди используют легкодоступные подсказки, чтобы повысить свою уверенность в том, что ошибки дублируются. Если ошибки имеют один и тот же путь (или, в более широком смысле, какую часть пути они разделяют), имеют ли они схожие заголовки, имеют ли они схожие трассировки стека, были ли они зарегистрированы примерно в одно и то же время и так далее. Человек смотрит на целый ряд измерений и, основываясь на предполагаемой близости между двумя ошибками в этих измерениях, принимает окончательное решение, объединяющее всю достоверность.

Это идеальное решение для машинного обучения! Пусть боты разберутся с трудом, созданным ботами!

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

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

Наша первоначальная мысль заключалась в том, что кластеризация хорошо подойдет для решения этой проблемы. Это потребовало от нас инвестиций в такие методы, как K-средние, или применения полуконтролируемых подходов, поскольку у нас была некоторая достоверная информация о дубликатах. Но поскольку мы все были новичками в машинном обучении, мы начали с более простого подхода — использования бинарной классификации — когда мы сравниваем две ошибки и определяем, являются ли они дубликатами или нет. Учитывая существующие инструменты и средства автоматизации в Google, мы смогли перейти от концепции к решению за считанные недели. Мы придумали функцию оценки, позволяющую ранжировать все возможные дубликаты на основе релевантности и выбирать только те, которые превышают пороговое значение. Ошибки были богаты метаданными, при этом название и описание ошибки были очевидными кандидатами, но мы также экспериментировали с другими фрагментами данных, такими как количество дубликатов, прикрепленных к ошибке, количество комментариев и обновлений, приоритет, серьезность, количество неправильных прогнозов дубликатов, которые частью которой была ошибка, количество затронутых пользователей и т. д. для ранжирования выявленных ошибок. Нам было относительно легко разобраться с моделью бинарной классификации и улучшить ее до уровня, при котором мы получили точность › 90%. Мы знали, что такой подход будет означать, что мы не сможем масштабироваться за границы продукта, то есть выявлять проблемы, которые оказывают влияние на разные продукты (что означало проведение попарного сравнения по каждой открытой проблеме в Google). Однако это представляло собой очень небольшую часть проблем, и мы были готовы пойти на этот компромисс ради скорости. Когда мы начинаем использовать машинное обучение для решения новых проблем, ключевым моментом является быстрота неудач, и этот подход позволил нам доказать эту идею и ускорить итерацию.

Как только мы доказали эту первоначальную осуществимость, пришло время задуматься о форме продукта. Прототипирование — это одно, а производство — совсем другая проблема. Нам нужно было подумать об опыте работы с клиентами и о том, как инженеры Google могли бы его использовать. Как мы можем превратить это в настоящий продукт?

Вот два решения, которые мы приняли вначале:

  • Автоматизированные ошибки или ошибки, зарегистрированные вручную? Мы решили сначала сосредоточить внимание на узкой направленности, чтобы доказать осуществимость в одном приложении, а не пытаться вскипятить океан. Мы выбрали автоматическую регистрацию ошибок из одного конкретного автофайла. Это упростило мир: поскольку каждая категория автоподавателей имела фиксированный шаблон, мы могли обучать модель на данных, которые следовали определенным шаблонам, и поэтому наша модель ML могла иметь более стабильный набор функций. Мы проанализировали исторические данные об ошибках и выбрали авторегистратор, который способствовал наибольшему количеству повторяющихся ошибок в Google, преследуя единственную крупнейшую бизнес-возможность. Мы осознавали, что существует риск, что наше решение действительно хорошо сработает в этом конкретном случае, давая нам ложную уверенность в том, что оно может применяться более широко, но здесь мы не хотели ставить телегу впереди лошади.
  • Сколько команд нужно нацелить? В краткосрочной перспективе мы начали с ошибок всего от двух команд, чтобы доказать жизнеспособность. Через три месяца мы увеличили объем работы примерно до десяти команд в этой организации, чтобы доказать, что модели могут обрабатывать более разнообразные данные. Мы решили работать глубоко с маленьким количеством команд, а не широко с большим количеством команд, чтобы мы могли понять нюансы пространства. Мы знали, что в конечном итоге нам нужен весь Google в нашей системе, и мы не могли поддерживать такой уровень поддержки и формального внедрения по мере масштабирования, но я считаю, что с точки зрения производительности труда обычно необходимо начните с подхода домашнее животное, а не скот, а затем разработайте процессы для его масштабирования до подхода скот, а не домашние животные, когда зрелость вашего продукта это оправдывает.

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

  • Принять меры. Как только наша система с достаточной уверенностью обнаружит дубликат, она сможет автоматически закрыть ошибку. Это полностью исключило тяжелый труд, но привело к значительному риску. Поскольку точность никогда не будет 100%, мы можем позволить законным проблемам ускользнуть в производство (ложные срабатывания). Даже если бы это был настоящий дубликат, мы также могли бы попасть в повторяющиеся циклы, когда тест терпит неудачу, мы решаем, что это дубликат, поэтому игнорируем его, а затем он продолжает терпеть неудачу, и мы продолжаем считать, что это дубликат, навсегда («откладывание» ошибок) . Это приводит к трате времени выполнения и аппаратных ресурсов на бессмысленный тест, о котором люди не знают. Наконец, если наша модель получит широкое распространение в Google и мы будем принимать все решения, в конечном итоге не останется никаких достоверных обучающих данных.
  • Предложить действие.более консервативный подход заключался в том, чтобы добавить комментарий к ошибке, но не предпринимать никаких действий. Это устранило риски предыдущего варианта (поскольку окончательное решение принимал человек и мог отвергнуть мнение нашей системы), но не устранило трудозатраты (хотя и значительно сократило их). Люди по-прежнему смотрели на ошибку и предпринимали окончательные действия, но теперь, поскольку мы добавили в саму ошибку четкую информацию, указывающую на предполагаемые повторяющиеся ошибки, они могли принять решение гораздо быстрее.
  • Что-то среднее:достижение золотой середины как с точки зрения толерантности к риску, так и с точки зрения снижения трудоемкости. Например, используя показатель уверенности машинного обучения, чтобы решить, следует ли (а) просто добавить комментарий к ошибке, (б) добавить комментарий и пометить ошибку как повторяющуюся, но позволить человеку закрыть ее, или (в) закрыть автоматически. Мы могли бы использовать другие параметры, чтобы влиять на наши пороговые значения, такие как приоритет ошибки: требуется гораздо более высокая точность для ошибок p1, чем для ошибок p2 и т. д. Наконец, мы могли бы сделать это полностью настраиваемым, чтобы команды были заинтересованы в уменьшении количества ошибок. человеческий труд может принять сознательное решение сделать это с более высоким риском того, что законная проблема ускользнет в производство («шкала риска»).

Поскольку это проблема машинного обучения, мы внутренне отслеживали точность и напоминаемость. Но мне нужен был лучший способ объяснить влияние на бизнес человеку, который не обязательно был энтузиастом МО. У меня получилась вот такая таблица:

Использование TP, TN, FN и FP вместо точности и полноты позволило нам сосредоточиться на каком влиянии на бизнес мы достигли. Что касается труда, если мы предположим, что человек потратил 5 минут своего времени на исследование повторяющейся ошибки, мы могли бы просто умножить TP*5m, чтобы выяснить, сколько времени мы сэкономим для Google. Что касается риска, FP дал четкую оценку проблем, которые могут ускользнуть от производства из-за нашего подхода.

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

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

Если вы хотите прочитать больше, мы опубликовали пару защитных публикаций: