
Все мы слышали об этих законах сетевых эффектов: ценность сети растёт как квадрат от количества участников. Или что затраты на коммуникацию растут как квадрат от количества участников; это может быть n log n или что-то подобное, в зависимости от того, как упорядочить участников. Иными словами, удвоение размера команды не удваивает её скорость, возникает ещё оверхед координирования. Величина оверхеда зависит от того, насколько плохо вы спроектировали организацию.
Но есть одно эмпирическое правило, о котором мне рассказали несколько десятков лет назад; с тех пор я не перестаю пользоваться им из-за его раздражающей истинности. Это правило раздражает, потому что кажется, что оно не должно быть верным. Я ни разу не слышал его теоретического обоснования. И тем не менее, оно проявляется постоянно.
Итак, вот оно:
Каждый слой согласований замедляет процесс в десять раз
Знаю, что вы подумали. «Да ладно, в десять раз? Это слишком много, не похоже на правду. Ты, наверно, преувеличиваешь».
Не-а.
Уточню, что здесь учитывается общее время, а не трудозатраты. Почти всё дополнительное время тратится на ожидание.
Пример:
Написать код простого устранения бага
30 минутПодождать, пока код проверит коллега, сидящий за соседним столом
300 минут → 5 часов → полдняПодождать, пока дизайн-документ сначала одобрит команда, занимающаяся архитектурой
50 часов → примерно неделяПодождать, пока всё это разместят в календаре какой-то другой команды
(например, если заказчик запросил фичу)
500 часов → 12 недель → один фискальный квартал
Хотел бы я сказать, что следующая ступенька — 10 кварталов, или примерно 2,5 года — это слишком безумно, чтобы быть правдой, но нет. Такова жизнь руководителя, находящегося выше команды средних размеров; когда мне нужно было изменить направление развития продукта, я постоянно сталкивался со всем этим даже в относительно маленькой команде уровня Tailscale. (А руководство, сидящее над крупными командами, вообще не может выполнять собственную работу. Но это уже другая история.)
ИИ этого не исправит
Во-первых, должен сказать, что этот пост не посвящён ИИ, потому что непосредственное влияние ИИ на эту проблему минимально. Говорите, Claude может написать код за 3 минуты вместо 30? Молодец, Claude, отличная работа.
А теперь вам нужно потратить 27 минут на проверку самому или в процессе диалога с ИИ (на самом деле, это довольно весело); или же вы можете сэкономить 27 минут и отправить ревьюеру непроверенный код; у него это, как и прежде, займёт 5 часов, но теперь он будет рассержен на вас за то, что вы заставили его читать слоп из-за собственной лени. Мы не получили от этого почти никакой пользы.
Вы скажете: но постойте, ценность агентского кодинга же не в этом. Мы не используем агентов, чтобы внести исправление, на которое разработчику понадобилось бы 30 минут. Мы применяем их в огромных недельных проектах, которые благодаря Claude теперь можно выполнять за пару часов! Вроде бы, звучит логично. Но нет, потому что если проект настолько огромен, то ревьюер будет ещё более взбешён тем, что вы не прочитали его сами; при этом проект слишком велик для проверки его одним блоком, поэтому вам приходится разбивать его на новые мелкие блоки, каждый из которых требует цикла ревью на 5 часов. К тому же, у такого проекта нет дизайн-документа, а значит, и осмысленной архитектуры, поэтому рано или поздно у кого-нибудь возникнут возражения; теперь мы снова возвращаемся к совещанию по ревью дизайн-документа, а наш монструозный недельный проект, который мы выполнили за два часа... снова требует неделю.
Единственный способ существенно ускориться — снижение количества ревью
Забавно, что уже десятки лет люди предсказывают наступление сингулярности: мы начнём создавать системы, которые настолько умны, что они смогут создавать следующие системы, которые ещё умнее, которые создают ещё более умные и так далее. После того, как мы начнём, если они будут умнеть достаточно быстро, то инкрементальное время (t), необходимое для достижения единицы усовершенствования (u), снижается до нуля, поэтому (u/t) стремится к бесконечности.
Я никогда не верил в эту теорию по простой причине, о которой мы говорили выше: основная часть времени, необходимого для создания чего-либо — это на самом деле не время самой работы. Это физическое время, которое тратится на ожидание и задержки.
А задержки нельзя победить грубой силой.
Знаю, что вам этого хочется. И я знаю, что многие из вас работают в компаниях, бизнес-модель которых зависит именно от этого.
Увы.
Но нельзя просто отказаться от проверок!
Ну да, на самом деле, этого сделать не получится.
Многие люди сегодня уже столкнулись с этим симптомом: начало конвейера (сгенерированный ИИ код) стал намного быстрее, но последующие этапы (ревью) слишком медленные! Поэтому люди придумывают очевидное решение: перестать проверять!
Пусть результат будет слопом, но если этот слоп в 100 раз дешевле, то даже если он принесёт хотя бы 1% пользы на единицу, то это будет вполне приемлемый компромисс. А если польза на единицу составит даже скромные 2% от той, что была раньше, то вы удвоите свою выгоду! Потрясающе.
В основе этой теории лежат довольно глупые допущения; вы и сами можете это понять. Достаточно сказать, что при этом возникает эффект, называемый мной «Прогрессирующее безумие ИИ-разработчика»:
Ого, я создал этот прототип так быстро! У меня появились сверхспособности!
Этот прототип становится забагованным. Скажу ИИ, чтобы он устранил баги.
Хм, каждое изменение вносит столько же новых багов, что и устраняет.
Ага! Но если у меня будет ИИ-агент, который проверяет код, то он сможет находить собственные баги!
Постойте-ка, а зачем мне самому передавать данные между агентами?
Мне нужен агентский фреймворк
Можно попросить моего агента написать этот фреймворк!
GOTO 1
Меня очень тревожит, что многие мои друзья и уважаемые коллеги уже потерялись в этом цикле. Claude Code стал хорош, может быть, несколько месяцев назад, поэтому это начало происходить только недавно, поэтому они рано или поздно выберутся из этой спирали. По крайней мере, я на это надеюсь. Знать наверняка мы не можем.
Зачем мы выполняем проверки
Итак, нам понятен симптом: в конвейере образуется пробка, потому что на этапе 1 создаётся слишком много нового кода. Но в чём первопричина этой пробки? Почему конвейер не становится быстрее?
Выше я сказал, что эта статья не про ИИ. Пока это неочевидно, поэтому давайте вернёмся к людям и к раздражающе верному наблюдению: каждый новый слой ревью медленнее в десять раз. Нам это известно. Возможно, раньше вы с этим не сталкивались, но поверьте мне: люди, занимающиеся проектированием организаций, знают, что слои обходятся дорого... однако они всё равно их создают.
В процессе роста компаний в них становится всё больше слоёв совместной работы, проверок и управления. Почему? Потому что в противном случае возникают ошибки, а с увеличением масштабов ошибки становятся всё болезненнее. Средняя польза, привносимая новой фичей, в итоге становится меньше, чем средняя потерянная польза из-за новых багов, вызванных этой фичей. Итак, если мы не можем сделать так, чтобы фичи повышали полезность (хотя было бы здорово!), мы хотя бы пытаемся снизить ущерб от них.
Чем больше проверок и контроля, тем медленнее мы двигаемся, но тем равномернее растёт качество. Разве это не фундамент непрерывного совершенствования?
Ну, более-менее. Равномерное повышение качества — это верный путь. Но из-за увеличения объёма проверок и контроля мы с него сбиваемся. Это единственный способ повышения качества, но он чреват последствиями.
Quality Assurance снижает качество
Несколько лет назад я писал об Уильяме Деминге и «новой» философии качества, которую он популяризировал в японском автомобилестроении. (Позже эту идею более-менее усвоили автопроизводители США, но не индустрия разработки ПО).
Один из подчёркнутых Демингом эффектов стала проблема этапа QA на заводе: создаём устройства, они проходят этап контроля качества/QA, бракуем устройства, не прошедшие QA. Разумеется, контролёры упустят часть сбоев, но если вы сомневаетесь, добавьте второй этап QA после первого, чтобы выявить оставшиеся, и так далее.
В упрощённой математической модели это вроде бы имеет смысл. (Например, если каждый этап QA отлавливает 90% дефектов, то после двух этапов QA вы снизите количество дефектов в 100 раз. Разве не здорово?)
Но в реальности живых людей не всё так просто. Во-первых, возникают странности с мотивацией. Второй отдел QA, по сути, должен оценивать качество работы первого; если первый отдел QA постоянно упускает дефекты, то его можно уволить. Но у второго отдела теперь мало мотивации подставлять своих коллег, поэтому, вероятно, они будут закрывать на что-то глаза; в конце концов, если первый отдел упустил дефект, то вполне логично, что и мы можем его не заметить.
Кроме того, теперь первый отдел знает, что второй отдел сможет отлавливать любые дефекты; если мы сегодня решим немного отдохнуть, то второй отдел будет на подхвате. Для этого ведь он и нужен!
При этом изготавливающий устройства отдел не будет особо тщательно проверять свою работу, ведь для этого есть контроль качества! Зачем тормозить производство каждого устройства, тщательно проверяя их и тратя при этом, скажем, на 20% больше времени, если останется всего 10 дефектов из 100, и мы сможем устранить их на следующем этапе, увеличив отбраковку всего на 10%? Это вполне логично. Плюс меня уволят, если я стану работать на 20% медленнее.
А уж о полной перепланировке устройства для повышения качества и говорить не стоит: она будет крайне дорогой и вместо неё можно спроектировать новые устройства.
Наверно, так ведут себя все известные вам отделы разработки?
Здесь стоит сказать, что методики Деминга сработали. Благодаря ним у нас есть, например, система производства Toyota, из которой полност��ю исключили этап QA, но выдали всем кнопку «чёрт, остановите линию, я обнаружил дефект!».
Известно, что автопроизводители в США пытались применить ту же систему, установив кнопки остановки линии. Разумеется, на эти кнопки никто не нажимал: все боялись, что их уволят.
Доверие
Основа системы, которая сработала в Японии, но не сработала в США — это доверие. Сотрудники должны верить, что их начальник на самом деле хочет знать о любых дефектах и хочет, чтобы они останавливали линию при их обнаружении. Руководители должны верить, что высшее руководство серьёзно настроено обеспечивать качество. Высшее руководство должно верить, что при наличии работающей системы и нужной мотивации сотрудники будут выполнять работу качественно и находить собственные дефекты, нажимая кнопку тогда, когда это нужно сделать.
Но нужна ещё одна вера: в то, что система действительно работает. Значит, сначала нам нужна система, которая работает.
Свойство ошибаться
ИИ-кодеры могут ошибаться; часто они пишут плохой код. В этом смысле они похожи на живых программистов.
В подходе Деминга к производству не было каких-то «серебряных пуль». Увы, нельзя просто реализовать его десятиэтапный процесс и сразу же повысить качество разработки. Секрет заключается в том, что ваши разработчики должны встраивать качество во всю систему, сверху вниз. Многократно и непрерывно.
Каждый раз, когда что-то идёт не так, нужно задаваться вопросом: «Как это произошло?», составлять целый постмортем с Пятью «Почему» (или тем количеством Почему, которое сегодня модно), а затем устранять Первопричины, чтобы этого не произошло снова. «Кодер ошибся» — это никогда не первопричина, а лишь синдром. Как так получилось, что кодер получил возможность ошибиться?
Задача ревьюера кода заключается не в ревью кода. Он должен разбираться, как избавиться от возможности появления его комментария, целого класса таких комментариев во всех будущих случаях, до тех пор, пока его ревью вообще больше не понадобятся.
(Вспомните о том моменте, когда изобрели go fmt, и о том, что после этого куча глупых комментариев о пробелах пропала навечно. Вот это настоящее проектирование.)
К моменту, когда ревью находит ошибку, ошибка уже совершена. Первопричина уже возникла, вы опоздали.
Модульность
Хотел бы я сказать, что у меня есть ответы на все вопросы, но на самом деле, их у меня не так много. Если бы они у меня были, я бы первым встал в очередь за сингулярностью, потому что теоретически выглядит она потрясающе.
Думаю, мы ещё очень долго будем сталкиваться с этими системными проблемами конвейеров. Конвейеры ревью (слои QA) не помогают. На самом деле, они замедляют работу, скрывая при этом первопричины. Из-за сокрытия причин их становится сложнее устранить.
Однако перспектива ИИ-кодинга выглядит очень привлекательно. Этот первый этап конвейера становится таким быстрым! Действительно кажется, что ты обрёл сверхспособности. Мне нужно больше сверхспособностей. И что нам делать с этим стремлением?
Возможно, у нас наконец появилось достаточно убедительное оправдание для устранения накопившихся за двадцать лет проблем, сокрытых культурой ревью кода, чтобы заменить их реальной культурой качества.
Мне кажется, оптимисты наполовину правы. Потребуется ограничивать количество этапов ревью, даже если это вызовет дискомфорт. Но нельзя просто избавляться от слоёв ревью, не привнеся вместо них чего-то ещё. Иначе мы получим новый Ford Pinto или самолёт Boeing.
Деминг привнёс в сферу производства концепцию в целом, полную замену подходов. Нельзя реализовать систему «тотального качества» наполовину. Необходимо за один шаг устранить ревью и сделать их ненужными.
Как? Можно полностью реализовать новую систему небольшими шагами. Что, если какие-то компоненты системы можно разрабатывать по-новому? Представьте американского автопроизводителя старой школы, покупающего детали у японских поставщиков: ого, эти детали такие качественные! Теперь можно начать избавляться от этапов QA на других участках, потому что мы допускаем, что эти детали будут работать, и в моей задаче сборки устройства из деталей я избавился от большой степени сложности.
Мне нравится такая точка зрения. Я всегда любил маленькие красивые вещи, это моя личная предвзятость. Но можно собирать большие красивые вещи из маленьких красивых.
Гораздо проще создавать эти отдельные красивые вещи в небольших командах, доверяющих друг другу и знающих, как выглядит качество для них. Они выпускают свои изделия для команд заказчика, способных чётко объяснить, что значит качество для них. И так можно двигаться дальше: качество начинается снизу и распространяется вверх.
Я считаю, что в этом новом мире очень хорошо себя будут чувствовать маленькие стартапы; возможно, даже лучше, чем когда-либо. У стартапов уже меньше слоёв ревью просто потому, что в них меньше людей. Некоторые стартапы научатся быстро создавать высококачественные компоненты, другие потерпят поражение и разорятся. Обеспечение качества как естественный отбор?
Более крупным компаниям придётся сложнее, потому что в них встроены медленные системы ревью, и избавление от них вызовет абсолютный хаос.
Но дело не только в размере компании. Я считаю, что команды разработчиков в любой компании можно сделать меньше и лучше сформулировать интерфейсы между ними.
Вероятно, можно создать в компании несколько команд, конкурирующих за выпуск одного и того же компонента. В каждой из них будет всего несколько человек и несколько кодинг-ботов. Пусть они попробуют сто способов и посмотрят, кто придумает лучший. Качество снова возникнет благодаря эволюции. Код дёшев, но хорошие идеи ценны. А сегодня можно пробовать новые идеи с беспрецедентной скоростью.
Возможно, мы найдём новый оптимум в спектре «монолиты-микросервисы». Микросервисы получили плохую репутацию из-за того, что они слишком «микро»; в исходной терминологии «микро»-сервис был подходящим размером для разработки и поддержки «командами на две пиццы». Может быть, с появлением ИИ это будет только одна пицца и горстка токенов.
Интересно то, что мы можем применять этот новый быстрый кодинг для ускорения экспериментов с разными границами модулей. По множеству причин с фичами пока всё сложно, зато ИИ замечательно справляется с рефакторингом и автоматизированным интеграционным тестированием. Попробуйте разделить модуль, который вы раньше боялись разделять. Может быть, при этом добавится несколько строк кода. Но строки кода внезапно стали дешёвыми по сравнению с оверхедом координирования крупной команды.
У каждой команды есть монолиты слишком большого размера и слишком большое количество слоёв ревью. Пусть мы не доберёмся до истинной сингулярности, но можем спроектировать гораздо более совершенный мир. Наши проблемы решаемы.
Для этого просто нужно доверие.
