Предистория
Последние пару лет, кажется, невозможно поговорить об ИИ в разработке, чтобы разговор не упирался в тему производительности.
Отовсюду постоянно вылезают новые истории успеха. Кто-то показывает, как сократил время разработки в несколько раз. Кто-то рассказывает, что теперь пишет за день столько кода, сколько раньше писал за неделю. Иные вообще собирают полноценный продукт за выходные и искренне не понимают, почему раньше на это уходили месяцы. Честно говоря – раньше читал, но в последнее время просто игнорирую такие заголовки (почему – надеюсь станет понятно из статьи).
В общем, начинает возникать ощущение, что индустрия наконец приближается к своей заветной мечте: программирование становится быстрее, а создание продукта дешевле и доступнее.
И мы, с моей командой тоже находимся в середине этого славного пути.
Сначала у нас появился Copilot. Потом Claude и GPT стали нормой в ежедневой работе как с IDE, так и с Git. В конце-концов мы остановились на Windsurf (вот уже больше полутора лет), который фактически берёт на себя заметную часть работы. Последним «писком моды» стало использование OpenSpec – от которого мы все, често говоря, просто без ума – добавили его в PHPStorm и результаты были мягко говоря… ошеломительные.
То есть, каждый следующий шаг, которым мы делали в испльзовании ИИ, был абсолютно логичным. Если модель хорошо пишет функции и тесты, почему бы не доверить ей написание не только юнит тестов, но API – тем более, что есть готовые рабочие (качественно написанные) образцы? Если она уверенно справляется с тестами, почему бы не поручить написание какого сервиса целиком? Если сервис получается качественным, то почему бы не попробовать написать уже целую фичу?
И вот, в какой-то момент для такого эксперимента у нас появилась идеальная возможность.
Как мы почти полностью создали функционал с помощью ИИ
Задача была вполне стандартной по сегодняшним меркам.
Нужно было создать чат-бота на базе RAG-архитектуры: загрузка документов из разных источников, индексация, хранение эмбеддингов, поиск контекста, re-ranking, работа с LLM, интерфейс, валидация результата, история диалогов – ничего экзотического.
Я решил посмотреть, насколько далеко можно зайти, если максимально использовать современные инструменты генерации кода.
Большая часть системы создавалась через Windsurf с моделью GPT-5 Low Thinking Pro с использованием OpenSpec (всё писалось на PHP под сильно кастомизированный фреймворк Yii).
Конечно, код генерировали не только токены – команда тоже не сидела сложа руки. Она формулировала требования, уточняла детали, ребята исправляли ошибки, направляли процесс. Но если быть честным до конца, многие архитектурные решения появлялись сначала в ответах модели, а уже потом становились частью функционал.
Самое удивительное – это работало. Причем работало настолько хорошо, что временами становилось не по себе.
То, что раньше требовало многих дней обсуждений, проектирования и реализации, теперь появлялось буквально за часы. Сначала мы получили прототип. Затем первую рабочую версию. Потом модуль с нужным функционалом, которым уже можно было пользоваться без ощущения, что он собран на скорую руку.
Если бы тогда кто-то спросил меня, считаю ли я эксперимент успешным, я бы ответил без малейших сомнений: да, абсолютно.
Но спустя некоторое время я начал задавать вопросы.
Вопросы, на которые неожиданно оказалось сложно ответить
Через какое-то время я начал задавать команде обычные вопросы.
Почему вы выбрали именно такой способ индексации? Почему решили хранить эмбеддинги именно так? Почему такой размер? А модель? Как мы будем масштабировать систему, если данных станет в десять раз больше?
Хорошим примером оказалась работа с эмбеддингами.
Для хранения векторов GPT предложил использовать pgvector поверх PostgreSQL. Решение выглядело вполне разумным: оно быстро внедрялось, не требовало дополнительной инфраструктуры и отлично работало на наших объёмах данных.
Мы приняли эту рекомендацию практически без обсуждений.
Но позже я задал команде простой вопрос: почему pgvector, а не отдельный векторный движок вроде Qdrant или Milvus? В какой момент PostgreSQL перестанет справляться? Какие ограничения мы получим при росте объёма данных?
И неожиданно оказалось, что на эти вопросы никто не мог ответить достаточно уверенно.
Не потому, что решение было плохим. Наоборот – вполне возможно, что для наших задач оно было оптимальным. Проблема была в другом: мы не пришли к этому выбору самостоятельно. Мы просто приняли первую качественную рекомендацию модели.
Главное здесь – я не пытался никого поймать на ошибке. Мне просто хотелось понять, как команда рассуждала, когда принимала эти решения.
Вы знаете как это происходит в реальной жизни…
Обычно за такими вещами стоит какая-то история. Сначала пробовали один подход, потом столкнулись с ограничениями, потом спорили, сравнивали варианты и в итоге пришли к решению.
Но в первом варианте такой истории не было вообще. Точнее, она была у модели, но не у команды.
Команда хорошо понимала код. Любой мог открыть нужный файл и… через некоторе время объяснить, как он работает. Проблема была не в этом.
Проблема была в том, что многие решения как будто появились сразу в готовом виде. команда не проходила через несколько плохих вариантов. Не успевала набить шишки. Не спорила достаточно долго, чтобы по-настоящему понять цену каждого компромисса.
ИИ предлагал разумный вариант, все видели, что он выглядит хорошо, и двигались дальше.
Я тогда понял для себя: понимать готовое решение и прийти к нему самому – это не одно и то же.
Иллюзия, которая возникает слишком легко
Есть одна ошибка, в которую очень легко попасть.
Когда инженеру показывают хороший кусок кода, он может быстро разобраться в нём и подробно объяснить, что и почему там происходит. После этого появляется ощущение, что написать такой код самому было бы несложно.
Но это ощущение часто обманчиво.
Мне это напоминает шахматы.
Когда гроссмейстер показывает красивую комбинацию, она кажется почти очевидной. Смотришь на доску и думаешь: «Да, логично. Я тоже мог бы до этого додуматься».
Но если убрать подсказку и дать ту же позицию без готового ответа, всё выглядит совсем иначе. Найти правильный ход самостоятельно оказывается гораздо сложнее.
Потому что понимать готовое решение и создавать его с нуля – разные вещи.
В разработке работает тот же принцип.
Разобраться в существующей архитектуре обычно проще, чем придумать её самому. Найти слабые места в решении легче, чем предложить действительно хорошую альтернативу. Проверить чужую работу проще, чем сделать её с чистого листа.
Это просто разные виды интеллектуальной работы, требующие разных навыков. Разных!
Почему я решил что нужно переписать то, что уже работало
Я задал себе прямой вопрос: а вырастут ли вместе с этим проектом мои программисты как инженеры?
И, увы, у меня уже не было уверенного ответа.
Тогда я принял решение, которое команда сначала приняла «в штыки». Я решил, что для них, как для инженеров, будет лучше переписать значительную часть проекта практически с нуля.
Сразу уточню важную вещь. Переписывание не означало, что мы выбросили уже сделанную работу и начали всё заново ради самого процесса.
Первая версия проекта осталась с нами. Она стала рабочим прототипом, эталоном поведения системы и, если хотите, своеобразной картой местности. Мы уже знали, какие решения работают, какие компоненты нужны и как должен выглядеть результат.
Фактически мы сохранили полученное знание, но решили заново пройти путь принятия ключевых инженерных решений. Нас интересовал не только готовый код, но и понимание того, почему именно этот код появился таким, а не другим.
То есть, мы это сделали не потому, что первая версия была неудачной. Не потому, что GPT где-то ошибся. И точно не потому, что я разочаровался в ИИ.
Скорее наоборот. Этот опыт окончательно убедил меня, что такие инструменты пришли надолго и со временем будут становиться только лучше.
Причина была совсем в другом.
Мне хотелось вернуть в разработку то, что постепенно и почти незаметно начало исчезать – самостоятельное инженерное мышление.
Когда ИИ перестал быть автором
Во второй версии проекта GPT никуда не исчез.
Мы переписали проект практически с нуля, используя как подсказку первую версию, полностью сгенерированную ИИ.
Да, где-то это даже напоминало старый стиль работы со stackoverflow, но код и структура проекта была написана живыми людьми, часть кода была сознательно упрощена, часть переписана. Даже имена переменных кое-где были заданы более «человеческим» стилем.
То есть, мы по-прежнему активно использовали ИИ в работе: обсуждали разные варианты реализации, разбирали идеи, изучали готовые подходы и просили посмотреть на наши решения со стороны.
Но теперь его роль изменилась. GPT больше не был тем, кто принимает решения.
Он стал помощником, с которым можно посоветоваться. Собеседником, иногда – оппонентом, который предлагает совершенно другой взгляд на проблему. А вот финальное решение всегда оставалось за командой. И в процессе переписывания проекта начали происходить самые интересные вещи.
Например, некоторые решения из первой версии вообще не пережили вторую.
В первой реализации мы практически без обсуждений приняли предложенный ИИ способ организации нескольких частей RAG-конвейера. Он работал и выглядел вполне разумно. Но когда начали проектировать систему самостоятельно, быстро выяснилось, что часть этих решений команда не смогла убедительно защитить даже перед собой.
Появились вопросы, которых раньше никто не задавал. Что произойдёт при десятикратном росте объёма документов? Где будут узкие места? Какие компоненты действительно нужны, а какие появились просто потому, что так предложила модель?
Некоторые решения в итоге остались без изменений. И это оказался лучший аргумент в пользу переписывания. Теперь команда могла объяснить не только то, как эти решения работают, но и почему были выбраны именно они.
Другие были упрощены или полностью заменены. Не потому, что первая версия была плохой, а потому, что теперь за каждым выбором стояло собственное понимание компромиссов.
Конечно же, разработка, заняла больше времени, чем генерация кода с ИИ.
Но… Вернулись обсуждения архитектуры. Снова появились проблемы, хотя на их решения уже уходили не дни, а гораздо меньше (всегда можно было подсмотреть на первый вариант). Некоторые идеи казались удачными, а некоторые приходилось полностью выбрасывать и начинать заново.
Появились тупики, споры и сложные компромиссы.
Все то, что программисты обычно считают самой неприятной частью своей работы.
Но я был доволен: я видел как в этих моментах и происходило настоящее профессиональное развитие. Не тогда, когда за тебя быстро находят ответ, а тогда, когда приходится искать его самому.
Где на самом деле растет инженер
Чем дольше я работаю в индустрии, тем меньше верю в то, что инженер растет просто потому, что пишет код.
Мне кажется, настоящий рост происходит в другие моменты.
Он начинается тогда, когда человек сталкивается с последствиями собственных решений. С результатами того, что он создал ранее.
Например, когда архитектура, которая сначала казалась удачной, вдруг перестает масштабироваться. Или когда выбранный подход упирается в ограничения, о которых раньше никто не думал.
Иногда приходится признать, что красивое решение на практике оказалось неправильным. Иногда после нескольких дней работы нужно удалить половину написанного и начать заново.
Я думаю, что именно в такие моменты и формируется инженерное мышление.
Не во время успешного релиза. Не после очередного коммита. И точно не тогда, когда просто нажимаешь кнопку Approve.
А тогда, когда приходится разбираться, почему решение не сработало, и искать новый путь.
Что будет с джунами
Если честно, будущее опытных программистов волнует меня не так сильно.
Скорее всего, они адаптируются без особых проблем.
Для сильного специалиста ИИ становится просто еще одним инструментом. Он помогает быстрее изучать новые подходы, быстрее писать рутинный код и быстрее проверять идеи.
Но все ключевые решения по-прежнему принимает сам инженер.
Гораздо интереснее то, что происходит с новичками.
Раньше путь развития был довольно непростым. Человек писал код, допускал ошибки, получал замечания на ревью (бывало десятками за раз), переделывал решение и снова ошибался. Через этот процесс постепенно приходило понимание того, как принимать хорошие инженерные решения.
Сегодня этот путь начинает меняться.
Очень часто GPT сразу предлагает решение, которое выглядит вполне рабочим. Сеньор оставляет несколько комментариев, задача закрывается, и команда движется дальше.
Для продукта это может быть отличным результатом. Работа выполняется быстрее, а компания получает нужный эффект.
Но становится ли при этом сильнее сам инженер? Я не знаю.
Возможно, мы только начинаем понимать, как меняется процесс обучения в эпоху ИИ. И пока непонятно, поможет ли это новичкам расти быстрее или, наоборот, лишит их важной части опыта, через которую раньше проходил практически каждый разработчик.
Поэтому я думаю, что главный вызов ближайших лет связан не с тем, научится ли ИИ генерировать код лучше человека.
Главный вопрос в том, как сохранить и развивать инженерное мышление в мире, где готовые ответы становятся доступнее с каждым днем.
Возможно, через несколько лет мы обнаружим, что научились создавать продукты гораздо быстрее. Но пока я не уверен, что мы научимся так же быстро выращивать инженеров.
И именно этот вопрос мне кажется сегодня самым важным!
ссылка на оригинал статьи https://habr.com/ru/articles/1046269/