Субпрайм-кризис кода. Долгосрочная цена ИИ-ассистентов

- -
- 100%
- +
Проверьте post-layoff MTTR. До сокращений инцидент закрывался за час? После — за шесть? Это и есть post-layoff MTTR. Считайте.
Метрики
Метрика Формула Что показывает
Review latency Время от PR до merge Скорость securitization
Unexplainable PR ratio PR без объяснения / всего PR Паттерн 3
Hallucinated dependency rate Найденные галлюцинации / всего зависимостей Паттерн 2
Patch-over-patch rate Патчи поверх патчей / всего фиксов Паттерн 4
Post-layoff MTTR MTTR после сокращений / MTTR до Паттерн 5
Формула unexplained PR ratio (оценка):
text
Unexplainable PR Ratio = (PR без объяснения / Всего PR) × 100%
Если> 20% — паттерн 3 в активной фазе. Если> 50% — вы в зоне субпрайма.
Кейс из trenches
Собирательный кейс. Детали изменены.
Enterprise, regulated, банк. 200 разработчиков. Стек: Java + Spring + Kafka + Oracle. Внедрили ИИ-ассистента по инициативе CTO. Цель — ускорить доставку фич. За полгода velocity выросла на 60%. Руководство довольно.
Через восемь месяцев — внутренний аудит. Комплаенс-требования: каждое изменение в критичных модулях должно быть объяснено и задокументировано.
Комплаенс-офицер открыл PaymentProcessor. java. 4000 строк. Сгенерировано ИИ. Документации нет. Он вызвал автора. Автор посмотрел на код и сказал: «Я не помню, что здесь». Комплаенс-офицер закрыл файл. Написал в отчёте: «Требуется ручное ревью каждого изменения».
Через неделю релизы встали.
Аудит показал: 30% сгенерированного кода не имеет документации. Авторы промптов не могут объяснить логику. Часть кода использует паттерны, несовместимые с внутренними стандартами.
Катастрофы не было. Никто не уволился. Прод не упал. Но:
Релизы критичных модулей остановлены на 6 недель.
Три команды переведены на ручное ревью каждого PR.
Введён обязательный owner для каждого изменения.
Внедрён AI Usage Policy.
Стоимость комплаенс-аудита: $80—120 тыс. (оценка).
Потеря времени: 6 недель релизного цикла.
Что сделали не так: не ввели ownership, не считали debt interest, не проверяли, что генерация совместима с комплаенс.
Что сделали правильно: остановились, провели аудит, ввели правила. Не стали ждать инцидента.
Кто заплатил? Банк — деньгами и временем. Команды — нервами. Но не клиенты. Пока.
Красные флаги
«Это просто хейтеры.»
«У нас не так.»
«На Reddit одни неудачники.»
«У нас всё под контролем.»
«Мы не читаем форумы. Мы делаем.»
«ИИ не может ошибаться, это модель.»
«Мы потом разберёмся.»
Антипаттерн
Как делать НЕ надо:
Игнорировать форумы, потому что «там одни жалобы».
Верить одному треду.
Не проверять паттерны у себя.
Считать review формальностью.
Не считать review latency.
Оставлять галлюцинированные зависимости в коде.
Чинить сгенерированный код сгенерированными патчами.
Сокращать команду под ИИ, не считая последствий.
Чеклист
□ Проведён анонимный опрос в команде.
□ Посчитан review latency.
□ Проверена доля PR без объяснения.
□ Проверены зависимости на галлюцинации.
□ Проверена доля патчей поверх патчей.
□ Проверены последствия сокращений (если были).
□ Команда знает паттерны и их названия.
□ Есть план реакции на каждый паттерн.
□ Руководство знает о паттернах.
□ Форумы читаются как диагностика, а не как шум.
Что запомнить
Один комментарий — это человек, у которого болит. Десять — это система. У вас она тоже есть. Проверьте.
Что почитать
DOU, Reddit r/programming, Hacker News — читать не как новости, а как диагностику. Ищите не истории, а совпадения. Если три команды в разных странах пишут одно и то же — это не совпадение.
«Accelerate» (Forsgren, Humble, Kim) — как отличать сигнал от шума в метриках.
«The Field Guide to Understanding Human Error» (Sidney Dekker) — почему системы ошибаются, а не люди.
Google SRE Book — как разбирать инциденты и находить паттерны.
«Thinking in Systems» (Donella Meadows) — как видеть системы, а не события.
Глава 4. Пять слоёв скрытого долга
«Мы думали, у нас один долг. Оказалось — пять. И они росли одновременно.»
— из разбора архитектурного аудита в продуктовой команде
Тезис
ИИ-код создаёт долг не в одном месте, а сразу в пяти: когнитивном, архитектурном, операционном, организационном и безопасностном. Лечить один слой бесполезно — остальные четыре продолжат расти. Слои усиливают друг друга: когнитивный порождает архитектурный, архитектурный — операционный, операционный — организационный. Безопасностный ждёт своего часа.
Ключевые вопросы
Где именно накапливается долг от ИИ-кода?
Как измерить каждый слой?
Какой слой самый опасный?
Как слои усиливают друг друга?
Как провести аудит по пяти слоям и не утонуть?
4.1. Пять слоёв: почему одного недостаточно
Вторник, 11:20. Архитектурный аудит в продуктовой команде. Тимлид открывает отчёт и говорит: «У нас технический долг». Архитектор кивает. Через час выясняется: то, что они называют «техническим долгом», — это пять разных проблем, которые выросли одновременно.
Первая: никто не помнит, зачем в модуле оплаты два индекса. Это когнитивный долг. Вторая: три сервиса дублируют логику скидок. Это архитектурный. Третья: алерты приходят, но никто не знает, что они значат. Это операционный. Четвёртая: два разработчика ушли, их модули никто не поддерживает. Это организационный. Пятая: в сгенерированном конфиге лежит ключ от прода. Это безопасностный.
Пять слоёв. Пять разных людей, которые должны их чинить. Пять разных метрик. Если вы лечите только технический долг — вы лечите симптом, а не систему.
Слой Что включает Кто отвечает Когда срабатывает
Когнитивный Потеря замысла, непонятный код Автор, owner, команда При первом изменении
Архитектурный Дублирование, локальные оптимумы Архитектор, tech lead При масштабировании
Операционный Нет тестов, нет логирования, алерты-загадки SRE, on-call При инциденте
Организационный Ownership-вакуум, потеря экспертизы CTO, VP Engineering При уходе автора
Безопасностный Секреты в коде, уязвимые зависимости Security, комплаенс При аудите или атаке
Когнитивный измеряется временем до контекста. Архитектурный — дублированием. Операционный — MTTR. Организационный — orphan code ratio. Безопасностный — находками сканера. Пять слоёв. Пять метрик. Одна таблица, которую никто не ведёт.
4.2. Когнитивный долг: никто не помнит замысел
Среда, 15:40. Разработчик открывает модуль, который нужно изменить. 800 строк на Go. Сгенерировано четыре месяца назад. Автор промпта ушёл — сначала в отпуск, потом в другую компанию. git blame показывает «AI assistant».
Он читает функцию ProcessPayment. Понимает процентов на тридцать. Остальное — «работает, но непонятно как». Почему здесь используется очередь вместо прямого вызова? Почему ретрай с экспоненциальной задержкой, а не фиксированной? Почему в одном месте context. WithTimeout, а в другом — time.After? Он не знает. Никто не знает.
Он идёт к тимлиду. Тимлид смотрит, пожимает плечами. Идёт к архитектору. Архитектор не видел этот модуль ни разу. Через час они втроём сидят в переговорке и гадают. Три senior-инженера, 40 лет опыта на троих, смотрят на код и не могут ответить на простой вопрос: почему?
Это когнитивный долг. Вы платите не за то, что код плохой. Вы платите за то, что никто не понимает, почему он хороший.
Когнитивный долг — самый коварный. Он не виден в метриках. Не проявляется в инцидентах. Он ждёт, пока кто-то попробует изменить код. Тогда срабатывает: изменение ломает три соседних модуля, потому что никто не знал про неочевидные связи.
Как его увидеть? Спросите нового разработчика: сколько времени ему нужно, чтобы понять модуль? Если час — долг низкий. Если день — средний. Если он приходит к вам через три дня и говорит «я не понимаю» — высокий. Это называется time to context. Если не можете назвать человека, который понимает модуль, — оценка 5.
4.3. Архитектурный долг: локальные оптимумы, дублирование
Четверг, 10:15. Архитектор смотрит на граф зависимостей. Три сервиса дублируют логику скидок. В одном — скидка считается по старой формуле. В другом — по новой. В третьем — по какой-то третьей, которую никто не помнит. Каждый сервис сгенерирован ИИ в разное время. Каждый — локальный оптимум. Глобально — хаос.
ИИ не знает, что скидка уже есть в трёх местах. Он знает про промпт. Промпт был «сделай скидку». Он сделал. Четвёртую. Пятая будет в следующем спринте.
Архитектурный долг выглядит так: дублирование логики (десять способов сделать одно и то же), dependency hell (сгенерированные зависимости, несовместимые друг с другом), несовместимые паттерны (один модуль на event-driven, другой на синхронных вызовах), нарушение границ (сервис А лезет в базу сервиса Б).
Измерить его можно через duplication rate — долю дублированного кода. Если у вас три реализации скидки, а должна быть одна, — это 200% дублирования в этой области. Если CI не проходит архитектурные проверки (fitness functions) — оценка 5.
Здесь есть соблазн: «Давайте отрефакторим». Отрефакторить три сервиса, которые никто не понимает, — это не рефакторинг. Это археология с риском обрушения.
4.4. Операционный долг: непредсказуемые отказы
Пятница, 2:47. Алерт. Модуль биллинга. On-call открывает дашборд. Метрики красные. Он открывает код. 1200 строк на Kotlin. Сгенерировано. Логирование отсутствует — вообще. Он не знает, где ставить breakpoint. Не знает, какие метрики смотреть. Не знает, что именно сломалось. Он знает только, что клиенты не могут оплатить.
В Slack — 200 алертов. Из них 5 требуют действия. Остальные 195 — шум. Через месяц никто не смотрит на алерты. Через два — алерты отключили. Через три — инцидент обнаружил клиент. Это alert-to-action ratio: доля алертов, которые приводят к действию. Если меньше 10% — вы в зоне операционного долга.
ИИ генерирует код, который делает то, что просили. Он не генерирует логирование. Не генерирует метрики. Не генерирует алерты. Не пишет runbook. Всё это — на команде. И часто этого нет.
Операционный долг — это когда код работает, но вы не можете понять, как он работает, когда он ломается. MTTR растёт. Инциденты повторяются. Если incident recurrence rate — доля повторных инцидентов — больше 20%, вы не чините. Вы закрашиваете.
4.5. Организационный долг: ownership-вакуум, сокращения
Понедельник, 9:00. Тимлид смотрит на список модулей. Пять модулей не имеют owner-а. Авторы ушли. Двое — уволены. Трое — перешли в другие команды. Модули работают. Пока.
Модуль работает. Но если что-то сломается — чинить некому. Можно, конечно, спросить у ИИ. Он сгенерирует фикс. Потом второй. Потом третий. Пока модуль не перестанет работать окончательно.
Организационный долг — это долг, который нельзя починить кодом. Только людьми. Или их отсутствием. ИИ его усиливает: раньше у кода был автор. Теперь автора нет. Формально есть тот, кто писал промпт. Но он может уйти. Или не помнить. Или не понимать. Ownership-вакуум — это когда код есть, а ответственного нет.
Измерить его можно через orphan code ratio — долю кода без owner-а. Если 20% — оценка 3. Если критичные модули знает один человек — оценка 5, независимо от процентов. Один человек — это bus factor = 1. Он в отпуске. Инцидент ждёт.
4.6. Безопасность и комплаенс: утечки, лицензии, supply chain
Среда, 14:30. Security-инженер запускает сканер. Находит ключ от прода в сгенерированном конфиге. Ключ лежит в репозитории три месяца. Кто его туда положил — неизвестно. Модель сгенерировала. Разработчик мержил. Ревьюер не заметил. Все трое уже не работают здесь. Ключ работает.
Безопасностный долг — это долг, который не проявляется, пока не станет поздно. ИИ генерирует код, который может содержать секреты в открытом виде, уязвимые зависимости, галлюцинированные пакеты (которые могут быть вредоносными), код, нарушающий лицензии, отсутствие валидации входных данных.
Он отличается от остальных. Не растёт постепенно. Срабатывает внезапно. Один инцидент — и вы теряете данные, деньги, репутацию.
Считать его можно через security findings per PR — сколько уязвимостей на PR. Если сканеры чистые и SBOM ведётся — оценка 1. Если ключи в репозитории и никто не проверяет зависимости — 5.
Здесь есть ложное успокоение: «У нас же не банк». Утечка ключа от staging — это доступ к staging. Через staging — доступ к продакшену. Через продакшен — ко всему. Банк вы или нет — неважно.
4.7. Как слои усиливают друг друга
Слои не существуют отдельно. Они связаны. И это самое опасное.
text
Когнитивный долг
↓
Никто не понимает код → нельзя безопасно изменить →
↓
Архитектурный долг
↓
Дублирование, локальные оптимумы → сложнее отладка →
↓
Операционный долг
↓
Инциденты, MTTR растёт → люди устают, уходят →
↓
Организационный долг
↓
Нет owner-а → никто не проверяет безопасность →
↓
Безопасностный долг
Пример первый. Когнитивный долг: никто не понимает модуль оплаты. Из-за этого нельзя безопасно изменить логику. Появляется дублирование: новый модуль пишется с нуля. Архитектурный долг растёт. Дублирование приводит к непредсказуемым инцидентам. Операционный растёт. Инциденты утомляют команду. Люди уходят. Организационный растёт. Без owner-а никто не проверяет зависимости. Безопасностный растёт.
Пример второй. В другой команде когнитивный долг привёл к тому, что новый разработчик сломал продакшен в первый день. Не потому что плохой. Потому что никто не объяснил, что этот модуль нельзя трогать по пятницам. Никто не помнил почему. Раньше знал один человек. Он ушёл в отпуск.
Каждый слой усиливает следующий. Если вы лечите только один — остальные четыре продолжают расти. Через год вы получаете систему, где все пять слоёв достигли максимума. Это и есть foreclosure.
Практика: что сделать завтра
Проведите аудит по пяти слоям. Оцените каждый по шкале 1—5. Запишите результат. Повторите через месяц.
Для каждого слоя назначьте ответственного. Когнитивный — tech lead. Архитектурный — архитектор. Операционный — SRE. Организационный — CTO/VP. Безопасностный — security.
Введите debt register по слоям. Одна таблица. Пять колонок. Обзор раз в спринт.
Проверьте связи между слоями. Какой слой самый слабый? Он усиливает остальные.
Начните с организационного. Если нет owner-а, остальные слои некому чинить.
Не назначайте одного человека на всё. Пять слоёв — пять ответственных. Иначе вы вернётесь к «у нас технический долг».
Метрики
Слой Метрика Формула Что показывает
Когнитивный Unexplainable PR ratio PR без объяснения / всего PR Потеря замысла
Когнитивный Time to context Время на понимание модуля Глубина долга
Архитектурный Duplication rate Дублированный код / всего кода Локальные оптимумы
Операционный MTTR Среднее время восстановления Способность чинить
Операционный Alert-to-action ratio Алерты с действием / всего алертов Шум в мониторинге
Организационный Orphan code ratio Код без owner-а / всего кода Ownership-вакуум
Организационный Bus factor Мин. число людей, знающих модуль Хрупкость команды
Безопасностный Security findings per PR Находки / PR Уязвимости
Формула Debt Score (оценка):
text
Debt Score = (Cognitive + Architectural + Operational + Organizational + Security) / 5
Если> 3 — вы в зоне субпрайма. Если> 4 — foreclosure близко.
Кейс из trenches
Собирательный кейс. Детали изменены.
Продуктовая команда, 8 разработчиков, mobile-приложение для e-commerce. Стек: Swift + Kotlin + Node. js + PostgreSQL + Redis. Внедрили ИИ-ассистента для ускорения фич. Через полгода velocity выросла на 70%.
В августе тимлид заметил: два разработчика ушли, их модули никто не поддерживает. Он провёл аудит по пяти слоям.
Тимлид сидел в переговорке с распечаткой. Пять колонок. Он вписывал числа и понимал: организационный — пять. Потому что два модуля не знает никто. Вообще никто. Он посмотрел на пустой стул напротив. На нём раньше сидел разработчик, который знал. Теперь стул пустой.
Когнитивный: 4/5. Сорок процентов модулей никто не может объяснить.
Архитектурный: 3/5. Дублирование логики скидок в трёх местах.
Операционный: 4/5. MTTR вырос с 40 минут до 4 часов.
Организационный: 5/5. Пять модулей без owner-а.
Безопасностный: 3/5. Нашли ключ от staging в репозитории.
Debt Score = (4+3+4+5+3) /5 = 3.8. Зона субпрайма.
Что сделали:
Назначили owner для каждого модуля. Даже если owner — один человек на три модуля.
Ввели правило: «Нет owner-а — нет merge».
Провели архитектурный review. Убрали дублирование скидок.
Добавили логирование и метрики в критичные модули.
Ввели security-сканер в CI.
Провели обучение по AI-aware review.
Через три месяца:
Когнитивный: 3/5. Архитектурный: 2/5. Операционный: 2/5.
Организационный: 2/5. Безопасностный: 2/5.
Debt Score = 2.2. Вышли из зоны субпрайма.
Катастрофы не было. Никто не уволился. Прод не упал. Но если бы аудит не провели — через год был бы foreclosure. Они остановились вовремя.
Красные флаги
«У нас только технический долг.»
«Безопасность — это отдел безопасности.»
«Мы потом разберёмся с owner-ами.»
«MTTR вырос, но это из-за роста нагрузки.»
«У нас всё под контролем.»
«Мы не считаем долг по слоям, это сложно.»
«Давайте сначала починим код, потом людей.»
Антипаттерн
Как делать НЕ надо:
Считать, что долг один.
Лечить только технический долг.
Не назначать owner-а.
Игнорировать безопасность до аудита.
Не считать MTTR.
Не проверять связи между слоями.
Начинать с кода, а не с людей.
Верить, что «потом разберёмся».
Чеклист
□ Проведён аудит по пяти слоям.
□ Каждый слой оценён по шкале 1—5.
□ Для каждого слоя назначен ответственный.
□ Введён debt register.
□ Проверены связи между слоями.
□ Назначен owner для каждого критичного модуля.
□ Введены метрики для каждого слоя.
□ Руководство знает о пяти слоях.
□ Есть план по каждому слою.
□ Аудит повторяется раз в квартал.
Что запомнить
Долг не один. Их пять. Лечить один — значит кормить остальные четыре.
Что почитать
«The DevOps Handbook» (Kim, Debois, Willis, Humble) — про операционный долг и как его измерять.
«Building Secure and Reliable Systems» (Google) — про безопасностный и операционный слои: как объединить их в одну систему.
«Software Architecture: The Hard Parts» (Ford, Richards, Sadalage, Dehghani) — про архитектурный долг и trade-off.
«The Phoenix Project» (Kim, Behr, Spafford) — про организационный долг и цену отсрочки.
«Thinking in Systems» (Donella Meadows) — про то, как слои усиливают друг друга.
Глава 5. Метрики, которые скрывают катастрофу
«Наш дашборд был зелёным. Прод — красным. Мы смотрели на дашборд.»
— из postmortem SaaS-компании
Тезис
Velocity, LOC и «скорость генерации» — это rating agencies субпрайма. Они показывают рост, пока не наступает foreclosure. Классические метрики не врут напрямую — они просто не видят того, что важно. Они измеряют то, что легко посчитать, а не то, что определяет выживание. Если метрика не включает стоимость владения — она врёт.
Ключевые вопросы
Почему классические метрики врут в эпоху ИИ?
Что мерить вместо них?
Почему DORA работает, но недостаточен?
Как cost of outage становится главной метрикой?
Как построить дашборд, который не скрывает катастрофу?
5.1. Метрики-обманки: LOC, PR count, story points
Понедельник, 10:00. Еженедельный статус. Тимлид открывает дашборд. Velocity — зелёная. LOC — растёт. PR count — рекорд за квартал. Руководство кивает. Все довольны. Через месяц — три инцидента. Через два — rewrite. Через три — CTO уволен. Дашборд не врал. Он показывал правду. Просто эта правда не имела отношения к выживанию.
Классические метрики измеряют то, что легко посчитать. Их легко посчитать, потому что они лежат на поверхности: строки, задачи, PR, story points. Но именно поэтому они не видят того, что важно.
Метрика Что измеряет Что не видит Почему обманка
LOC Объём кода Стоимость владения Больше кода ≠ больше ценности
PR count Скорость merge Качество review Больше PR ≠ лучше код
Story points Оценка сложности Реальная сложность Оценка ≠ реальность
Velocity Скорость доставки Стоимость доставки Скорость без направления — это бег в пропасть
«Скорость ИИ» Объём генерации Объём понимания Генерация ≠ понимание
Все пять метрик объединяет одно: они измеряют производство, а не владение. Производство видно сразу. Владение видно через год. Дашборд показывает первое. Второе вы узнаете из postmortem. Или из письма об увольнении.
Есть ирония. Чем быстрее вы генерируете, тем красивее дашборд. И тем ближе foreclosure. LOC растёт — и никто не понимает, что в этих строках. PR count растёт — и никто не помнит, что мержил вчера. Velocity растёт — и никто не считает, сколько будет стоить поддержка.



