📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

SO MANY Junior Developers Are Using AI Wrong

Eric Roby20:09

Transcription

При использовании инструментов ИИ для кодирования появляется новая философия построения программного обеспечения. Она называется разработкой, управляемой спецификациями. И вот почему это важно. 84% разработчиков используют инструменты ИИ прямо сейчас. Только 29% из них доверяют результату. Разрыв между этими двумя цифрами — это не проблема инструментов. Это не проблема модели. Это не проблема того, что эти агенты должны быть умнее. Это проблема спецификации. Узким местом в разработке с помощью ИИ больше не является модель. Да, модель продолжает становиться все лучше и лучше, но реальным узким местом является то, насколько четко вы можете описать, что хотите, прежде чем агент напишет хоть одну строку кода. Я занимаюсь этим последние несколько месяцев, наблюдая, как люди, которых я действительно уважаю, сокращают разрыв между использованием этих инструментов и выпуском продуктов с их помощью. И шаг, который они делают, всегда один и тот же. Это не лучшие подсказки, это спецификация, которая находится рядом с кодом до того, как агент даже запустится. Сегодня я проведу вас через то, что именно такое разработка, управляемая спецификациями, почему это не PRD, и уж точно не документ по дизайну. Это рабочий процесс, который я использую последние несколько месяцев, и который фактически превратил мой результат из «почти правильно», что является самым опасным типом результата, в «готово». Итак, давайте приступим. Итак, позвольте мне фактически определить, что такое разработка, управляемая спецификациями, потому что это тема, о которой многие слышали, но существует несколько ее определений. Разработка, управляемая спецификациями, — это рабочий процесс, который разработчики используют для сокращения этого разрыва между 84% и 29%, о котором я упомянул выше. Идея в целом проста. Прежде чем ваш ИИ-агент сгенерирует хоть одну строку кода, вы пишете краткую спецификацию, которая точно говорит ему, что строить, что не строить и как проверить то, что он построил, когда закончит. Спецификация хранится в вашем репозитории рядом с вашим кодом в папке под названием specs. Агент читает ее перед тем, как сгенерировать что-либо еще. И каждое исправление, которое вы вносите в кодовую базу, вы вносите в спецификацию, а не в код. Сама спецификация становится источником истины. Код — это просто артефакт, который произвела спецификация. Это и есть вся методология. Агент читает спецификацию. Затем агент строит на основе спецификации, а затем вы просматриваете ее, и в конечном итоге выпускаете. И это то, что я вначале как бы игнорировал, но теперь начинаю относиться серьезно. И это потому, что разработка, управляемая спецификациями, — это не функция Claude Code. Это не функция Cursor. Это не функция Codex. Это рабочий процесс, который работает поверх всех них. И когда вы понимаете рабочие процессы, которые работают поверх всех них, вы не зависите ни от одного из них. И доказательством того, куда это движется, является то, что крупнейший поставщик облачных услуг в мире буквально только что создал полностью интегрированную среду разработки, построенную на этой точной методологии. И если мы просто хотим продолжать с «и», а рынок инструментов ИИ продолжает расти. Это хорошая новость. Спецификация работает в Claude сегодня. Завтра она может работать в Codex. Она может работать в чем угодно в будущем, потому что каждый агент кодирования на рынке, независимо от того, кто его создал, читает файлы markdown в вашем репозитории перед генерацией кода. Это универсальный интерфейс. И еще кое-что, прежде чем мы углубимся в тему. Разработка, управляемая спецификациями, меняет то, как на самом деле работает разработка программного обеспечения. Старая работа заключалась в том, что вы читали задачу Jira, держали требования в голове, писали код, затем тестировали его, а затем выпускали. Навык заключался в том, чтобы довести код до производства. Результатом был код. Ваша работа сейчас с ИИ-агентами, верно? Наша, наша работа поднимается на уровень выше. Вы читаете требования, пишете точную спецификацию, передаете ее агенту, просматриваете результат по сравнению со спецификацией, и код теперь находится ниже по течению от спецификации. Итак, с учетом этой рамки, позвольте мне показать вам ловушку, которая заставляет ИИ и разработку, управляемую спецификациями, казаться несколько ненадежными, но в то же время казаться почти слишком хорошими, чтобы быть правдой. Итак, одна из самых неудобных вещей, с которыми я сталкивался при работе с кодированием с помощью ИИ за последний год, заключается в том, что с неправильным кодом на самом деле легче иметь дело, чем с почти правильным кодом. Неправильный код вы можете выбросить. Вы знаете, когда он неправильный, вы можете начать заново. Почти правильный код — это код, о котором вы на самом деле не знаете, что он неправильный. И вот некоторые данные, подтверждающие это. Например, опрос Stack Overflow 2025 года среди разработчиков показал эту цифру. 66% разработчиков говорят, что их самое большое разочарование в ИИ заключается в том, что код почти правильный, но не совсем. И 45% разработчиков в том же опросе заявили, что отладка кода, сгенерированного ИИ, занимает больше времени, чем просто написание его самостоятельно. Я создавал конечную точку API для довольно технического ответа, где значения базы данных нужно было рассчитать, а затем мне нужно было выполнить некоторую конкатенацию данных для новых значений. Это было довольно запутанно. Поэтому я смотрел на тестовые данные в документе, которые оказались неверными. Тестовые данные были неверными, потому что ИИ создал тестовые данные для того, кто их вставил в задачу. Когда я пошел реализовывать тестовые данные, они структурно не соответствовали тому, что было нужно. Мы обнаружили это только после того, как задача была уже завершена. Теперь большие языковые модели смогли создать это быстрее, вы знаете, я переделывал эту задачу быстрее, чем если бы я начал с нуля, но и я мог бы задать больше вопросов заранее. Но мы попадаем в этот круг, эту рутину, когда люди, которые создают задачи, используют большие языковые модели. Люди, которые занимаются фронтендом, создают большие языковые модели. Люди, которые занимаются бэкендом, используют большие языковые модели. И теперь мы пытаемся соединить их все с помощью трех разных сессий, где определение того, что нужно было создать, было утеряно в процессе. И исправление этого находится выше по течению от подсказки, верно? Исправление находится полностью выше по течению от агента. И исправление, чтобы не потерять источник истины, находится в разработке, управляемой спецификациями. Теперь, да, могли ли мы сделать что-то иначе? Конечно, лучшие подсказки могли бы сработать, но только до определенного момента. У подсказок есть потолок, и как только вы достигаете этого потолка, вы больше не пишете, чтобы улучшить подсказку. Вы начинаете пытаться втиснуть документы по дизайну в сообщение чата и просто надеетесь, что агент извлечет правильную структуру из предложений. Недопонимание, о котором я говорил выше, вызвано разрывом в понимании, верно? Это разрыв в спецификации. Разрыв — это население людей, говорящих, что они сталкиваются с проблемой при выпуске кода. Технический директор AWS назвал это «долгом верификации». Каждая непроверенная строка — это небольшой кредит, который вы берете против своего будущего времени. И при построении спецификаций вы не хотите просто иметь их в подсказках. Вы хотите, чтобы они были в своих собственных файлах, потому что сообщение чата — это просто неправильный контейнер для выбора для вашего программного обеспечения или архитектурных решений. Вы не можете втиснуть в чат-бот ограничения и функции, поведенческие спецификации и просто несколько абзацев, которые вот-вот потеряются. И контейнер просто слишком мал и слишком трудно вернуться к нему. Информация утекает. Агент заполняет пробелы тем, что он видел больше всего в обучении. А обучающие данные — это не ваша кодовая база. В разработке, управляемой спецификациями, вы все еще можете иметь несколько сессий, работающих одновременно, даже если они все полностью изолированы и полностью работают в разных рабочих деревьях, потому что речь идет скорее об одном источнике истины в вашей среде кодирования, с которым сравниваются ИИ-агенты. И эти файлы, документы, если хотите, отличаются от исходных документов, к которым мы привыкли для программного обеспечения. PRD, технический документ по дизайну, спецификация ИИ. Все это служит разным аудиториям с разными задачами. Они не взаимозаменяемы. И попытка сделать один документ для всех трех — это главная причина, по которой разработка, управляемая спецификациями, идет наперекосяк при первой попытке или не может быть реализована правильно. Сама спецификация ИИ также не является одним документом, верно? Спецификация ИИ, которую мы используем для разработки, управляемой спецификациями, также не является одним файлом. Это действительно три разных файла. И каждая папка имеет свою собственную функцию со своей собственной специфической структурой. Теперь структура этих элементов будет включать файл requirements.md, файл design и файл tasks.md. Итак, всего три файла. Каждый имеет свою задачу. Каждый имеет свою структуру. Вместе они заменяют обмен сообщениями в чате с помощью подсказок, что очень полезно, потому что теперь у вас есть источник истины в файлах, к которым вы можете вернуться в разных сессиях, вместо того, чтобы полагаться на одну подсказку. Теперь агент сначала прочитает требования, чтобы понять, что на самом деле нужно пользователю. Затем он прочитает дизайн, чтобы понять, как должна работать система, а затем он прочитает задачи, чтобы знать, что делать дальше. Теперь давайте быстро перейдем в мою IDE, чтобы мы могли увидеть, как выглядит каждый файл. Итак, теперь я проведу вас через реальный пример разработки, управляемой спецификациями, и расскажу о том, что она для нас построила. Итак, я создал то, что называется notify deck, что просто является способом отправки уведомлений нашего приложения. Для этого мы использовали websockets, fast API и superbase. Итак, superbase — мой предпочтительный выбор для этого, потому что он уже имеет аутентификацию, реализованную в базе данных, и у него есть база данных, которую мы называем notifications, где мы сохраняем все наши уведомления. Итак, мы можем видеть прямо сейчас, если мы зайдем в наш редактор таблиц, нет сохраненных уведомлений. Я уже вошел в систему как мой пользователь. И я хотел сделать так, чтобы, когда вы вошли в систему, если websocket достигнет этого пользователя, он уведомит нас, например, уведомлением здесь, а затем сообщит нам внутри, что говорит уведомление. И для этого я просто создал терминал, где мы можем отправить POST-запрос на мой localhost:8000/notifications. Мы отправим его на hi@codingwithroby.com, который в нашей базе данных superbase является одним из пользователей, hi@codingwithroby.com. У нас также есть friend@codingwithroby.com. Тип будет comment. Мы отправим «новый комментарий к вашему посту» с телом «отличный отзыв». И давайте переключимся на это и отправим одновременно, потому что мы увидим уведомление в реальной жизни, что если мы отправим это, бум, оно прошло, и мы видим, что получили одно. Если мы сделаем это снова, бум, два. Если мы зайдем сюда и изменим заголовок, так что, возможно, я могу сказать, например, «новый комментарий к вашему сообщению!» Бум. Три. Мы видим, как они приходят. И мы видим первый, второй и третий. И что круто, если мы вернемся в нашу базу данных на Supabase и зайдем в наш редактор таблиц здесь, мы увидим три уведомления, которые все связаны через websocket. Итак, как мы построили это приложение? Ну, я использовал практики разработки, управляемой спецификациями, которые мы рассмотрели, а именно requirements.mmd, который точно расскажет нам, как построить это приложение. Итак, мы говорим, что мы будем использовать websockets для этого живого канала, и мы скажем, что нам нужен этот критерий приемки, что пользователь должен войти в систему, а затем, нам нужен этот критерий приемки, что уведомления должны поступать в реальном времени, используя websockets, как мы будем передавать это, и мы перечисляем все требования здесь. После того, как мы создадим требования, мы переходим к дизайну. Теперь дизайн просто говорит нам, как мы будем интегрировать или разрабатывать это приложение. Итак, у нас есть наш внешний HTTP-клиент, которым будет fast API с post notifications, а также у нас будет этот websocket с менеджером соединений. Вставка сохранит его в нашей базе данных, нашей базе данных superbase, а затем мы отправим его на нашу панель управления Nest.js, и она расскажет нам, как мы можем подключить наш JDT. Как мы можем аутентифицироваться на основе websocket, как мы можем убедиться, что приложение fast API будет связано с приложением Nest.js, и как мы можем сделать это в реальном времени. У нас также есть наша логика бэкенда и фронтенда с нашими моделями базы данных, и у нас все перечислено здесь в нашем дизайне, а затем tasks — это просто то, как мы будем это настраивать, начиная с шага первого. Итак, первый шаг — настроить проект superbase в схеме. Затем нам нужно сохранить демо-пользователей. Затем нам нужно проверить JWT Superbase и fast API, потому что мы используем аутентификацию superbase. Затем нам нужно реализовать, знаете ли, менеджер соединений для каждого пользователя, раскрыть websocket, сделать все, а затем мы просто просим cloud code реализовать это на основе спецификаций, которые мы создали здесь, и окончательный пример, который мы получили, — это приложение, и это заняло около 50 минут работы, но оно сделало это полностью с первой попытки. Так что это очень хороший пример разработки, управляемой спецификациями, и того, как она может помочь вам создавать лучшие приложения. Теперь, одна вещь, которую всегда следует помнить об агентах, заключается в том, что агенты нетерпеливы, верно? Они хотят быть полезными, верно? Теперь они хотят быть тщательными. И поэтому они с готовностью добавят кучу всего в ваш продукт, будь то правильно реализовано, избыточно спроектировано, возможно, недостаточно спроектировано в некоторых случаях. Они просто с готовностью строят. Вот почему вы также должны добавить в свой документ спецификации список того, что не следует строить. Это сильно помогает при попытке заставить агента построить правильную вещь. И это то, во что я постоянно попадаю, потому что я хотел что-то построить, и я просто не буду достаточно четким или не буду достаточно явным. Я заставлю ИИ-агента, знаете ли, более или менее исследовать код для меня и придумать собственное решение. Теперь, когда ИИ-агент делает это, это работает очень хорошо для простых реализаций, таких как шаблонный код или вещи, которые есть повсюду в Интернете и которые делались много раз, или, знаете ли, даже если это пошаговый процесс, который находится в каком-то роде, знаете ли, линейной прогрессии. Но это также может быть очень вредно. И вот почему так важно следовать спецификациям при желании внедрить новые вещи в вашу кодовую базу, потому что буквально тот же агент, та же модель, тот же контекст, если вы упакуете их в разные сессии, они могут дать совершенно разные результаты. И вот почему разработка, управляемая спецификациями, так полезна, потому что она помогает установить ограждения для каждой из этих сессий, чтобы надеяться построить что-то похожее и помочь вам приблизиться к стадии завершения, а не к стадии «почти правильно». Если вы не добавите список того, что не следует строить, вы фактически даете ИИ-агенту разрешение строить что угодно. Это своего рода его стандартное, знаете ли, присутствие, верно? Каждое ограничение, которое вы добавляете в файл дизайна, — это степень свободы, которую вы отнимаете у интерпретации агента. Спецификации без явных разделов «вне сферы действия» по сути просят модель сгенерировать как можно больше, чтобы завершить свое предположение о задаче, которую вы хотите завершить. Они строят именно то, что вы просили, насколько им известно. Ничего больше и ничего меньше. И теперь здесь есть различие. Предприятия, управляемые спецификациями, о которых я говорил вам раньше, о AWS, которая создала IDE на основе спецификаций, думает. Не каждая спецификация предназначена для новой функции. Некоторые спецификации предназначены для исправления ошибок. И структура достаточно отличается, что вы, вероятно, должны использовать разные шаблоны, независимо от того, занимаетесь ли вы разработкой ошибок или функций. Спецификация функции состоит из трех файлов. Она включает требования, дизайн и задачи. Это то, через что я только что провел вас. Это шаблон, к которому вы обращаетесь, когда пытаетесь построить что-то новое. Спецификация исправления ошибки немного отличается. Я обычно называю ее просто bugfix.md. Она имеет другую структуру, потому что задача немного отличается. Вы не собираете требования с нуля, как при разработке функций. Вы описываете уже то, что сломано, что должно произойти вместо этого и что должно остаться прежним. И когда вы думаете об этом, у нее есть три четких поведения, которые вы хотите реализовать при работе с ошибками. И это то, о чем я только что говорил, верно? Текущее, ожидаемое и неизмененное. Итак, текущее поведение — это то, что система делает сейчас. Вы хотите быть максимально конкретными. Например, когда пользователь обновляет свой адрес электронной почты, журнал аудита записывает изменение с новым адресом электронной почты, но в базе данных все еще остается старый адрес электронной почты до 200 миллисекунд, прежде чем завершится фиксация данных. Это, если я даже сказал это правильно, является конкретным воспроизводимым описанием того, что сломано. Затем, если бы вы перешли к ожидаемому поведению, вы бы сказали, что система должна делать вместо этого? Ну, журнал аудита должен записывать изменение только после успешной фиксации базы данных. Если фиксация базы данных не удалась, запись в журнале аудита не должна создаваться. Это исправление. Оно очень конкретно до того, как будет написан какой-либо код. И затем может быть что-то, что вы не хотите менять, просто чтобы убедиться, что агент ничего не изменит. И это то, что называется неизмененным поведением. Итак, вы по сути говорите, что не должно измениться в результате этого исправления. Формат журнала аудита не должен меняться. Схема базы данных не меняется. Контракт API не меняется. Другие конечные точки не затрагиваются. Этот раздел — негативное пространство для исправлений ошибок. Он точно говорит агенту, какие измерения ему не разрешено трогать при внесении исправления. Теперь это важно, потому что исправления ошибок — это то, где происходит много регрессий. Проще говоря, используйте спецификацию функции, когда вы строите что-то новое. Используйте спецификацию исправления ошибки, когда вы работаете над чем-то, что сломано. Это разные шаблоны, потому что они решают разные проблемы. Вы, возможно, слышали об инверсии управления в программировании. Я называю эту новую вещь инверсией источника истины. Когда агент генерирует что-то неправильное, ваш инстинкт — исправить код. Разработка, управляемая спецификациями, не исправляйте код. Вместо этого исправьте спецификацию. Спецификация — это входные данные. Код — это просто выходные данные. Одно место, где это действительно хорошо сохраняет весь источник истины в спецификации. Если вам нужно вернуться к функции или ошибке и запустить новую сессию, новая сессия может просто прочитать то, что у вас сейчас есть в спецификации, которая является источником истины, вместо того, чтобы вам приходилось передавать кучу информации через подсказку, или вы воссоздаете колесо того, что старая сессия уже знала, что очень помогает, когда вы пытаетесь использовать рабочие деревья или, знаете ли, иметь несколько сессий какого-либо инструмента ИИ-кодирования одновременно. И вот еще одна вещь, о которой стоит подумать, когда мы завершаем это видео, — это отчет команды Google Dora Dor A за 2025 год об разработке с помощью ИИ. Более 5000 респондентов, и вывод заключался в том, что ИИ не исправляет сломанную команду. Никогда не будет. Культура исправляет сломанные команды. ИИ усиливает то, что уже есть. Сильные команды становятся только сильнее. Борющиеся команды усиливаются и становятся слабее. Возможности, которые отчет определил как определяющие, на какой стороне усилителя вы находитесь, почти один к одному соответствуют тому, насколько хорошо у вас документированы вещи, что является прямым корреляцией со спецификацией, управляемой разработкой. Проще говоря, работа в небольших партиях, сильные практики контроля версий, сильное руководство тем, что должно быть построено, делает сильную команду. Это рабочий процесс, на который указывают данные. Итак, если вы были инженером, который всегда мог написать хороший документ по дизайну, ваши навыки стали более ценными. Если вы были инженером, который любит писать только код, потому что любит просто писать код и держать руки на клавиатуре, роль немного меняется. Но выход из этого — не просто писать больше кода, верно? Выход из этого — писать лучшую спецификацию. До следующего раза, друзья.