Я создал язык программирования с помощью Claude Code
@ai_longreadsЗа четыре недели автор с нуля создал интерпретируемый язык программирования Cutlet, полностью доверив написание кода Claude Code. Статья рассказывает о процессе, выводах и четырёх ключевых навыках агентной инженерии.
Это AI-перевод статьи, сделанный каналом Про AI: Лучшие Статьи и Исследования.
Я создал язык программирования с помощью Claude Code
I built a programming language using Claude Code Автор: Ankur Sethi Оригинальный текст:
За четыре недели в январе и феврале я создал новый язык программирования с помощью Claude Code. Я назвал его Cutlet — в честь своего кота. Это абсолютно законно. Вы можете найти исходный код на GitHub, а также инструкции по сборке и примеры программ.
Я использую программирование с помощью LLM с момента выхода оригинального GitHub Copilot в 2021 году, но до сих пор ограничивался генерацией boilerplate (шаблонного кода) и внесением точечных, целенаправленных изменений в свои проекты. Однако при работе над Cutlet я позволил Claude генерировать каждую строчку кода. Я даже не читал код. Вместо этого я выстроил систему ограничений, чтобы убедиться, что всё работает корректно (подробнее об этом ниже).
Результаты этого эксперимента меня удивили. Cutlet существует. Он собирается и запускается как на macOS, так и на Linux. Он может выполнять реальные программы. В его недрах, возможно, скрываются баги, но они, вероятно, не хуже тех, что можно найти в любом другом четырёхнедельном языке программирования в мире.
У меня есть Чувства™ по поводу всего этого и того, что это значит для моей профессии, но сначала я хочу провести вам экскурсию по языку, а уже потом взойду на трибуну.
Обзор Cutlet
Если хотите следовать за мной, соберите интерпретатор Cutlet из исходников и войдите в REPL командой /path/to/cutlet repl.
Массивы и строки работают так, как вы ожидаете от любого динамического языка. Переменные объявляются с помощью ключевого слова my.
cutlet> my cities = ["Tokyo", "Paris", "New York", "London", "Sydney"] => [Tokyo, Paris, New York, London, Sydney]
Имена переменных могут содержать дефисы. Те же правила синтаксиса, что и в Raku. Единственный тип числа (пока что) — число с плавающей запятой двойной точности.
cutlet> my temps-c = [28, 22, 31, 18, 15] => [28, 22, 31, 18, 15]
А вот что действительно интересно: метаоператор @ превращает любой обычный бинарный оператор в векторизованную операцию над массивом. В следующей строке мы умножаем каждый элемент temps-c на 1.8, а затем прибавляем 32 к каждому элементу результирующего массива.
cutlet> my temps-f = (temps-c @* 1.8) @+ 32 => [82.4, 71.6, 87.8, 64.4, 59]
Оператор @: — это операция zip. Он «сшивает» два массива в словарь.
cutlet> my cities-to-temps = cities @: temps-f
=> {Tokyo: 82.4, Paris: 71.6, New York: 87.8, London: 64.4, Sydney: 59}Вывод текста осуществляется встроенной функцией say. Эта функция возвращает nothing — аналог null в Cutlet.
cutlet> say(cities-to-temps)
{Tokyo: 82.4, Paris: 71.6, New York: 87.8, London: 64.4, Sydney: 59}
=> nothingМетаоператор @ также работает со сравнениями.
cutlet> my greater-than-seventy-five = temps-f @> 75 => [true, false, true, false, false]
А вот ещё одна крутая возможность: можно индексировать массив с помощью массива булевых значений. Это операция фильтрации. Она выбирает элементы с индексами, соответствующими true, и отбрасывает те, которые соответствуют false.
cutlet> cities[greater-than-seventy-five] => [Tokyo, New York]
Вот более короткая форма записи того же самого.
cutlet> cities[temps-f @> 75] => [Tokyo, New York]
Давайте выведем это с понятным сообщением. Оператор ++ выполняет конкатенацию строк и массивов. Встроенная функция str преобразует значения в строки.
cutlet> say("Pack light for: " ++ str(cities[temps-f @> 75]))
Pack light for: [Tokyo, New York]
=> nothingМетаоператор @ в префиксной позиции работает как операция свёртки (reduce).
cutlet> my total-temp = @+ temps-c => 114
Давайте найдём среднюю температуру. @+ складывает все температуры, а встроенная функция len() определяет длину массива.
cutlet> (@+ temps-c) / len(temps-c) => 22.8
Давайте выведем это красиво.
cutlet> say("Average: " ++ str((@+ temps-c) / len(temps-c)) ++ "°C")
Average: 22.8°C
=> nothingФункции объявляются с помощью fn. В Cutlet всё является выражением, включая функции и условные конструкции. Последнее значение, вычисленное в теле функции, становится её возвращаемым значением.
cutlet> fn max(a, b) is ... if a > b then a else b ... end =>
Ваши собственные функции тоже работают с @. Давайте свернём массив температур с помощью нашей функции max, чтобы найти самую высокую температуру.
cutlet> my hottest = @max temps-c => 31
Cutlet умеет гораздо больше. В нём есть все обычные возможности, которые вы ожидаете от динамического языка: циклы, объекты, прототипное наследование, примеси (mixins), сборщик мусора с алгоритмом пометки и очистки (mark-and-sweep) и дружелюбный REPL. Файлового ввода-вывода пока нет, и некоторые фундаментальные конструкции вроде обработки ошибок ещё отсутствуют, но мы движемся в этом направлении!
Полную документацию смотрите в TUTORIAL.md в git-репозитории.
Зачем создавать ещё один язык?
Я — фронтенд-инженер и (иногда) дизайнер. Я пробовал использовать LLM для создания веб-приложений, но всегда натыкался на ограничения.
По моему опыту, Claude и другие модели пугающе хороши в написании сложной бизнес-логики, но плохо справляются с задачами, требующими навыков визуального дизайна.
Оказывается, описывать адаптивные макеты и анимации на английском языке непросто. Никакое количество скриншотов и макетов не может передать LLM суть адаптивных макетов и анимаций. Я потратил часы, споря с Claude о проблемах вёрстки, которые он клялся, что исправил, но которые я по-прежнему ясно видел своими дырявыми человеческими глазами.
Я также обнаружил, что эти инструменты отлично справляются с созданием типовых интерфейсов, которые они уже видели в публично доступных репозиториях, но сдают позиции, когда я хочу сделать что-то новаторское. Я часто работаю с клиентами над сложными визуализациями данных для нишевых доменов, и LLM полностью провалились в попытках выдать полезные результаты на этих проектах.
С другой стороны, я видел, как люди совершали невероятные вещи с помощью LLM в последние несколько месяцев, и мне хотелось повторить эти эксперименты самому. Но мой предыдущий опыт с LLM подсказывал, что нужно тщательно выбирать проект.
- Я не хотел решать особенно новаторскую задачу, но хотел иметь возможность иногда направлять LLM в интересные направления.
- Я не хотел вручную проверять сгенерированный LLM код. Я хотел дать модели спецификации, тестовые случаи, документацию и примеры выходных данных, и заставить её делать всю сложную работу по проверке правильности результатов.
- Я хотел дать агенту сильную обратную связь, чтобы он мог работать автономно.
- Мне не нравятся MCP. Я не хотел с ними возиться. Поэтому всё, что требовало подключения к браузеру, создания скриншотов или общения с API по сети, автоматически отсеивалось.
- Я хотел использовать скучный язык с минимумом внешних зависимостей.
Небольшой динамический язык программирования удовлетворил все мои требования.
- LLM умеют создавать реализации языков, потому что их обучающие данные содержат тысячи существующих реализаций, научных статей и учебников по информатике. Меня заинтриговала идея создания языка-«ремикса» путём отбора и комбинирования возможностей, которые мне нравятся, из различных существующих языков.
- Я мог написать набор небольших детерминированных программ с ожидаемыми результатами для тестирования реализации. Я мог даже попросить Claude написать их за меня, что давало мне потенциально бесконечное количество тестовых случаев для проверки правильности работы языка.
- Реализации языков можно тестировать из командной строки, с чисто текстовыми входными и выходными данными. Не нужно делать скриншоты, записывать видео или настраивать хрупкие MCP. Для агента нет лучшей обратной связи, чем «запусти
make testиmake check, пока не исчезнут все ошибки». - C — язык настолько скучный, насколько это вообще возможно, и на нём существует огромное количество реализаций языков программирования.
Наконец, это также был эксперимент, чтобы понять, как далеко я могу продвинуть agentic (агентную) инженерию. Могу ли я сжать шесть месяцев работы в несколько недель? Могу ли я создать что-то, что выходит за рамки моих собственных возможностей? Как будет выглядеть мой ежедневный рабочий процесс, если я полностью перейду на программирование с помощью LLM? Я хотел ответить на все эти вопросы.
Я приступил к этому эксперименту с некоторым скептицизмом. Мои предыдущие попытки создать что-то целиком с помощью Claude Code не увенчались успехом. Но эта попытка не только оказалась успешной, но и принесла результаты, превзошедшие мои ожидания. Я не придерживаюсь мнения, что всё программное обеспечение в будущем будет написано LLM. Но я верю, что существует значительная часть задач, которые можно частично или в основном делегировать этим новым инструментам.
Создание Cutlet научило меня кое-чему важному: использование LLM для генерации кода не означает, что вы забываете всё, чему научились в разработке программного обеспечения. Агентная инженерия требует тщательного планирования, мастерства, аккуратности и дисциплины — точно так же, как и любое достойное программное обеспечение, созданное до эпохи генеративного ИИ. Навыки, необходимые для работы с программирующими агентами, могут выглядеть иначе, чем набор кода строчка за строчкой в редакторе, но это по-прежнему те самые инженерные навыки, которые мы оттачивали всю свою карьеру.
Четыре навыка агентной инженерии
Получение хороших результатов от LLM требует большой работы. Агентная инженерия не означает сброс расплывчатых инструкций в чат-окно и сбор урожая кода на выходе.
Я считаю, что сегодня нужно освоить четыре основных навыка для эффективной работы с программирующими агентами:
- Понимание того, какие задачи могут быть эффективно решены с помощью LLM, какие требуют участия человека, а какие должны полностью выполняться людьми.
- Умение чётко формулировать свои намерения и определять критерии успеха.
- Создание среды, в которой LLM может работать максимально эффективно.
- Мониторинг и оптимизация агентного цикла для повышения эффективности работы агента.
Понимание того, какие задачи LLM решают эффективно
Модели и инструменты быстро меняются, поэтому для определения того, какие задачи LLM решают хорошо, нужно развивать интуицию, общаться с коллегами и держать руку на пульсе.
Однако, если вы не хотите следить за стремительно меняющейся областью — и я не стану вас за это осуждать, там сейчас безумие — вот два вопроса, которые можно задать себе, чтобы понять, подходит ли ваша задача для LLM:
- Можно ли для вашей задачи определить и проверить критерии успеха автоматизированным способом?
- Решали ли другие люди эту задачу — или похожую — раньше? Другими словами, присутствует ли ваша задача в обучающих данных LLM?
Если ответ на любой из этих вопросов — «нет», бросать ИИ на эту проблему вряд ли даст хорошие результаты. Если на оба ответ — «да», то у вас может получиться с агентной инженерией.
Хорошая новость в том, что стоимость проверки — это цена подписки на Claude Code и один «жертвенный агнец» в вашей команде, готовый потратить месяц на эксперименты с вашей кодовой базой.
Формулирование намерений
LLM работают с естественным языком, поэтому умение выражать свои идеи словами стало критически важным. Если вы не можете объяснить свои идеи в письменном виде коллегам, вы не сможете эффективно работать с программирующими агентами.
Из Claude Code можно извлечь многое с помощью простых, расплывчатых, чрезмерно общих промптов. Но при этом вы делегируете большую часть своего мышления и принятия решений роботу. Для одноразовых проектов это нормально, но вам, вероятно, стоит быть осторожнее, когда вы строите что-то, что будете запускать в продакшен и поддерживать годами.
Вы хотите снабжать программирующих агентов точно написанными спецификациями, охватывающими максимально возможную часть пространства задачи. Работая над Cutlet, я проводил большую часть времени, записывая, генерируя, читая и корректируя документы-спецификации.
Для меня это был новый опыт. Я в основном работаю с стартапами на ранних стадиях, поэтому большую часть карьеры я относился к своему коду как к спецификации. Написание формальных спецификаций было чуждым для меня опытом.
К счастью, я мог положиться на Claude в написании большинства этих спецификаций. Я чувствовал себя комфортно только потому, что Cutlet был экспериментом. В проекте, на который я хотел бы поставить свою репутацию, я бы, возможно, вообще исключил агента из процесса и написал спецификации сам.
Вот мой общий рабочий процесс при внесении любых изменений в Cutlet:
- Сначала я представлял LLM новую функцию (например, циклы) или рефакторинг (рефакторинг) (например, переход от древовидного интерпретатора к байткодной виртуальной машине). Затем я вёл с ним беседу о том, как это изменение будет работать в контексте Cutlet, как другие языки это реализовали, какие есть проектные соображения, какие идеи можно позаимствовать из интересных/нишевых языков и т. д. Просто непринуждённый диалог, такой же, как вы ведёте с коллегой.
- Когда я хорошо представлял, как будет выглядеть функция или изменение, я просил LLM дать мне план реализации, разбитый на небольшие шаги.
- Я просматривал план и обсуждал с LLM для его доработки. Мы исследовали различные граничные случаи, подводные камни, ловушки, недостающие элементы и улучшения.
- Когда план меня устраивал, я просил LLM записать его в файл, который отправлялся в директорию
plans/doing/. Иногда для одной функции у нас получалось 3–4 файла планов. Это было намеренно. Мне нужно было, чтобы планы были читаемы для человека, и чтобы каждый план был атомарной единицей, которую я мог откатить, если что-то не сработает. Они также служили историей развития проекта. Все исторические файлы планов можно найти в репозитории Cutlet. - Я читал и рецензировал сгенерированный файл плана, снова обсуждал его с LLM для внесения изменений и фиксировал коммит, когда всё выглядело хорошо.
- Наконец, я запускал Docker-контейнер, запускал Claude со всеми правами — включая доступ
sudo— и просил его реализовать мой план.
Этот рабочий процесс переносил всю когнитивную нагрузку изменений на начало. Всё обдумывание происходило до написания единой строки кода — чего я почти никогда не делаю. Для меня программирование заключается в органическом обнаружении формы задачи в процессе работы. Однако я обнаружил, что такой подход плохо работает с LLM. Они отлично справляются с масштабными изменениями в кодовой базе, но ужасно — с быстрыми, итеративными, органическими рабочими процессами.
Возможно, мой рабочий процесс эволюционирует по мере ускорения inference (инференса) и улучшения моделей, но до тех пор лучше всего работает эта модель в стиле водопадной разработки.
Создание среды для эффективной работы агента
Я считаю это самой интересной и увлекательной частью работы с программирующими агентами. Это совершенно новый класс задач!
Ключевой принцип таков: программирующие агенты — это компьютерные программы, и поэтому у них ограниченное представление о мире, в котором они существуют. Их единственное окно в решаемую задачу — это директория с кодом, к которой они имеют доступ. Это не даёт им достаточно возможностей или информации для качественной работы. Поэтому, чтобы помочь им преуспеть, вы должны предоставить им эти возможности и информацию в виде инструментов, которые они могут использовать для взаимодействия с внешним миром.
Что это означает на практике? Для разных проектов это выглядит по-разному, но вот что я сделал для Cutlet:
- Полноценный набор тестов. Мои инструкции для проекта указывали Claude писать тесты и убеждаться в их падении перед написанием нового кода. Параллельно я просил его запускать тесты после значительных изменений в коде или слияния веток. Вооружённый постоянно растущим набором тестов, Claude мог быстро находить и исправлять любые регрессии, которые он вносил в кодовую базу. Тесты также служили документацией и спецификацией.
- Примеры входных и выходных данных. Это были мои интеграционные тесты. Я добавил ряд примеров программ в репозиторий Cutlet — большинство написано самим Claude — которые служат не только документацией для людей, но и комплектом сквозных тестов. Инструкции для проекта указывали Claude запускать их все и проверять вывод после каждого изменения кода.
- Линтеры, форматировщики и инструменты статического анализа. В Cutlet используются
clang-tidyиclang-formatдля обеспечения базового качества кода. Как и с тестами, инструкции проекта требовали от LLM запускать эти инструменты после каждого значительного изменения кода. Я заметил, чтоclang-tidyчасто выдавал диагностические сообщения, которые заставляли Claude переписывать части кода. Если бы у меня был доступ к более дорогим инструментам статического анализа (таким как Coverity), я бы добавил их в свой процесс разработки тоже. - Инструменты проверки безопасности памяти. Я попросил Claude создать таргет
make test-sanitize, который пересобирал весь проект и набор тестов с включёнными ASan и UBSan (с LSan, работающим через ASan), а затем запускал каждый тест в инструментированной сборке. Инструкции проекта включали запуск этой проверки в конце реализации плана. Это обнаруживало ошибки памяти — use-after-free, переполнение буфера, неопределённое поведение — которые не могли найти ни тесты, ни линтер. Запуск этих тестов занимал время и значительно замедлял агента, но они находили ещё больше проблем, чемclang-tidy. - Индексы символов. Агент имел доступ к
ctagsиcscopeдля навигации по исходному коду. Не знаю, насколько это было полезно, потому что я редко видел, чтобы он ими пользовался. В большинстве случаев он просто использовалgrepдля поиска символов. Возможно, в будущем я это уберу. - Инструменты интроспекции времени выполнения. На раннем этапе проекта я попросил Claude дать Cutlet возможность выводить поток токенов, AST и байткод для любого фрагмента кода в стандартный вывод перед его выполнением. Это позволяло агенту быстро определить, внёс ли он ошибки в какую-либо часть pipeline (конвейера выполнения) без необходимости навигации по исходному коду или запуска отладчика.
- Трассировка конвейера. Я попросил Claude написать Python-скрипт, который пропускает программу на Cutlet через интерпретатор с отладочными флагами, чтобы захватить весь конвейер компиляции: поток токенов, AST и дизассемблированный байткод. Затем он сопоставлял каждый тип токена, узел AST и опкод с точными местами в исходном коде парсера, компилятора и виртуальной машины, где они обрабатывались. Когда агенту нужно было добавить новую языковую возможность, он мог запустить трассировщик на примере похожей существующей возможности, чтобы увидеть, какие именно файлы и функции нужно затронуть. Я очень гордился этим механизмом, но так и не видел, чтобы Claude им активно пользовался.
- Запуск со всеми возможными правами. Я хотел, чтобы агент работал автономно и имел доступ к каждому отладочному инструменту, который мог ему понадобиться. Для этого я запускал его внутри Docker-контейнера с включённым
--dangerously-skip-permissionsи полным доступомsudo. Я считаю, что это единственный практичный способ использования программирующих агентов на крупных проектах. Отвечать на запросы разрешений когнитивно затратно, когда у вас пять агентов работают параллельно, а ограничение их возможностей делает их менее эффективными. Нам ещё предстоит решить множество вопросов безопасности, возникающих, когда вы даёте LLM возможность полного контроля над системой, но в этом проекте я был готов принять риски, связанные с YOLO mode (режимом полного автопилота).
Все эти инструменты и возможности гарантировали, что любые обновления кода приводили к проекту, который как минимум компилировался и выполнялся. Но что ещё важнее, они увеличивали количество информации и возможностей, доступных Claude, делая его более эффективным в обнаружении и отладке проблем без моего вмешательства. Если я продолжу работу над этим проектом, моим главным фокусом будет предоставление агентам ещё большего понимания артефакта, который они создают, ещё больше инструментов отладки, ещё больше свободы и ещё больше доступа к полезной информации.
Вам следует разработать собственный инструментарий, подходящий для вашего конкретного проекта. Если вы создаёте приложение на Django, возможно, стоит дать агенту доступ к тестовой базе данных. Если строите React-приложение — доступ к headless-браузеру. Единого ответа для всех проектов не существует, и я уверен, что люди придумают очень интересные инструменты, позволяющие LLM наблюдать за результатами своей работы в реальном мире.
Оптимизация агентного цикла
Программирующие агенты иногда бывают неэффективны в использовании предоставленных инструментов.
Например, работая над этим проектом, Claude иногда выполнял команду, решал, что её вывод слишком длинный для контекстного окна, и запускал её снова с выводом, перенаправленным через head -n 10. В других случаях он запускал make check, забывал применить grep к выводу для поиска ошибок и запускал его повторно для захвата вывода. Из-за этого одни и те же дорогостоящие проверки выполнялись несколько раз в ходе одной правки. Эти ошибки значительно замедляли агентный цикл.
Некоторые из этих узких мест производительности я мог исправить, отредактировав CLAUDE.md или изменив вывод пользовательского скрипта. Но некоторые проблемы требовали больших усилий для обнаружения и исправления.
Я быстро приобрёл привычку наблюдать за работой агента, замечать последовательности команд, которые агент повторял снова и снова, и превращать их в скрипты, которые агент мог вызывать вместо них. Многие скрипты в директории `scripts` Cutlet появились именно таким образом.
Это была очень ручная, совсем не весёлая работа. Я надеюсь, что со временем это станет более автоматизированным. Может быть, будущая версия Claude Code сможет анализировать результаты собственных вызовов инструментов и предлагать скрипты, которые вы могли бы для него написать?
Конечно, самой плодотворной оптимизацией был запуск Claude внутри Docker с --dangerously-skip-permissions и доступом sudo. Этим я убрал себя из агентного цикла. После создания файла плана я не хотел сидеть и нянчить агентов, нажимая Yes каждый раз, когда они хотят выполнить ls.
По мере развития Cutlet инфраструктура, которую я создал для Claude, тоже развивалась. В конце концов я оформил многие рабочие процессы, которым Claude естественно следовал, в виде скриптов, слэш-команд или инструкций в CLAUDE.md. Я также узнал, где агент чаще всего спотыкался, и предупреждал эти ошибки, давая ему лучшие инструкции или скрипты для выполнения.
Инфраструктура, которую я создал для Claude, была ценна и для меня, человека, работающего над проектом. Те же скрипты, которые помогали Claude автоматизировать его работу, помогали мне быстро выполнять типовые задачи.
По мере роста проекта эта инфраструктура будет продолжать эволюционировать вместе с ним. Модели постоянно меняются. Как и требования проекта, и рабочие процессы. Я рассматриваю всю эту проектную инфраструктуру как живой организм, который будет меняться, пока проект активен.
Мертва ли программная инженерия в привычном виде?
Теперь, когда отдельные разработчики могут достигать так много за такое короткое время, мертва ли программная инженерия как карьера?
Мой ответ на этот вопрос — нет, совсем нет. Навыки программной инженерии столь же ценны сегодня, как и до того, как языковые модели стали хороши. Если бы я не прошёл курс компиляторов в университете и не проработал книгу Crafting Interpreters, я не смог бы создать Cutlet. Мне всё ещё приходилось принимать технические решения, которые я мог принять только благодаря (некоторому) знанию предметной области и опыту.
Кроме того, мне пришлось освоить целый ряд новых навыков для эффективной работы над Cutlet. Эти новые навыки тоже требовали технических знаний. Странного и нового и иного рода технических знаний, но технических знаний тем не менее.
До этого проекта я переживал, будет ли у меня работа через пять лет. Но сегодня я убеждён, что миру и дальше будут нужны программные инженеры. Наши профессии трансформируются — и некоторым людям могут не понравиться новые обязанности — но работы для нас по-прежнему будет предостаточно. Возможно, у нас будет даже больше работы, чем раньше, поскольку LLM позволяют создавать намного больше программного обеспечения намного быстрее.
А для тех из нас, кто никогда не хочет прикасаться к LLM, останутся области, куда LLM так и не проникнут. Мои друзья, работающие над низкоуровневыми мультимедийными системами, добились меньшего успеха с LLM по сравнению с теми, кто создаёт веб-приложения. Скорее всего, так будет ещё много лет. В конце концов эти профессии тоже трансформируются, но это будет гораздо более медленный сдвиг.
Справедливо ли приписывать себе работу Claude?
Справедливо ли говорить, что я создал Cutlet? В конце концов, большую часть работы проделал Claude. Каков был мой вклад помимо написания промптов?
Более того, этот эксперимент удался только потому, что Claude имел доступ к множеству реализаций языков и книгам по информатике в своих обучающих данных. Без работы сотен программистов, учёных и авторов, которые бесплатно поделились своей работой с общественностью, этот проект был бы невозможен. Так кто на самом деле создал Cutlet?
У меня нет хорошего ответа на этот вопрос. Мне комфортно брать на себя заслугу за заботу и обслуживание программирующего агента в процессе генерации токенов, но я не чувствую чувства собственности над самим кодом.
Я не считаю это «моей» работой. Это не кажется правильным. Может быть, мои чувства изменятся в будущем, но я не очень понимаю, как именно.
Из-за моих сомнений относительно того, кому на самом деле принадлежит этот код, я не добавил лицензию в GitHub-репозиторий Cutlet. Cutlet принадлежит коллективному сознанию каждого проектировщика языков программирования, разработчика и преподавателя, выложившего свою работу в интернет.
(Также стоит отметить, что Cutlet почти наверняка содержит код из интерпретаторов Lua и Python. Модель постоянно ссылалась на эти языки, когда мы обсуждали языковые возможности. Я также собственными глазами видел, как тонны кода из Crafting Interpreters попадали в кодовую базу.)
Это не пошло на пользу моему ментальному здоровью
Был бы упущением, если бы не включил заметку о ментальном здоровье в эту и без того огромную статью.
Легко подсесть на инструменты агентной инженерии. Работая над этим проектом, я часто обнаруживал себя за компьютером в полночь со словами «ещё один промпт», как будто играл в самую экзотическую в мире партию Civilization. Мне неловко признавать, что я часто оставлял Claude Code работать в фоновом режиме, когда ко мне приходили гости, когда шёл в душ или уходил на обед. Это опьяняющее чувство — столько успеть за такое короткое время.
Ещё более затягивающей оказывается непредсказуемость и случайность, присущие этим инструментам. Если вы бросаете задачу Claude, никогда не знаешь, что он выдаст. Он может с первого раза решить сложную проблему, над которой вы бились неделями, или может устроить полный бардак. Как и с игровым автоматом, никогда не знаешь, что произойдёт. Это создаёт сильное побуждение пробовать использовать его для всего и всегда. И как с игровыми автоматами, казино всегда в выигрыше.
В наши дни я устанавливаю лимиты на то, как долго и как часто мне разрешено пользоваться Claude. По мере того как LLM становятся широкодоступными, нам как обществу придётся найти лучший способ использовать их, не разрушая своё ментальное здоровье.
В этой части я не очень оптимистичен. Мы полностью провалились в регулировании и ограничении использования социальных сетей, и я готов поспорить, что с LLM ситуация повторится.
Что делать с этими новыми суперспособностями?
Теперь, когда мы можем производить большие объёмы кода очень быстро, что мы можем делать такого, чего не могли раньше?
Это ещё один вопрос, на который у меня пока нет полного ответа.
Тем не менее, одна область, где я вижу непосредственную пользу LLM лично для себя, — это возможность очень быстро экспериментировать. Мне очень легко опробовать десять разных функций в Cutlet, потому что мне нужно всего лишь написать спецификацию и отойти от компьютера. Неудачные эксперименты практически ничего не стоят. Даже если я не могу использовать код, который генерирует Claude, наличие работающих прототипов помогает мне быстро проверять идеи и рано отбрасывать неудачные.
Я также смог радикально сократить зависимость от сторонних библиотек в своих проектах на JavaScript и Python. Я часто использую LLM для генерации небольших утилитарных функций, которые раньше требовали подключения зависимостей из NPM или PyPI.
Но если честно, это мелочи. Я не могу предсказать масштабные общественные изменения, которые произойдут благодаря ИИ-агентам. Всё, что я могу сказать: программирование в 2030 году будет радикально отличаться от программирования в 2026 году.
Что дальше с Cutlet?
Этот проект был проверкой концепции, чтобы понять, как далеко я могу продвинуть Claude Code. Сейчас я ищу новый контракт как фронтенд-инженер, поэтому у меня, вероятно, не будет времени продолжать работу над Cutlet. У меня также есть ещё несколько идей по развитию агентного программирования, так что я, скорее всего, буду отдавать им приоритет перед продолжением работы над Cutlet.
Когда будет настроение, я, возможно, буду время от времени добавлять небольшие функции в язык. Теперь, когда я убрал себя из цикла разработки, это не требует много времени и усилий. Может быть, я даже пройду Advent of Code на Cutlet в декабре!
Конечно, если вы работаете в Anthropic и хотите дать мне денег, чтобы я продолжил этот эксперимент, я доступен для контрактной работы на ближайшие 8 месяцев :)
А пока я закрываю главу Cutlet и перехожу к другим проектам (и коту).
Подпишитесь на канал и каждый день читайте лучшие материалы про AI переведенные на русский!
Нашли интересную статью для перевода? Пришлите нашему боту: @ailongreadsbot