📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Building a REAL feature with Claude Code: every step explained

Matt Pocock44:16

Transcription

Я в последнее время много публиковал о том, что следует делать с кодом Claude, и в основном подходил к этому с философской точки зрения. Другими словами, все думают, что это новый сдвиг парадигмы, но на самом деле то, что мы делали в течение 20 лет, действительно очень хорошо работает с кодом Claude. Вы получаете максимум от этого, когда относитесь к нему как к кому-то, кому вы бы делегировали задачи в своей команде. Другими словами, вы фокусируетесь на архитектуре, вы фокусируетесь на обеспечении хороших циклов обратной связи. Вы фокусируетесь на всем том, что мы делали в течение последних 20 лет, не планируя слишком много заранее, и на всем этом. И во всех комментариях люди говорили: «Покажите нам что-нибудь практическое. Покажите, как вы это делаете». И вот, это то видео. Я понятия не имею, сколько времени займет это видео. Я понятия не имею, что именно мы будем охватывать. Я просто собираюсь приступить к реальной работе с кодом Claude в своем репозитории и буду рассказывать вам об этом. Я покажу вам все навыки, которые я использую. Я покажу вам свой процесс, и мы просто дадим вам весь контекст, который вы можете получить о том, как эти инструменты на самом деле используются. И если вам это понравится, то через пару недель я запускаю когорту по коду Claude для настоящих инженеров. На этой неделе скидка 40%, и она либо научит вас навыкам, которые вам нужны для настоящей инженерии, либо предоставит вам курс конвертации, который вам нужен, чтобы взять существующие навыки и применить их к этому новому веку. Так что, если это звучит для вас хорошо, ссылка ниже.

Хорошо, давайте начнем с понимания проекта, над которым я работаю, и на какой стадии его жизненного цикла он находится, и всего такого. Это мой менеджер видеокурсов. Он находится примерно на 1200-м коммите. Я закрыл около 637 задач по этому проекту. И я использую это как свою основную точку входа для всего, что я делаю, связанного с созданием контента. Другими словами, я создаю здесь видео. Я организую здесь свои курсы. Я публикую здесь видео. Я редактирую здесь миниатюры. Я пишу здесь. Это действительно мой универсальный магазин для всего, что мне нужно, чтобы выполнять свою работу, и это потрясающе. С точки зрения кода, это приложение React Router, которое использует TypeScript и Node, и использует Drizzle для ORM базы данных, использует PostgreSQL в качестве своей базы данных. Много тестирования с помощью Vest. И способ, которым я запускаю это, заключается в том, что я на самом деле не развертываю его. Я просто запускаю его локально. Так что я просто запускаю start. Я собираю его и просто, знаете ли, запускаю с помощью скрипта start.

Это запутанное видео для меня, потому что на самом деле сейчас я записываю видео, которое я делаю на менеджере видеокурсов. Вот. Это я. Это клипы, которые были обнаружены из видео, которое я записываю. И вот. Это предыдущий клип. Это запутанное видео для меня, чтобы сделать. Вы понимаете, что я имею в виду? Здесь просто куча всего. Вот как выглядит основной вид. У нас есть курсы здесь, слева. Затем у нас есть уроки и разделы в этих курсах. И то, что я хочу вам показать, находится здесь, в бесплатных видео. Внутри приложения у меня есть концепция "призрачных" уроков и "реальных" уроков, которые вы можете видеть здесь, в фильтрах. Эти "призрачные" уроки, по сути, не существуют на диске. И мне нужно щелкнуть правой кнопкой мыши по уроку и сказать "создать на диске", чтобы он фактически создал урок в репозитории на диске. И логика для этого довольно сложна, потому что я могу вернуть это обратно в "призрачное" состояние здесь. Так что, а затем, когда я это сделаю, мне нужно удалить все файлы, которые находятся в файловой системе. преобразовать его обратно в "призрачное". Идея здесь в том, что это позволяет мне планировать и создавать курсы в одном и том же пользовательском интерфейсе, что в итоге оказывается очень, очень приятно. Но то, что я хочу добавить, это некоторые улучшения здесь. Так что, я хочу иметь возможность, когда я создаю урок, мне не нужно просто создавать "призрачный" урок. Мне следует иметь возможность добавить "реальный" урок вместо "призрачного". То же самое, когда я удаляю "реальный" урок, мне следует иметь возможность просто удалить его, а не сначала превращать его в "призрачный". Так что, вот этот.

Теперь эта часть кодовой базы очень хорошо протестирована, и поэтому это должно быть относительно простое создание. Но есть еще одна вещь, которую я хочу сделать, а именно, когда мы переходим к этим курсам здесь и добавляем новый курс, я хочу иметь возможность, по сути, создать "призрачный" курс, курс, который еще не существует в файловой системе, потому что в настоящее время каждый курс требует записи в файловой системе. Так что это моя идея. У меня есть очень свободный набор требований, и это, возможно, то, как вы начинаете большинство дней в качестве разработчика. У вас есть небольшие изменения, которые вам нужно внести в свое приложение, основанные на некоторых расплывчатых идеях. Возможно, это идеи, которые вы придумали. Возможно, это идеи, которые пришли откуда-то еще. И первое, что вам нужно сделать, это фактически протестировать эти идеи и укрепить их. Но первое, что мы сделаем, это откроем это в VS Code. И мы перейдем к этому и скажем "задай мне вопросы". И я буду использовать свой инструмент диктовки, чтобы надиктовать сюда кое-что.

Способ, которым мы обрабатываем "призрачные" и "реальные" уроки, немного громоздкий в некоторых местах. Раздражает, что вам нужно создать "призрачный" урок, прежде чем вы сможете создать "реальный" урок. И также раздражает, что когда вы удаляете его или удаляете "реальный" урок, вы не можете просто удалить "реальный" урок. Вам нужно сначала превратить его в "призрачный". Теперь, в этот момент, я думаю, хочу ли я в этой сессии также заняться другой вещью? Хочу ли я заняться идеей "призрачных" курсов? Мое пространство решений для этого такое: вытеснит ли это сессию "задай мне вопросы" или все это на самом деле довольно плавно свяжется? Потому что идея этой сессии "задай мне вопросы" заключается в том, что я создам документ из этого, который я затем буду использовать для будущих сборок. Так что это мое решение: хочу ли я создать PRD, документ с требованиями к продукту, который содержит обе эти вещи, или это отдельные проблемы, которые мне нужно разделить на отдельные PRD? Я скажу, что эти вещи на самом деле как бы принадлежат вместе, но я принимаю это решение как бы произвольно.

Я также хочу расширить функциональность курсов, чтобы она позволяла мне создавать курс без пути к файлу. Это был бы своего рода "призрачный" курс, запланированный курс, который я еще не решил, буду ли я создавать. Теперь эту вторую часть я на самом деле не объяснил "почему". Это то, что у меня на уме сейчас. Я как бы объяснил, что я хочу, чтобы функция делала, но я не объяснил, почему я хочу, чтобы функция существовала. Всегда очень важно, когда вы входите в эти сессии, объяснять "почему" LLM. Потому что, конечно, если у LLM есть "что", то она понимает, что вы хотите построить. Но если она не знает "почему", то она не может предложить альтернативы. Причина, по которой я хочу этого, заключается в том, чтобы я мог свободно планировать курсы, не обязываясь точной формой в файловой системе. Инициирование новых репозиториев довольно громоздко, и я иногда просто предпочитаю или предпочитаю создавать вещи в пустом пространстве, а не обязываться реальной формой. "Призрачные" курсы имели бы немного другие ограничения. "Призрачные" курсы, вероятно, имели бы, нет, я полагаю, "призрачные" курсы могли бы иметь "реальные" уроки. Просто в тот момент, когда у них есть "реальный" урок внутри них, они становятся "реальным" курсом, и вы тогда обязаны поместить его в файловую систему, я полагаю, или я не знаю. Я не уверен в этом потоке. Может быть, мы сможем поработать над этим вместе. Обратите внимание, насколько это грубо. Это просто супер-набросанная идея, которую я как бы, знаете ли, просто выплевываю LLM и заставляю ее делать всю работу. Если вы не видели мой навык "задай мне вопросы", то перейдите по моей ссылке. Я отправлю ее по ссылке ниже. Она есть в моей статье "Топ-5 навыков", но вы сможете увидеть, что она делает здесь. Это действительно, действительно круто.

Хорошо, он собирается провести фазу исследования. Я собираюсь пойти и взять стакан воды. И кстати, если вы не знаете, что такое исследование, исследование — это, по сути, вызов под-агента. Так что это, по сути, просто передача сообщения другому агенту с просьбой исследовать эту кодовую базу. Этот агент затем исследует ее в своем собственном контекстном окне, а затем берет этот контекст, берет своего рода резюме этого и передает его обратно родительскому агенту. Так что это позволяет вам получить много пользы от фазы исследования, потому что исследователь может просто бам-бам-бам-бам читать тонны и тонны файлов, а затем родительский агент получает только резюме. Так что это очень эффективно по токенам. Но в любом случае, мне нужен стакан воды.

Хорошо, "задай мне вопросы" вернулся с вызовом вашей формулировки текущих болевых точек. Он говорит, что, глядя на код, удаление урока в сервисе записи курса уже обрабатывает как "призрачные", так и "реальные" уроки напрямую. Если это "реальный", он удаляет каталог и перенумеровывает. Если это "призрачный", он просто удаляет строку из базы данных. Так что вы можете удалить "реальный" урок, не превращая его сначала в "призрачный". Есть ли что-то в пользовательском интерфейсе, что заставляет поток "преобразовать в призрачный", а затем "удалить"? Ну, да, есть. Да, в пользовательском интерфейсе нет возможности немедленно удалить урок. И под удалением "реального" урока я имею в виду, что он удалит как запись из базы данных, так и ее представление на диске.

Я отправлю это, пока буду объяснять кое-что очень крутое, что я недавно начал делать. Я читал книгу под названием "Предметно-ориентированное проектирование". И в этой книге они говорят о том, как важно поддерживать глоссарий всех терминов, которые вы используете для описания системы. Этот универсальный язык затем может использоваться, по сути, для преодоления разрыва между разработчиками и экспертами предметной области, людьми, для которых вы на самом деле строите. Так что мне это нравится, потому что это именно то, что LLM должна иметь со мной. Я эксперт предметной области, а LLM — разработчик. И нам нужен какой-то общий язык, чтобы мы могли говорить точно. Например, здесь у нас есть концепция "призрачного" урока. Урок, который существует на... Ой. Урок, который существует в базе данных. Где он? Да. Урок, который существует в базе данных, но еще не в файловой системе. И поэтому всякий раз, когда LLM ищет информацию о "призрачных" уроках, она столкнется с этим файлом универсального языка.

Хорошо. Хорошо, он вернулся и сказал: "Да, пользовательский интерфейс в настоящее время предоставляет только преобразование в "призрачный" для "реальных" уроков, а не прямую опцию полного удаления". Это простой пробел в пользовательском интерфейсе. Хорошо, это полезно. Давайте быстро поговорим о том, как он использует сервис здесь и что это на самом деле означает в моей кодовой базе. Я, возможно, даже попробую новую функцию бокового вопроса. Это очень полезно, когда вы просто хотите задать быстрый вопрос, и вы не хотите, чтобы он попадал в историю чата. Опишите, что происходит с сервисом записи курса. Опишите его форму. опишите его возможности. Посмотрим, что он вернет. Причина, по которой я спрашиваю об этом и хочу показать вам, что это такое, заключается в том, что я очень горжусь тем, как я спроектировал этот репозиторий. Я имею в виду, там определенно есть вещи, которые определенно нужно рассмотреть, но способ, которым я сделал сервисы, я думаю, довольно приятный. Сервис записи курса — это основной слой бизнес-логики для изменения данных курса, правой стороны системы. Он координирует работу между базой данных, файловой системой и логикой нумерации и перенумерации путей. У него очень четкий интерфейс здесь, например, вы можете добавлять "призрачные" уроки, вы можете материализовать "призрачный". Так что, преобразовать "призрачный" урок в "реальный" урок, преобразовать его обратно в "призрачный", удалить урок и т. д. Так что это большой, большой блок функциональности. И тесты для этого сервиса записи курса находятся в одном месте. Так что, course_write_service.test.ts. О, нет. Раньше было там. Больше нет. Да, вот они. Course_e2e.test.ts. ts, и это фактически создает тестовую базу данных. Он настраивает временный git-репозиторий и таким образом тестирует всю синхронизацию между этим. Этот репозиторий использует Effect, и Effect делает его таким приятным для создания этих своего рода единиц в вашей системе, которые вы можете легко тестировать. Другие языки имеют это как первоклассную вещь, но Effect как бы прикрепляет это поверх TypeScript действительно красивым способом. Я уже делал видео об Effect на этом канале, всего одно видео. И, скажем так, я все еще люблю его и использую его буквально для всего, или, по крайней мере, для всего серверного, что я строю, все находится в Effect. В любом случае, этот огромный сервис, сервис записи курса, где он? DB_function_service. Вот он. Сервис записи курса. Он просто живет здесь. Так что это файл, по сути, с кучей методов внутри. И эти методы, такие как materialize_ghost, add_ghost_section, add_ghost_lesson, delete_lesson и т. д. Это то, о чем мы говорим, когда говорим об этом сервисе.

Так что я могу выйти из этого режима "кстати" просто нажав пробел, ввод или Escape. И теперь я вернулся сюда. Так что это отличный вопрос. Какой поток вы на самом деле хотите здесь? Вы говорите, что хотите создать действие по созданию урока, которое немедленно создает каталог на диске, полностью пропуская шаг "призрачный"? Или боль заключается в том, что двухэтапный процесс "создать призрачный", а затем "материализовать" кажется ненужной формальностью, когда вы уже знаете, что хотите "реальный" урок? Да, именно. Двухэтапный процесс кажется ненужным, и он говорит: "Хорошо". Так что вы хотите единое действие "создать урок", которое создает как сущность базы данных, так и каталог на диске за один раз, когда вы уже знаете, что он будет "реальным". Да. Хорошо. И теперь он перешел к более крупной теме. "Призрачные" курсы. Да. Вот. Затем вы сказали что-то интересное и немедленно отступили от этого. "Призрачные" курсы могут иметь "реальные" уроки, и когда они это делают, они становятся "реальным" курсом, и вы обязаны поместить его в файловую систему. Давайте разберем это. Первый вопрос. "Призрачный" курс не имеет пути к файлу. Так что у него нет git-репозитория. Разделы и уроки внутри него будут по необходимости "призрачными". Там негде их разместить на диске. Когда вы говорите, что "призрачный" курс может иметь "реальные" уроки, что означает "реальный" без файловой системы? Правильно. Так что здесь он немного дорабатывает мой как бы расплывчатый язык и заставляет меня быть более конкретным. Это легкий вопрос для меня, чтобы ответить. Я не хочу, чтобы у них был какой-то промежуточный статус, вроде "более проработанный, чем "призрачный"". Какая отличная фраза. Но да, А, очевидно, здесь. Добавление "реального" урока к "призрачному" курсу — это триггер, который заставляет вас назначить путь к файлу и материализовать курс.

Теперь я уже думаю с точки зрения пользовательского интерфейса, что будет проще сделать? Или, скорее, самое очевидное для пользователя, самый чистый пользовательский интерфейс, либо когда мы создаем, как бы, "реальный" урок внутри "призрачного" курса, мы говорим: "Нет, вы не можете этого сделать. Вам нужно сначала выбрать что-то на диске, а затем вам нужно щелкнуть". Или мы создаем своего рода интегрированный поток, где вы говорите: "Хорошо, вы записываете это на диск. Когда вы делаете это впервые внутри "призрачного" курса, вам нужно выбрать место, где он будет находиться. Я думаю, я склоняюсь ко второму, потому что это не так сложно сделать с точки зрения пользовательского интерфейса, и я думаю, что это будет более приятный поток. Так что, давайте скажем ему это. Да, мы выберем здесь. И я думаю, что имеет смысл, что когда вы нажимаете "преобразовать в" или "преобразовать и показать в файловой системе" или как бы там ни называлась кнопка, когда вы материализуете, обратите внимание здесь, вот где универсальный язык очень полезен, потому что я просто там болтался. Но я имею в виду, что когда я материализую "призрачный" урок, когда вы материализуете "призрачный" урок, у вас должно появиться модальное окно, которое заставит вас материализовать курс. Посмотрите, насколько чистый, насколько чище этот язык, потому что у меня есть концепция материализации, и слово согласовано между мной и LLM. В любом случае, давайте запустим это и посмотрим, что произойдет.

Право. Да, у нас есть концепция версий внутри приложения. Так что, версии курсов. Это очень важно для меня, потому что у меня есть команда людей, которые фактически применяют курс к CMS. И поэтому у меня есть курс и журнал изменений. Например, здесь, в моей когорте Claude Code, у меня есть несколько версий. И чем раньше я приближаюсь к когорте, тем больше я исправляю ошибки или, как бы, меняю видео, и тому подобное. Последняя версия всегда является черновиком. А затем я могу, как бы, опубликовать этот черновик и добавить к нему сообщение коммита, и он попадает в журнал изменений. Вот. Это пользовательский интерфейс для публикации новой версии. И вот предварительный просмотр журнала изменений. Так что да, я почти уверен, что схема, на которую мы полагаемся, требует, чтобы "призрачные" курсы все еще имели версии. Да, я почти уверен, что схема, которая нам нужна, потребует, чтобы у нас были версии, потому что версии нужны для того, чтобы иметь в них разделы и уроки и тому подобное. Однако нет никакого смысла иметь возможность публиковать "призрачную" версию. Так что мы должны просто скрыть части пользовательского интерфейса, которые позволяют нам публиковать, и действия в меню, которые позволяют нам публиковать. Так что, давайте запустим это. Я вижу в своем видеоредакторе, что мы примерно на 15 минут. И просто обратите внимание, сколько времени мы тратим здесь на проработку этих идей. Чем больше мы здесь делаем, тем меньше нам придется делать, когда мы фактически будем направлять LLM.

Хорошо, давайте перейдем к моменту назначения файла. Когда вы материализуете "призрачный" курс, потому что вы материализуете урок внутри него, вам нужно присвоить ему путь к файлу. Либо репозиторий уже существует, либо репозиторий еще не существует. Когда вы присваиваете "призрачному" курсу путь к файлу, должно ли приложение обрабатывать создание репозитория для вас? Нет, оно не должно обрабатывать создание репозитория. Оно просто указывает на существующий каталог. Это легко выяснить.

Хорошо, это такой прекрасный умный вопрос, который он нам задал. Он излагает то, что вы просите. Прямое удаление "реальных" уроков, прямое создание "реальных" уроков, "призрачные" курсы, а затем материализация урока в "призрачных" курсах. Вопрос: применяется ли прямое создание также и к "призрачным" курсам? Это так чертовски умно. Это такой хороший вопрос. Я могу представить, как мой бывший начальник Уиллоу Риган задавал бы этот вопрос, который является парнем, у которого я многому научился в области ведущего разработчика. У него была невероятная способность просто сидеть на встрече и задавать умные вопросы часами и часами. И это именно то, что делает ИИ здесь. Он задает действительно умные вопросы в нужный момент процесса. Так что, если вы находитесь внутри "призрачного" курса и нажимаете "создать урок", должно ли это немедленно вызвать модальное окно назначения пути к файлу и создать его на диске? Опять же, здесь есть компромисс. И вместо того, чтобы я думал об этом в своей голове, что не особенно приятно смотреть, почему бы нам не смоделировать, как это может выглядеть, если я как бы проработаю это с LLM? Можете ли вы привести мне компромиссы обоих этих подходов?

Хорошо, он говорит, что в варианте А, "создать урок внутри "призрачного" курса" всегда создает "призрачный" урок. Сохраняет "призрачный" курс как чистое пространство для планирования. Момент назначения пути к файлу происходит только тогда, когда вы явно выбираете материализацию, что является четким преднамеренным действием. Есть недостаток. Если вы уже решили, что этот курс "реальный", и вы просто добавляете уроки, вы возвращаетесь к двухэтапному раздражению, которое вы пытаетесь исправить. Вариант Б, "создать урок внутри "призрачного" курса" запускает каскад материализации. Да, он говорит, что вариант А — очевидный выбор, учитывая вашу заявленную цель. Двухэтапное раздражение, которое вы описали, касается конкретно "реальных" курсов, где файловая система существует, и вы хотите "реальный" урок. Да, я, вероятно, согласен с ним. Если мы хотим последовательный пользовательский интерфейс, то мы хотим иметь возможность создавать как "реальные" уроки, так и "призрачные" уроки на любом этапе курса, будь то "реальный" или "призрачный". Это будет означать немного меньше работы на фронтенде, потому что мы не хотим или не будем нуждаться в условном отображении вещей и так далее. Да, это имеет смысл для меня. Вариант А звучит хорошо. Я думаю, что это в основном имеет смысл в контексте наличия двух кнопок: одной для создания "реального" урока и одной для создания "призрачного" урока.

Можете ли вы немного рассказать мне о пользовательском интерфейсе и о том, как это будет выглядеть? Обратите внимание, что я сейчас больше управляю этим. Это тоже нормально. Навык "задай мне вопросы" приятен и гибок, так что вы можете управлять иногда, а ИИ может управлять. Это тоже приятно, что он фактически проверяет текущий пользовательский интерфейс для создания уроков. Это часть навыка: я заставляю его, вместо того чтобы задавать мне вопросы обо всем, если это вопрос, на который можно ответить, или можно ответить, посмотрев на код, он должен сначала посмотреть на код. Мне хотелось бы, чтобы исследование было быстрее. Исследование — это то, что вам нужно в каждой сессии, иногда несколько раз в сессии. И мне просто хотелось бы, чтобы это было быстрее.

Хорошо, вот как работает текущий пользовательский интерфейс. Вы щелкаете правой кнопкой мыши по заголовку раздела, добавляете урок. Щелкните правой кнопкой мыши по существующему уроку, добавьте урок до, добавьте урок после. Также создает "призрачный". Внутри "реального" курса вы щелкаете правой кнопкой мыши по разделу, вы увидите "добавить призрачный урок" и "добавить урок". Внутри "призрачного" курса, щелкните правой кнопкой мыши по разделу, вы увидите только "добавить призрачный урок". Да, верно. Это вопрос. Внутри "призрачного" курса вы хотите, чтобы кнопка "создать реальный урок" вообще существовала? Теперь, в этот момент, я не знаю. Я представляю, что этот пользовательский интерфейс станет довольно перегруженным с этим, как бы, потому что у вас будет несколько кнопок. У вас будет, как бы, "добавить урок перед этим", а затем вы сделаете его "призрачным" или "реальным"? Я полагаю, как бы, о боже, это на самом деле довольно сложно. Я думаю, хочу ли я на самом деле прототип этого, чтобы я мог увидеть, как это выглядит? Потому что есть несколько способов, которыми мы можем с этим повозиться и сделать это как бы приятно. Вы можете сделать так, чтобы вы добавляли урок, затем открывалось модальное окно, и вы выбирали, является ли он "призрачным" уроком или "реальным" уроком. Я думаю, что, вероятно, я просто построю его одним способом, а затем, возможно, дам обратную связь после. Так что давайте скажем да, внутри "призрачного" курса, давайте иметь кнопку "создать реальный урок". Вы знаете, я мог бы прекратить всю эту сессию "задавания вопросов", я мог бы перейти в режим прототипирования, где я просто как бы прототипирую, знаете ли, три разных версии, пять разных версий этого, чтобы увидеть, как будет выглядеть пользовательский интерфейс. Но я очень хочу приступить к реализации сейчас.

Хорошо. Так что "создать реальный урок" внутри "призрачного" курса запускает полный каскад. Модальное окно запрашивает путь к файлу, курс становится "реальным", раздел материализуется, урок создается на диске — все в одном потоке. Это верно. Это модальное окно делает много работы. Правильно. Ему нужно получить заголовок урока и путь к файлу курса. Да, это все. Правильно. Это все. Нам нужен только заголовок урока и путь к файлу курса. Это все. Я чувствую это. Мы приближаемся к концу этой сессии "задавания вопросов". О, может быть, нет. Он спрашивает о поведении разделов. Разделы внутри "призрачных" курсов. И состояние раздела, по сути, просто выводится из урока. Если внутри раздела есть какие-либо "призрачные" уроки, то это "призрачный". О, извините. Если внутри раздела есть какие-либо "реальные" уроки, то это "реальный" раздел на диске. Раздел, по сути, выглядит так. Это просто, по сути, каталог на диске. Вы можете переименовать его и переименовать каталог или добавить в него что-то, но это, по сути, все. Логика разделов должна подчиняться текущим правилам, которые у нас уже есть. Нет ничего действительно нового в разделах. Например, когда мы находимся внутри "призрачного" курса и создаем "реальный" урок внутри этого раздела, то мы, по сути, проходим весь путь вверх. Так что он становится "реальным" разделом, становится "реальным" уроком и становится "реальным" курсом.

Вот. Продолжим. Позвольте мне перейти к схеме базы данных. Сейчас таблица курсов имеет поле "путь к файлу" как обязательное текстовое поле. Для "призрачных" курсов это должно быть необязательным. Это единственное изменение схемы, которое я предвижу. Да, просто скажу "да" этому. Он будет задавать мне вопросы о сложном крайнем случае. Я вижу, у вас есть "реальный" курс с путем к файлу. У него есть несколько "реальных" уроков и несколько "призрачных" уроков. Вы удаляете все "реальные" уроки или преобразуете их все в "призрачные". Становится ли "реальный" курс "призрачным" курсом? Опять же, это классический вопрос Уиллоу Ригана. Это фантастика. Действительно, действительно хорошо. Нет, "реальный" курс не становится "призрачным" курсом. Как только у курса появляется путь к файлу, он остается "реальным" навсегда, потому что то, что находится на диске, никуда не денется. Да, я думал об этом раньше, и поэтому я очень рад, что он ответил, потому что теперь это в контексте и это изложено. Еще один крайний случай. У вас есть "призрачный" курс. Вы материализуете урок, присваиваете путь к файлу, все становится "реальным". Теперь у курса есть путь к файлу, но нет "реальных" уроков. Мне кажется, мы только что ответили на это, верно? Это странный. Я не думаю, что Уиллоу Риган задал бы этот вопрос. Да.

Позвольте мне перейти к удалению. Вы хотите прямое действие удаления для "реальных" уроков в пользовательском интерфейсе? В настоящее время контекстное меню для "реальных" уроков показывает "преобразовать в призрачный", но не "удалить". Да, это проблема пользовательского интерфейса. Должны ли "реальные" уроки иметь оба варианта: "преобразовать в призрачный" и "удалить"? Я думаю, нам нужны оба. Хорошо, мы приближаемся. Мы приближаемся. Я думаю, я охватил основные ветви. Позвольте мне изложить полный объем, как я его понимаю, и вы скажите мне, если я что-то упускаю. Путь к файлу курсов становится необязательным. Создание "призрачного" курса — новый поток создания курса, который запрашивает только имя. Без пути к файлу. Правильно. Пользовательский интерфейс "призрачного" курса — скрыть действия публикации и экспорта. Правильно. Создать кнопку "реальный урок", доступную как в "реальных", так и в "призрачных" курсах. В "реальном" курсе создает на диске немедленно. В "призрачном" курсе запускает модальное окно, сначала запрашивая путь к файлу, затем каскад материализации. Это выглядит хорошо. Создать "призрачный" урок работает как сегодня. Доступно везде. Действие удаления для "реальных" уроков — очищает с диска и из базы данных за один шаг. Да. Действие удаления для "призрачных" уроков — уже без изменений. И, наконец, преобразование в "призрачный" остается для "реальных" уроков, которые вы хотите продолжать планировать, но удалить с диска. Точно. Так что, у нас есть это. Это, по сути, восемь пунктов, на которые мы только что потратили 22 минуты видео, пытаясь получить.

Мне это кажется очень знакомым. Вот как я много работаю с ИИ. Я, знаете ли, выделяю полчаса в своем календаре, чтобы точно проработать нужную мне функцию. И отсюда это почти все на полном ходу. Как бы, мы сделали сложную часть. Теперь мы сделали часть "человек в цикле". Что я делаю дальше, это я теперь... Я пробую это уже несколько дней. Я заставляю его обновить мой документ универсального языка, чтобы он просто оставался актуальным с любыми идеями, которые у меня есть здесь. Например, у нас есть новая терминология, у нас есть эта идея "призрачных" сущностей, которая является новой. Давайте посмотрим, какие изменения он внес. На самом деле, я просто приму их и просмотрю позже. Так что, вот. Мы можем видеть, что он обновил свою идею "призрачных" сущностей здесь. У него есть "призрачные" уроки, "призрачные" разделы и "призрачные" курсы. Глагол "материализовать" теперь правильно здесь. Акт перехода "призрачной" сущности в "реальную" сущность путем создания ее представления на диске. Мне также нравится, что у него есть "создать на диске" и "реализовать", как псевдонимы, которых следует избегать. Это действительно круто. И у него даже есть концепция каскада материализации. Цепная реакция при материализации урока внутри "призрачного" курса. Присваивает путь к файлу курсу, материализует раздел, который материализует урок. Я чертовски люблю это, потому что позже я могу сказать: "Да, есть ошибка в каскаде материализации", и он точно знает, о чем я говорю. Так что, давайте зафиксируем это обновление в документе универсального языка. Посмотрите на это. Да, иногда я действительно сам коммичу код.

Хорошо, он вернулся к "заданию вопросов". Да, он теперь просто повторил восемь разделов. Существующая сущность "план" — это отдельный, отключенный инструмент планирования. Да, у меня раньше была отдельная область планирования, но затем я как бы использовал эту "призрачную" концепцию, чтобы интегрировать ее в свою реальную вещь с курсами. У меня есть это внутри универсального языка здесь, внизу. План, раздел плана и урок плана там. Но это, по сути, устарело. Я собираюсь удалить это в какой-то момент. И поэтому мы можем сказать, что планы устарели, а "призрачные" курсы — это новый способ сделать это. И на самом деле, я думаю, я собираюсь сказать, что я удовлетворен. Давайте, и я вызову свой следующий навык, который заключается в том, чтобы написать PRD.

Так что, если мы подумаем о разговоре, который мы только что провели с LLM, это невероятно хороший корм для простого превращения этого в более краткий сводный документ всего, что мы хотим построить. Я чертовски люблю вопросы и ответы, потому что это размещает вопрос рядом с ответом. Я знаю, что это звучит как такая, как бы, базовая вещь, но способ, которым работают эти механизмы внимания, заключается в том, что вещи, которые находятся близко друг к другу, имеют тенденцию проявляться как горячая точка для LLM с точки зрения ее механизма внимания, точно так же, как и для людей. И все это в итоге означает, что это такой богатый документ для него, чтобы просмотреть. Теперь он проводит еще одну фазу исследования. Мы должны провести поверхностную проверку нашего контекстного окна здесь. Мы сейчас только около 40 тысяч токенов, что довольно впечатляет, учитывая, сколько времени мы провели с LLM, работая над этим. Многие люди спрашивали меня, почему мой навык "задай мне вопросы" не использует инструмент "спросить пользователя". Как бы, мы на самом деле не использовали встроенный механизм Claude для задавания вопросов. И причина этого в том, что мне на самом деле не нравится этот пользовательский интерфейс, во-первых. И во-вторых, как бы, если у вас есть выбор между вызовом инструмента и невызовом инструмента, то невызов инструмента всегда будет более эффективным по токенам, потому что каждый раз, когда вы вызываете инструмент, вам нужно обернуть его в JSON. Вам нужно сделать различные вещи.

Оки-доки. Мы можем видеть здесь, что хорошо, он теперь набрасывает основные модули перед написанием PRD. Я раньше говорил на этом канале о том, насколько важными я считаю модули и понимание модулей в вашей кодовой базе, не обязательно заглядывая внутрь них. Например, сервис записи курса, который мы рассматривали раньше, это большой тестируемый модуль, который я очень тщательно спроектировал и спроектировал его интерфейс. И я считаю, что это настолько важно, что я встроил это в свой навык "писатель PRD". Так что он набрасывает модули и представляет их вам. Мне не обязательно заглядывать внутрь этих модулей. Мне просто нужно знать, как они меняются. Например, здесь я вижу что-то немного подозрительное, верно? Он хочет создать новый метод в сервисе записи курса materialize_course, и урок повторно использует существующую логику материализации призрачного и секционного материала внутри. Я думаю о том, может ли он просто вместо этого использовать существующий materialize_ghost и передать ему, как бы, дополнительный параметр, но я думаю, что это было бы немного подозрительно с точки зрения API. Так что я думаю, что он, вероятно, прав. Я думаю, что у него должен быть новый метод. Обратите внимание, как я думаю об интерфейсе, а не о реализации. Реализация меня не особо волнует, но я хочу убедиться, что это тестируемо и, знаете ли, что остальная часть репозитория и любые будущие агенты ИИ могут понять, что он делает. И опять же, обратите внимание, насколько легко назвать эти функции, потому что у нас есть эта концепция универсального языка. Так что модуль один — это схема "призрачного" курса, операции с базой данных, это кажется нормальным. Сервис каскада материализации, это кажется нормальным. Это просто новый метод в сервисе курса. Здесь у нас есть два новых API-маршрута, что имеет смысл, потому что мы делаем прямое создание "реального" урока, прямое удаление "реального" урока. Я мог бы поместить их в другие API-маршруты, но поскольку это всего лишь внутренний инструмент, меня не особо волнует, как выглядит мой API снаружи, поэтому меня не особо волнует, сколько у меня API-маршрутов или как они выглядят. Это просто деталь реализации.

Теперь он говорит о пользовательском интерфейсе "призрачного" курса. Новая опция "добавить призрачный курс" в боковой панели. Да, это кажется нормальным. Модальное окно материализации, две кнопки создания уроков в контекстных меню и действие удаления. И затем модуль шесть, устаревание планов. Эй, я имею в виду, я хочу устареть планы в какой-то момент, но я не думаю, что хочу устареть планы сейчас. Определенно не как часть этого PRD. И он задает мне второй вопрос. Для каких модулей вы хотите тесты? Я хочу тесты в местах, где у нас уже есть тестовые среды. Так что для сервиса записи курса определенно. И если у нас есть что-то для прямого удаления, я думаю, это тоже будет частью сервиса записи курса, верно? Так что давайте посмотрим, что он говорит здесь. Теперь это смешно. Он говорит, что нет существующей тестовой среды для сервиса записи курса. Тесты в репозитории в основном для чистых функций и редьюсеров. Это чушь. Так что я сделаю рафики. Я скажу "посмотри внимательнее". И вот они. Целый набор их, разделенных по проблемам. Хорошо. И он удовлетворен. У него есть все, что ему нужно. Теперь он напишет PRD и отправит его как проблему GitHub. Вот что я делаю со своими PRD. Вот что я делаю со всеми своими проблемами. Я помещаю их в GitHub, потому что тогда, когда мы будем фактически реализовывать это с помощью AFK-агента, AFK-агент загрузит все проблемы GitHub, выберет ту, над которой он будет работать, а затем просто будет работать над ней.

Теперь возникает вопрос: буду ли я просматривать этот PRD? И нет, я не буду. LLM действительно, действительно хороши в обобщении вещей. И поэтому я знаю, что этот PRD, вероятно, будет довольно хорошим обобщением этого разговора. Так что я просто приму его на веру. И затем я скажу "PRD в проблемы". Так что теперь пришло время разбить этот PRD на отдельные проблемы. Преимущество этого заключается в том, что PRD уже находится в его контексте, поскольку он его написал. И поэтому мы можем просто разбить проблемы прямо оттуда. Все они имеют блокирующие отношения. Так что это ничем не заблокировано. Это заблокировано номером один. Это также ничем не заблокировано. Это круто. Теперь давайте просто посмотрим, сколько их здесь. Шесть кажется правильным, я думаю. И под этим я имею в виду, что это будет подобрано циклом Ральфа. И поэтому он просто будет работать последовательно над каждой из этих задач. И поэтому я хочу выбирать задачи, которые не слишком большие и не слишком маленькие, потому что если они слишком маленькие, то мы платим стоимость вызова целого агента только для того, чтобы сделать, как бы, номер два здесь, скрыть пользовательский интерфейс публикации экспорта в "призрачных" курсах. Это крошечная задача, и ее можно объединить с чем-то еще. Но, возможно, создание "призрачного" курса? Нет, это кажется достаточно большим, потому что оно затрагивает пользовательский интерфейс, схему, API. Две кнопки создания уроков, создать "призрачный" урок и создать "реальный" урок. Это кажется очень маленьким. И на самом деле, я думаю, что он разбил их немного слишком далеко. Кроме, возможно, каскада материализации, который должен жить отдельно. Так что я думаю, что, возможно, мы просто объединим два и три, и я думаю, мы будем довольны. Так что давайте спустимся вниз. Давайте скажем "объединить два и три".

Хорошо, теперь у нас четыре части. Это создание "призрачного" курса — UI-штуки, действие прямого удаления и каскад материализации. Отлично. Давайте сделаем это. Давайте создадим проблемы. Буду ли я просматривать эти проблемы? Абсолютно нет. Я понимаю. Как бы, я уже как бы предварительно их просмотрел. Это просто расширение того, что есть в PRD, а затем, знаете ли, помещение их в проблемы. Это будет нормально. Я, возможно, просто покажу вам одну из них, чтобы увидеть, как они выглядят. Она ссылается на родительский PRD. Она точно говорит, что нужно построить. Она дает некоторые критерии приемки. Говорит, чем она заблокирована. И она также говорит о пользовательских историях, которые решаются в родительском PRD. Если родительский PRD — это как бы пункт назначения, то эти вещи — это путь к нему. И обратите внимание, что PRD просто содержит кучу пользовательских историй, некоторые решения по реализации и решения по тестированию. Все это, по сути, исходит из навыков, которые я собрал. И я обнаружил, что они достаточно хороши, чтобы удерживать LLM в рамках. Мне очень нравится добавлять решения по тестированию, потому что это означает, что она с большей вероятностью будет следовать TDD и создавать некоторые, как бы, циклы обратной связи по мере продвижения, что здорово.

Итак, хорошо, мы все настроили, чтобы создать нашего AFK-агента, дать ему наилучший шанс произвести хорошую работу. Теперь я немного готовился к этому в течение последних 24 часов, и я как бы построил мини-библиотеку, чтобы она работала лучше, чем раньше. Предварительное название для этого — "песочница", и у нас есть Dockerfile здесь. Он запустит контейнер Docker. Он смонтирует рабочую директорию внутри этого Dockerfile, а затем любые коммиты, которые будут сделаны внутри Dockerfile Claude, который будет работать там. Затем он выделит их. Так что извлечет эти коммиты в виде патчей и применит их к моему локальному репозиторию. Я обнаружил, что эта настройка просто супер гибкая. У меня есть Dockerfile и промпт здесь, и я могу просто запускать цикл Ральфа снова и снова, передавая кучу проблем и передавая, как бы, последние x коммитов. Но вы можете проверить репозиторий, чтобы увидеть самый актуальный файл об этом. Я собираюсь запустить, где это? Я думаю, это PNPM Ralph. Так что я запущу PNPM Ralph. Это теперь запустит моего AFK-агента с максимальным количеством итераций 100. Что он должен сделать, это то, что он исчерпает проблемы GitHub, потому что он будет закрывать проблемы GitHub по мере создания коммитов для них. Но в этот момент я могу, по сути, просто отойти, потому что, знаете ли, мы можем видеть, что он делает вещи в терминале. Он говорит, что смотрит на проблемы, которые нужно решить для... Но я могу выпить чаю или сделать кофе или что-нибудь еще, или, скорее всего, я просто открою другой терминал и начну еще одну сессию "задавания вопросов".

Для тех, кто говорит, что этот подход кажется очень медленным, вам нужно понять, что он медленный, потому что вы пытаетесь извлечь идеи из своего человеческого мозга. И пока это происходит, у вас работают AFK-агенты на заднем плане, реализующие ваши предыдущие сессии "задавания вопросов". Вот почему это революционно, потому что, как только мы закончим обдумывать идею, наша работа как бы закончена, пока мы не проверим результаты. Мой друг Джамон в Твиттере назвал это дневной сменой и ночной сменой, где я делаю дневную смену. Я, знаете ли, придумываю идеи. Я "задаю вопросы" с LLM. Я превращаю это в PRD и превращаю эти PRD в проблемы. А затем LLM берет на себя ночную смену. Claude идет и фактически реализует эти вещи AFK. Так что я сделаю небольшой перерыв. Я, возможно, даже пойду на небольшую прогулку, и я просто подожду и проверю, когда это будет сделано.

Хорошо, мы вернулись. Прошло около полутора часов. Я, знаете ли, пошел на прогулку. Я выпил чаю с родителями. Да, давайте посмотрим, что он сделал. Так что мы можем видеть, что агент сигнализировал о завершении после пяти итераций. Так что мы, по сути, запустили очищенный агент Claude Code пять раз в репозитории, и он должен был произвести для нас. Да, я думаю, шесть коммитов здесь. Я думаю, один из этих коммитов — это тот, который я еще не отправил. Да, мы можем видеть всю историю коммитов здесь. Он оставлял действительно хорошие подробные сообщения коммитов для нас. И он должен быть... Да, я думаю, это было обновление, которое я отправил раньше или еще не отправил. Так что на этом этапе процесса мне нужно как бы просмотреть эти коммиты. Я хочу просмотреть код, но я думаю, что я просто хочу сначала просмотреть реализацию. Так что я открою новую сессию Claude. И у меня еще нет навыка для этого. Так что я просто как бы свободно выстрелю. Так что я скажу: "Возьми последние пять коммитов и создай для меня план QA". Сохрани этот план QA в проблеме GitHub. План QA должен дать мне пошаговое руководство по тестированию каждой части новой реализации. Это то, что я как бы играл с добавлением в свои навыки, потому что я думаю, что это имеет смысл почти в каждом, как бы, изменении, ориентированном на пользователя. И пока он это делает, я перестрою приложение и снова запущу его локально, чтобы мы могли точно увидеть, что с ним происходит.

Хорошо, он создал для нас план QA. Прекрасно. Теперь я должен сказать, что нет ничего более скучного, чем смотреть, как кто-то другой делает QA. Так что я собираюсь просто пройти через это сам, и я вернусь к вам, если у меня возникнут какие-либо проблемы. Хорошо, первый действительно возник очень рано, а именно нажатие этой кнопки "добавить курс". Я вижу, что теперь здесь есть две вкладки. Мне это на самом деле очень не нравится. Как бы, я просто хочу, чтобы каждый раз, когда вы добавляете новый курс, это был "призрачный" курс. И мне не очень нравится терминология "призрачный курс", появляющаяся в пользовательском интерфейсе. Так что я выйду из этого. И у меня есть маленькая кнопка обратной связи здесь, которую вы можете увидеть, если я просто уберу себя отсюда. Эта кнопка обратной связи, я могу просто подробно описать свою обратную связь, и тогда она создаст для меня проблему GitHub, которая затем может быть подобрана циклом Ральфа. Так что я скажу: "Когда я открою модальное окно "добавить курс", единственной опцией должно быть "добавить призрачный курс", и я не хочу, чтобы "призрачный курс" появлялся в пользовательском интерфейсе. Он должен просто выглядеть так, как будто мы создаем курс, а затем он создает "призрачный" курс". Так что я отправлю это, и когда я перейду к проблемам GitHub, мы увидим, что у нас теперь есть новая проблема: "скрыть опцию "призрачный курс" в модальном окне "добавить курс", создать "призрачный" курс бесшумно". Так что я на самом деле использовал хайку, чтобы сгенерировать мне заголовок здесь, а затем у нас есть маршрут, с которого он был отправлен, а затем то, что я сказал в кнопке обратной связи. Вот как я делаю QA. Этой информации достаточно, чтобы Ральф сделал действительно хорошую работу. Так что я фактически начну свой цикл Ральфа, пока я иду. Я вернусь.

к плану тестирования, и я просто добавлю комментарий к этому, и я скажу: «Петля Ральфа не должна работать над этим». Это задача только для человека в цикле. Или, по сути, я просто переименую первый в AFK. На самом деле, у меня есть что-то в моем запросе, что говорит: если есть человек в цикле, например, метка на нем, или он выглядит так, как будто он для людей, не работайте над этим. И поэтому, давайте вернемся сюда. Давайте снова запустим PNPM Ralph. И он фактически будет работать над этой проблемой, пока мы тестируем другие вещи. Итак, я вернусь к тестированию и увидимся через секунду. Хорошо, новая вещь заключается в том, что когда я создаю здесь призрачный курс и, например, говорю «новый забавный курс», затем, когда я нажимаю «создать призрачный курс», ничего не происходит. Но на самом деле, как вы можете видеть в верхнем левом углу, о, прежде всего, мы получаем эту странную минифицированную ошибку React. Так что я просто скопирую и вставлю это для формы обратной связи позже, он фактически создает курс, но мы не переходим к курсу, и модальное окно не закрывается. Итак, давайте добавим это обратно в обратную связь. Когда я создаю призрачный курс, он не перенаправляет меня на новую страницу и показывает эту ошибку. Также нет состояния загрузки на кнопке, что выглядит запутанным с точки зрения пользователя. Итак, давайте отправим это снова. Агент, которого мы запустили для исправления предыдущей ошибки, фактически уже закончил. Так что давайте просто запустим его снова, и я продолжу тестирование. На этот раз я не буду прерывать. Я просто буду проходить через проблемы и пытаться исправить их с Ральфом на заднем плане. Хорошо, это я действительно думал, что стоит показать. Когда я вижу новый призрачный раздел внутри призрачного курса, и я нажимаю правой кнопкой мыши здесь, «создать призрачный урок» и «создать реальный урок» мне не кажутся правильными. Я чувствую, что когда я перехожу к «создать призрачный урок» здесь или «создать», я просто хочу что-то вроде «добавить урок». У нас уже есть модальное окно. Что нам следует сделать, так это просто иметь флажок, который говорит «также создать это в файловой системе». Так что это то, что возникло в наших ранних обсуждениях этой функции, что я не мог понять, в каком направлении двигаться, пока не увидел это в реальности. Так что вот так иногда идут дела. Мы могли бы иметь дополнительный этап проектирования или дополнительный этап прототипирования, но, знаете ли, я не против просто перейти к коду и исправить это там. Так что я добавлю некоторую обратную связь для этого, но я избавлю вас от прослушивания моей диктовки. Хорошо, тогда. Я прошел по плану тестирования и создал семь проблем здесь за последние восемь минут. Мы можем видеть, что пока я тестировал, Ральф работал на заднем плане и исправлял проблемы. Большинство этих проблем — ошибки, но некоторые из них — функции, о которых мы просто не думали. Так, например, когда мы удаляем реальные уроки, мы хотим добавить модальное окно подтверждения, чтобы убедиться, что оно не просто, знаете ли, как бы мы случайно не нажали на него, и оно удалится или что-то в этом роде. Здесь определенно были некоторые критические ошибки. Например, если это не репозиторий git, он попадает в очень странное состояние. Да. Если репозиторий курса не является репозиторием git, и что-то в этом терпит неудачу, то мы должны отменить создание каталога внутри него, поскольку каталог и файловая система, и база данных тогда будут не синхронизированы. Это то, о чем мы снова не думали на сессии «гриль меня» в начале. Так что теперь мы узнаем об этом в QA. Именно такие вещи заставляют меня думать, что подход «спецификации к коду» никогда не будет работать, потому что когда вы находитесь там, когда вы находитесь в цикле QA, когда вы итерируете к чему-то, вы найдете мелкие странные крайние случаи, которые действительно трудно спланировать заранее. В любом случае, нытье закончено. Суть в том, что я теперь выполнил дополнительный шаг QA. Ральф теперь будет разбираться с этими проблемами. Я, вероятно, могу закрыть этот план тестирования и, возможно, снова открыть его, если я захочу переделать его, скажем так, но поведение немного изменилось. Так что я закрываю его, чтобы убрать его из контекста Ральфа или, скорее, агента, которого я использую. Так что он не рассматривает это как источник истины для того, что он должен строить. В любом случае, я пойду делать что-нибудь еще, а потом посмотрим, что произойдет с Ральфом, когда он вернется. Хорошо, мы вернулись, и у нас есть итерация 8, которая почти завершена. Это выглядит как последняя проблема здесь, где просто добавляется модальное окно подтверждения с деталями файла при удалении реальных уроков. Мы можем видеть, что мы дошли до 14 коммитов, которые были добавлены в ходе создания этой функции, пока мы шли. И проблемы здесь почти закрыты. Вы можете видеть, что я последний раз открыл эту проблему 30 минут назад. Так что вот как долго это работает. Одна вещь, которую я хотел бы добавить здесь, это потенциально параллелизация этих циклов Ральфа и наличие команды агентов, работающих над этим одновременно. Но, честно говоря, приятно иметь эти пробелы, потому что это означает, что я могу сосредоточиться на чем-то. Например, «гриль меня» на чем-то, а затем позже я могу вернуться и вернуться к коду и провести большую сессию QA, отправить ее снова, вы поняли. Что-то, что имеет решающее значение для успеха этих циклов Ральфа, — это обеспечение того, чтобы он запускал тесты и типы на каждом отдельном коммите. Мы можем видеть, что в большинстве этих циклов он также добавляет тесты. Так что он обновляет тест редуктора, чтобы охватить новое действие. Теперь он коммитит и закрывает проблему. Так что мы почти у цели. Хорошо. И мы готовы к работе. Я перезапущу сборку и проведу еще немного тестирования. И я избавлю вас от этого дополнительного шага QA. Но достаточно сказать, что я бы сделал с этого момента, так это вернулся бы сюда и продолжил бы тестирование, нашел бы больше ошибок, и в какой-то момент я бы назвал это сделанным и прекратил бы работу над этим. Одна вещь, которая велика в таком гибком подходе к бэклогу, заключается в том, что я могу в любое время поставить в очередь кучу исправлений ошибок, и он займется их исправлением. Давайте просто проверим одну вещь: мы можем видеть, что «добавить урок» теперь больше не говорит «призрачный урок» и «реальный урок», и мы видим здесь, что он говорит «создать в файловой системе» в маленьком флажке. Если я перейду к «фубар» и скажу «создать в файловой системе», то он добавит урок, и мы должны увидеть, как только это будет сделано. Это довольно медленно, не так ли? Мне интересно, почему это так медленно, особенно потому, что все это локально. Теперь это должно быть завершено, и он создает этот «фубар» как второй урок. Но вот оно. По моим подсчетам, которые не совсем точны. Это будет примерно 42 минуты видео к этому моменту. Если вы здесь, спасибо вам большое за просмотр до самого конца. Что я надеюсь, вы вынесете из этого видео. Я не уверен, честно говоря. Это намного свободнее, чем видео, которые я обычно делаю, которые обычно довольно плотные и сосредоточены на конкретной цели. Я надеюсь, что вы сможете уловить от меня некоторые настроения в плане того, насколько подробно и глубоко я смотрю на то, что я произвожу. Вы также заметите, как мало я смотрел на код. То, что я делаю здесь, это я просматриваю входы и выходы. Меня интересует код. Абсолютно. Меня интересует, как меняются интерфейсы. Меня интересует, как выглядят модули. И время от времени я иду и немного копаюсь в коде, просто чтобы убедиться, что он на правильном пути. Но для меня на самом деле я просматриваю выходные данные, которые поступают от ИИ, передаю ему больше информации и вхожу в тесный цикл с ним. И, что крайне важно, поскольку я могу запускать Claude AFK, я могу параллелизовать свое собственное тестирование с исправлением ошибок, знаете ли, что просто потрясающе. Я предполагаю, что у вас есть десятки и десятки вопросов. Не стесняйтесь задавать их в комментариях ниже. Или, если вы хотите изучить это с нуля, а не просто погружаться в это грязное видео, то курс — это то, что вам нужно. Этот начинается 30 марта, но если вы видите это когда-нибудь в будущем, то, вероятно, будет место, где вы сможете записаться на следующий. Это были последние два месяца моей жизни, фактически полный рабочий день, посвященный этому. И я так горжусь тем, как это получилось, потому что все, что вы видите здесь, в этом большом видео, исходит из того, что я глубоко размышлял над этими вещами. И курс — это идеальное воплощение, самый простой способ изучить это с нуля. В любом случае, спасибо вам огромное за просмотр. Спасибо, что дошли до этого момента. И я увижу вас в следующем.