(hm) Human made
My current strategy is to not read any of the code written by my agents.
Robert Cecil Martin
В этом году, похоже, мы уже окончательно перешли на кодирование с ИИ, и назад дороги нет. Лично у меня ИИ отобрать будет сложно — крепко на него подсел. Но вот что я до недавнего времени никак не мог понять: почему одни разработчики утверждают, что теперь весь код за них пишет ИИ и им вообще не приходится ничего делать, в то время как другие настаивают на том, что ИИ — это лишь помощник и код за ним надо тщательно проверять. А есть и такие, кто в ИИ полностью разочаровался и, по их словам, использует его скорее как справочник, чем полноценный инструмент для разработки. Ладно бы только это. В начале октября некий Брэндон Томас (для меня некий — я вообще раньше о нем не слышал) выкатил в общий доступ свой проект ArtCraft, в котором он, по сути, воспроизвел все популярные редакторы от MS и Adobe (от Word до Photoshop). Хоть стой, хоть падай, короче. Кажется, что индустрия рванула куда-то вперед, а ты вцепился в поручень отходящего поезда и изо всех сил стараешься не разжать пальцы. Хуже того. Ты наблюдаешь, как товарищи по несчастью спрыгивают на ходу, не выдерживают, сдаются. Печаль.
Однако меня так просто не стряхнуть и сдаваться я не спешу. Слишком уж много я видел таких “уходящих поездов” за свою жизнь, чтобы поддаваться панике. Тут важно разобраться в происходящем. Не получается — передохнуть и попробовать снова. Нынешняя ситуация необычна тем, что все меняется так быстро, что на передышку времени почти нет. Но что точно есть — это противоречивость поступающей информации. И, казалось бы, попробуй и сам все поймешь. Попробовал, понял. Но почему мои впечатления так сильно контрастируют с оными у других разработчиков? Это никак не давало мне покоя.
И вот совсем недавно кое-что произошло. Я послушал несколько очередных подкастов, где разработчики с совершенно разным опытом рассуждали в формате не интервью, а обычной беседы о том, как они используют ИИ, о своих проблемах и впечатлениях, — сейчас этого в сети навалом. Но тут, после очередного подкаста, у меня в голове что-то щелкнуло и некоторые вещи внезапно встали на свои места. Вдруг я понял, что некоторые программисты пишут код ровно так, как я это делал четверть века назад. И, мысленно переместившись в те ламповые времена, осознал, что если бы ИИ появился тогда, то я говорил бы точно так же и использовал бы те же самые эпитеты в отношении него. Я был бы от ИИ в полном восторге! И точно бы не стал мешать ему писать код.
Прыжки
И что же такого я вспомнил? Я вспомнил, как я пытался писать программы как бы “в лоб”, “с наскоку”. Не в том смысле, что за один день, — не настолько маленькими были мои проекты. В то время Кент Бек еще не написал свою книгу по XP, а все, что я знал о проектировании, — это стандартны вроде IDEF0. Мой подход работал, но до какого-то момента. А затем — стена. Я тогда еще не понимал, что это такое, во что я каждый раз упираюсь. Мне потребовалось несколько лет, чтобы найти нужную литературу и разгадать эту загадку. Моя разработка выглядела как “прыжок” вверх, когда, достигнув некой верхней точки, я неизменно падал назад и начинал все сначала. Я менял подход, архитектуру и прыгал чуть выше. Использовал библиотеки, которые забирали часть работы на себя, позволяя еще немного поднять планку. Тогда я решил подойти к вопросу системно. В стране (1998 г.) начала появляться зарубежная современная литература, в том числе та самая книга Грэди Буча, которая изменила все. С самых первых страниц эта книга в точности описывала мою боль. А дальше — как с ней бороться. Сначало было не очень понятно. Но потом словно открылся третий глаз, снизошло какое-то озарение. Для себя я это назвал “шифтом” (у меня их было несколько). Мозг словно перестроился, появился взгляд на все как бы со стороны, все стало кристально ясно. Остальное — технические детали (их хорошо описали Бек, Ларман, чуть позже Фаулер, потом — Дядя Боб). И все писали про “архитектурный предел”, “когнитивный барьер”, “лимит ментальной емкости”. Но самое главное, я понял, как этот барьер преодолеть или как минимум отодвинуть достаточно далеко, чтобы он не мешал. Это как достичь первой космической — ты больше не падаешь назад.
С тех пор я почти никогда не начинаю проекты заново. В этом просто нет смысла. Всегда можно перестроить, переделать. Мне больше не нужно все с самого начала продумывать до мельчайших деталей. Достаточно иметь под рукой хорошую метафору и просто ставить цели. Одну за другой. Примерно так описывает разработку Бек.
Зачем я все это рассказываю? Дело в том, что ИИ может “прыгать”. Он прыгает лучше всех и выше всех. Для разработчика, который пишет код подобным образом, это что-то недостижимое. Перепрыгнуть ИИ нельзя. Он в этом лучший. Он — чемпион. Он может прыгнуть, сделать в верхней точке сальтуху и прыгнуть еще чуть-чуть выше. И такой код не то, что можно не читать, его в определенный момент читать бесполезно. Человек упирается в свою стену сложности, которую ему не преодолеть. У ИИ она заметно дальше. И вот тогда мы слышим в очередном подкасте что-то вроде “я больше не пишу код сам”, “я не смотрю то, что пишут мои агенты”, “ИИ пишет весь код на нашем проекте”, “писать код руками — прошлый век” и т.п.
Плоское ПО
И что не так? Чтобы ответить на этот вопрос, нам нужно взглянуть на структуру программы под определенным углом. Возьмем простой пример — школьную задачку, где нам надо создать калькулятор, вычисляющий арифметические выражения вроде “1 + 2*3”. Основная нагрузка здесь ложиться на парсер. Само вычисление тривиально. Разбор выражения можно назвать ключевой фичей нашего решения, его ядром. Немного усложним ядро и добавим в него вызов функций. Теперь мы можем работать с выражениями вроде “1 + exp(2, 3)”. И вот тут происходит магия: не меняя ядро, мы способны добавить в нашу программу почти неограниченное количество функций. Кодовая база может стать огромной, миллионы строк кода. При этом ее сложность останется на уровне школьной задачи.
В данном примере функции — это противовес ядру, аддитивная часть (расширения, плагины и п.р.). Уверен, что большинство ваших программ можно описать подобным образом (базовый архитектурный паттерн). Аддитивная часть может, в свою очередь, тоже состоять из пространства “ядер”, но сути это не меняет: ближайший барьер сложности будет у самого крупного ядра.
Теперь, складывая все вместе, несложно прийти к выводу, что если высоты прыжка достаточно, чтобы “перепрыгнуть” самое большое ядро в программе, то описанный ранее подход написания кода вполне оправдан. Более того, так можно писать большие программы. Ядро VS Code, к примеру, совсем небольшое по сравнению с его окружением. Тем не менее, в нем нет некоторых возможностей, которые можно назвать базовыми для подобного ПО… Может, поэтому и нет?
Объем
А что, не все программы такие? Почти все, только вот не у всех программ маленькое ядро (например, у ОС). Большие ядра пишутся иначе. Они набирают вес в ходе тысяч итераций. Я бы сравнил это с наматыванием лески на катушку бесконечной длины. И вот именно тут с ИИ возникает проблемка: он может “мотать леску”, но делает это так, что она быстро запутывается и на горизонте начинает материализовываться тот самый барьер, приобретая очертания пятой точки. В норме перед внесением изменений проводится рефакторинг разного уровня сложности для придания коду нужной “эластичности”. И только потом на подготовленную почву аккуратно укладывается фича. Это как полку в квартире повесить: ее можно просто прибить гвоздями, а можно установить в стену дюбели и прикрутить полку к ним. Не сложно догадаться в каком случае полка провисит дольше. В некоторых случаях требуется более серьезная подготовка вплоть до перепланировки. Так вот ИИ ничего такого не делает, он все “прибивает гвоздями”. Как его ни уговаривай. Все бестолку. У хорошего кода обычно есть некоторый запас эластичности — ИИ его моментально съедает и только за счет этого способен что-то сделать.
Так, может, ему надо просто объяснить, добавить нужные скилы? Нет, он прекрасно знает что такое рефакторинг, он прочел про него все книги. Он просто его не делает. Не распознает момент, когда он нужен. Оказывается, знать и делать не одно и то же. Скажу больше, не все можно описать словами.
Здесь очень показательна история Ботвинника (это чемпион мира по шахматам и по совместительству — доктор наук). Он поставил перед собой амбициозную цель: формализовать все свои знания и опыт в шахматах и записать их в виде алгоритмов. Т.е. создать программу, которая будет играть на его уровне. Не смог. Не формализовал, не создал. Выяснилось, что это неимоверно сложно. Опыт можно передать лишь частично, и одних слов тут недостаточно.
Языковые модели — довольно посредственные шахматисты… ИИ надо специально тренировать. Как тренировали в свое время AlphaGo. С рефакторингом все то же самое. ИИ решает задачи в лоб: делает врезки, вставки, россыпи ветвлений — без каких-либо попыток сохранить выразительность и стиль кода, удержать барьер на том же расстоянии. Нет, даже не пытается. И именно поэтому мы слышим от некоторых разработчиков, что “ИИ слабоват”, что “за ним нужен глаз да глаз”. Так что, похоже, противоречий никаких нет — правы и те, и другие.
Все сильно зависит от проекта и подхода к разработке. В одних случаях можно полностью положиться на ИИ и лишь контролировать конечный результат. В других — ни в коем случае не оставлять ИИ одного и все за ним перепроверять. Лично для себя я склоняюсь ко второму варианту, т. к. для меня важно выявить потенциальную проблему как можно раньше, чтобы снизить цену ее исправления. Но теперь и у самого такого контроля появилась цена. С другой стороны, цена есть и у абсолютного доверия ИИ, и цена эта может быть огромной. Лишь время покажет, кто был прав.
Возможно, дело не столько в том, насколько хорошо ИИ пишет код, сколько в том, какую сложность мы способны с его помощью удерживать под контролем.
ChatGPT
Фантастическое время.
Автор: wetnose


