ИИ ускорил разработку. Почему продакшен стал ломаться чаще

от автора

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

Начну с ситуации, которая, скорее всего, уже с вами случалась.

На прошлой неделе вы сделали пулл-реквест. Код, сгенерированный искусственным интеллектом, выглядел аккуратно: читаемый diff, тесты проходят, ничего явно подозрительного. Вы его одобрили. А через два дня в продакшене что-то сломалось так, как никто не ожидал.

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

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

Баг, которого как будто нет

У этого сценария сбоя теперь есть название: иллюзия корректности.

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

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

Допущения о границах. «Это поле всегда есть». Только вот его нет. Один из ваших downstream-сервисов восемь месяцев назад неудачно задеплоился и при определенных условиях начал отбрасывать это поле. В стейджинге тесты проходят. Нагрузочный тест выглядит нормально. А потом в два часа ночи реальный заказ попадает в настоящий краевой случай.

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

Доменные допущения. «Эти два статуса заказа эквивалентны». Нет, не эквивалентны. Ваша команда fulfillment и команда биллинга всегда обрабатывали их по-разному. Просто никто не зафиксировал это как правило, которое можно автоматически проверять. Искусственный интеллект не мог об этом знать, потому что этого не было в коде.

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

Код компилируется. Пулл-реквест выглядит чисто. А потом продакшен-данные и реальные пользователи показывают, каких правил в нем не хватало.

Особенно неприятно то, что это не всплывает на код-ревью. Это всплывает уже в инцидентах.

Почему ускорение может на самом деле вас замедлить

Вот ментальная модель, которую я использую со своими командами.

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

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

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

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

Рефакторинг — это не уборка. Это мультипликатор

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

Ни одна из этих рамок не помогает, когда вы пытаетесь двигаться быстро и при этом безопасно.

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

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

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

Четыре guardrails, которые закрепляют скорость: CATS

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

C — Contracts

Сделайте границы явными. Спецификации API, схемы событий, контракты данных, определения зон ответственности.

Вот сценарий, который я наблюдал уже не раз. Три команды используют общий сервис расчета цен. Формального контракта нет — только общее понимание и документ, который никто не поддерживает в актуальном состоянии. Один инженер с помощью ИИ рефакторит структуру ответа. Выглядит чисто, тесты проходят, изменения вливаются. Через два дня две из трех команд получают алерты, потому что поля, на которые они полагались, изменили смысл или исчезли.

Это не проблема искусственного интеллекта. Это отсутствующий контракт.

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

Каждый раз, когда ваша команда говорила: «Я думал, это поле всегда есть», — перед вами кандидат на контракт. Зафиксируйте его. Не только структуру: смысл, допустимые значения и того, к кому идти, если всё сломается.

A — Automated Verification

Тесты, которые проверяют доменные инварианты, а не просто покрывают happy path. Валидация схем в CI. Проверки безопасности в пайплайне.

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

Типичная ошибка: команда с помощью ИИ генерирует набор тестов, показатели покрытия выглядят прилично, команда им доверяет. Но это покрытие построено вокруг сценариев, которые искусственный интеллект смог вывести из паттернов в коде. А продакшен ломают как раз те сценарии, которые никто не записал.

Ваша задача — назвать инварианты. Задача ИИ — покрыть их тестами. Валидация схем в CI ловит дрейф контракта на этапе merge, а не в продакшене. Автоматизированные проверки безопасности ловят места, где «это же внутреннее, значит, безопасно» незаметно зашивается в код, и никто не задает лишних вопросов.

T — Telemetry

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

Код-ревью показывает, что написано в коде. Телеметрия показывает, что он делает. Это разные вещи. Когда вы вливаете больше пулл-реквестов и делаете это быстрее, разрыв между тем, что код говорит, и тем, что он реально делает, может быстро расти.

Реальный пример: команда выкатывает отрефакторенный флоу обработки заказов. На ревью всё выглядит нормально, нагрузочные тесты проходят. Но из-за небольшого изменения в обработке null-значений определенный тип edge-case-заказов начинает тихо падать — без ошибки, просто с неправильным состоянием. Без алерта на переходы состояний заказа команда узнает об этом через три дня из тикета в поддержку.

С обнаружением дрейфа вы ловите это на уровне 0,3% ошибок. А не в момент «подождите, почему в четверг просела выручка?».

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

S — Simplification

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

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

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

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

Как это выглядит на практике

Давайте сравним два режима на конкретном примере.

Без CATS: Искусственный интеллект генерирует сервис. Пулл-реквест выглядит отлично. Формального API-контракта нет. Downstream-команды интегрируются по тому, что видят в поведении сервиса. Через три квартала кто-то рефакторит структуру ответа. Две команды одновременно получают алерты вечером в пятницу. В постмортеме пишут: «сбой коммуникации». Настоящая причина — отсутствующий контракт.

С CATS: Искусственный интеллект генерирует тот же сервис. Перед merge кто-то описывает контракт: спецификацию API, смысл полей, зоны ответственности, версионирование. В CI добавляют валидацию схем. Когда через три квартала происходит рефакторинг, версия контракта повышается, а потребители узнают об этом через падение CI, а не через инцидент в продакшене.

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

Быстро без CATS — это когда скорость превращается в хрупкость. Быстро с CATS — это когда скорость накапливает эффект.

Двухнедельный спринт для старта — без остановки разработки фич

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

Неделя 1: контракты и безопасность

Найдите две-три самые хрупкие границы. Где чаще всего всё ломается? Где ваша команда говорила: «Я думал, так было всегда»? Это ваши кандидаты на контракты.

Опишите контракты. Не только структуру, но и смысл. Что означает каждое поле? Какие значения допустимы? Кто за него отвечает? К кому идти, если оно ломается?

Добавьте проверку контрактов в CI. Валидация схем при merge, как обязательный гейт.

Напишите один тест на инвариант. Выберите доменное правило, нарушение которого причиняет больше всего ущерба. Один набор тестов. Не весь бэклог — только один.

Неделя 2: наблюдаемость и упрощение

Добавьте дашборды и алерты для обнаружения дрейфа. Отслеживайте сценарии сбоев из первой недели. Узнавайте, что что-то идет не так, на уровне 0,3%, а не когда об этом сообщает пользователь.

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

Добавьте безопасные настройки выкатки по умолчанию. Шаблон фича-флага, пороговые значения для canary-выкатки, чек-лист отката, которым команда реально может воспользоваться, не созывая отдельный звонок.

Измеряйте. Размер пулл-реквеста, количество инцидентов на изменение, накладные расходы на координацию. Зафиксируйте базовые значения сейчас. Вернитесь к ним на четвертой неделе.

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

Сдвиг, который действительно важен

Сообщество platform engineering годами строило более удобные инструменты: внутренние платформы для разработчиков, golden paths, service mesh, стандартизированные стеки наблюдаемости. Вся эта инфраструктура исходит из предположения, что команды могут доставлять изменения в высоком темпе, а система при этом не будет постепенно становиться хрупкой.

Искусственный интеллект резко изменил сторону уравнения, связанную со скоростью. Сторона безопасности за ним не успела.

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

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

Подведем итоги

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

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

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

Что сделать в понедельник: найдите одну хрупкую границу. Опишите для нее контракт. Добавьте один тест на инвариант.

С этого всё начинается.

Больше о качестве и безопасной автоматизации разработки —
в двух материалах по теме:

Тему инженерных guardrails можно продолжить на двух бесплатных демо-уроках. На них разберут наблюдаемость и безопасный деплой, а заодно можно будет задать вопросы преподавателям-практикам и посмотреть, как устроено обучение.

  • 4 августа, 20:00. «OpenTelemetry — наблюдаемость на блюдечке». Записаться

  • 10 августа, 20:00. «Kubernetes + CI/CD + GitOps — делаем стабильный деплой без выхода из кластера». Записаться

ссылка на оригинал статьи https://habr.com/ru/articles/1058978/