Вайбкодинг: что дальше?
Агенты стали новой средой разработки, которая фактически заменяет существующие IDE. В ней, имея лишь промпт, вы можете выполнять все те же самые функции, что и в любой другой IDE (написание кода, тестов, рефакторинг, синтаксический анализ и проч.). Просто способ написания кода изменился. Вы на естественном языке пишете, что хотите сделать, и модель это реализует: ищет файлы, правит код, запускает команды.
Андрей Карпатый, 2 февраля 2025 года (перевод с английского):
Есть новый вид программирования, который я называю «вайбкодингом»: ты полностью отдаёшься вайбам, принимаешь экспоненциальный рост и забываешь, что код вообще существует.
Разумеется, это современный, прогрессивный метод, который дает серьезный буст в производительности по сравнению с ручным написанием кода. Однако на серьезных задачах со временем начинают проявляться его минусы, которые особенно видны на слабых моделях. Недостатки эти связаны с глобальным пониманием задачи моделью, отсутствием самоконтроля, ограничением контекста и другими проблемами, которые ведут к понижению качества. Для решения этих проблем приходится тратить больше времени на ревью кода, на общение с моделью по результатам ее реализации, на ручное управление контекстом и т.д. Я не раз ловил себя на мысли, что вот эту задачу я бы точно сделал сам быстрее. Часто модель репортует, что задача сделана, но на поверку выясняется, что решение половинчатое либо вообще нерабочее (хотя все тесты зеленые). Теряется доверие к ее результатам, и вы тратите по итогу больше времени на фиксы, чем потратили бы на самостоятельное решение задачи.
Конечно, это все не критично и лечится путем задания правил поведения, инструкций, скиллов. Со временем у вас будут скапливаться рабочие промпты, скиллы и спеки. Можно поставить плагины для динамического управления контекстом, выгрузки его в офлайн-хранилище и т.д. В целом с этим можно жить, но что делать, если вы хотите большего?
Почти эйфория
Первые месяцы, откровенно говоря, я был впечатлен промпт-инженерингом. Современные IDE с IntelliSense и IntelliCode понижают порог входа, говорите вы? Чепуха! Теперь вам вообще не нужно помнить синтаксис, библиотеку и конкретный API, вам достаточно описать словами на естественном языке, чего хотите, и все подключения сложных библиотек и вызовы их методов, которые раньше нужно было помнить либо искать и вручную кодить, магически сами собой появляются. Вам не нужно забивать голову мелочами: обвязку, конфиги, тесты, замеры производительности модель делает сама, пока вы держите в голове основной замысел.
Вы пишете промпт, агент выдает результат. Вам все нравится, вы сохраняете промпт и начинаете его применять регулярно для подобного класса задач. Со временем получается небольшая библиотечка промптов.
Для однотипных небольших задач вайбкодинг подходит идеально. Прототип, скрипт «на сегодня», демо идеи, проверка незнакомой технологии, написание тестов для готового кода. Однако даже на одинаковых задачах те же самые промпты порой выдают разные результаты. Кроме содержимого контекста на решения модели могут влиять совершенно случайные параметры. Вы даже можете управлять степенью случайности с помощью параметра temperature (обычно значения от 0 до 1). Низкие значения уменьшают случайность ответа, высокие увеличивают ее. Для автоматизации и большей предсказуемости результата промпт можно преобразовать в скилл. Скилл является пакетом инструкций, который состоит из описания и конкретного порядка действий.
При ежедневной практике за пару месяцев я набрал из промптов набор скиллов, которые помогли мне достичь повторяемости и определенного качества. Скиллы задавали паттерны поведения модели, чтобы ход ее мыслей шел в нужном мне направлении.
Порог сложности
Все же я искал что-то более системное, чем вайбкодинг. Для задач определенного объема вайбкодинг очень хорош, но когда задачи требуют большого контекста, состоят из массы требований и затрагивают большой кусок кода, подход буксует. Реализация не влезает в рамки одного промпта, автокомпакция контекста не является спасением, так как в ее процессе теряется информация. Да и лимиты на таких задачах улетают мгновенно, я уже молчу про стоимость вызовов по API.
Кроме повышенных требований к контексту, промпт/скилл не дает проверяемости. Проблема простых промптов и односложных скиллов в том, что они линейны. Большую задачу нужно декомпозировать на более мелкие и решать отдельно. Частично умные модели это умеют, но опять же от случая к случаю. Также нужна цикличность, которую пока могут дать только мультиагентские системы, где среда специально поднимает множество агентов на разных моделях и гоняет их, многократно передавая результаты работы друг другу.
Собственно примерно такую систему я и создал в рамках одного харнеса. За основу я взял управленческий цикл Plan-Do-Check-Act, добавил к нему специфику агентской разработки, наработки по другим моим скиллам, и получился отдельный скилл PDCA.
Скилл жестко задает рамки рассуждения модели и требует проверяемого результата: например, после изменений производительность не должна деградировать или покрытие тестами не должно упасть. Причем этот результат никак не вшит в скилл. Для каждой задачи критерии приемки свои и определяются на этапе планирования. Скилл цикличен, из шагов DO и CHECK мы можем возвращаться, и, по сравнению с линейной реализацией, скилл работает сильно дольше.
При таком подходе уже не побалуешься с простым рефакторингом. Но взамен я получил две важные вещи.
-
Результат, который стал проверяемым и предсказуемым.
-
Качество, которое стало заметно выше.
Как работает скилл
Скилл определяет несколько фаз (ролей) и правила перехода между ними. За ролями закрепляется набор функций и прав. У роли есть атрибут: тир, который описывает сложность задач, которые возлагаются на эту роль. Сложность задач определяет модель, которая больше всего подходит для их решения. Я выделил три уровня: cheap / medium / strong. Тир это показатель стоимости и качества модели. Другой атрибут роли: права. Они также зависят от решаемых задач. Сильная модель, как это ни странно, будет иметь меньше прав, чем дешевая. Об этом эффекте будет изложено в разделе экономики. В различных харнесах роли реализуются по-разному, лично я сижу в opencode и там это отлично ложится на сущности субагентов. Скилл ничего не знает про модели и права, он оперирует только ролями. Харнес реализует роль с помощью субагентов, задавая им конкретные модели и права.
На вход скилл получает задачу или цель. Она не может быть изменена или переформулирована внутри скилла (это допускается только пользователем). Если скилл понимает, что она недостижима, цикл останавливается.
После планирования рождается статус-файл, и он же является основным артефактом работы скилла.
Вся работа выполняется субагентами, реализующими определенные роли:
|
Роль |
Что делает |
Тир |
|---|---|---|
|
Скаут (GATHER) |
Собирает указатели file:line, URL, числа; без рекомендаций |
cheap |
|
Аналитик (PLAN) |
Цель, критерии приемки, декомпозиция, риски, способ проверки |
medium |
|
Исполнитель (DO) |
Правит файлы, запускает команды, ведет статус-файл |
cheap |
|
Аудитор (CHECK) |
Независимо проверяет каждый критерий по фактическим свидетельствам |
medium |
|
Эксперт (ESCALATE) |
Инстанция для трудных решений |
strong |
|
Оркестратор (RUNNER) |
Ведет цикл, ничего не читая и не правя |
cheap |
Далее в скилле задаются правила взаимодействия ролей:
-
Оркестратор ведет цикл, но ничего не читает и не меняет. Как правило, это первичный агент на дешевой или бесплатной модели. Он диспетчеризует роли через Task (инструмент запуска субагента) и передает им информацию друг от друга. План он не пишет, файлы не читает, команды не запускает; исключение: обновление прогресса выполнения (списка задач).
-
Скаут: универсальная роль, которая используется всеми недешевыми моделями для перелопачивания сырой информации.
-
План всегда за аналитиком. Он и составляет начальный план, и пересматривает его, когда приходит соответствующий сигнал.
-
Писать и запускать может только исполнитель, включая статус-файл.
-
Аудитор собирает доказательства (с помощью скаута) выполненной работы. Он получает отчет от исполнителя, критерии приемки от аналитика и пытается самостоятельно и независимо оценить достоверность результата.
С помощью механизма разграничения прав в харнесе задаются ограничения для ролей:
-
писать и запускать (exec) может только исполнитель, иначе источник изменений размножается.
-
чтение есть только у исполнителя, скаута и эксперта
-
Средние и сильные тиры не работают с сырой информацией. Прочитанный файл или скачанная из интернета документация попадает в контекст целиком, хотя для принятия решения, возможно, нужна только одна строчка. Поэтому сырые данные читает только скаут и возвращает указатели оркестратору, который дальше диспетчеризует это более сильным ролям.
Технические подробности
Машина состояний скилла выглядит так:
PLAN. Аналитик декомпозирует цель и отвечает на вопрос, какой результат нужен. Декомпозиция идет до атомарных неделимых задач с четкими границами, юнитов. Юнит это один проверяемый кусок работы со своими критериями приемки. Обязательные поля плана:
-
ожидаемый результат;
-
ограничения и допущения;
-
измеримые критерии приемки;
-
декомпозиция с зависимостями или явное решение не дробить;
-
средства и доступ;
-
риски и условия остановки.
DO. Исполнитель делает только то, что сказано в плане; изменения за пределами юнита запрещены. После завершения работы он возвращает оркестратору по сути черновик, корректность которого проверяет аудитор.
CHECK. Аудитор судит каждый ответ по фактическим свидетельствам и проверяет, что они не противоречат друг другу. Аудитор формирует вердикт в терминах критериев приемки и отдает его оркестратору. Дефект реализации возвращается в DO, неверный план в PLAN.
ACT. Завершает цикл: фиксирует выводы, ограничения, статус и передачу дел, финализирует статус-файл.
Если выясняется, что перед текущим юнитом нужно сделать еще один (DO может вернуть работу в PLAN, переведя текущий юнит в блок), то аналитик добавляет новый активный юнит. Когда новый юнит выполнится, исходный разблокируется и продолжает с теми же критериями.
Если исходный юнит больше недостижим, его вытесняет новый, а исходный помечается superseded. Чтобы при вытеснении не потерять требования, новый юнит наследует все критерии исходного, и CHECK проверяет их по прежнему сценарию.
Исполнение не может перейти от одного состояния в другое, пока не пройдет гейт:
-
План → DO: все обязательные поля на месте, план записан в статус-файл, получено подтверждение от пользователя или работа в автономном режиме.
-
DO → CHECK: все активные, не вытесненные юниты done со свидетельствами.
-
CHECK → ACT: все критерии проверены, ни одного несоответствующего или непроверенного.
-
ACT → EXIT: результат и статус-файл финализированы.
-
STOP: отдельная финализация, вне ряда переходов выше.
Так как граф допускает возвраты, то необходимо вести счетчик циклов. Оркестратор ведет три счетчика:
-
N: номер цикла задания в имени файла .pdca/status/<task>-<N>.md; растет только в ACT, когда планируется следующий цикл того же задания.
-
r: ревизия плана; растет только при действительно другом плане (DO или CHECK могут запросить изменение плана).
-
n: попытка исполнения текущей ревизии: старт с 1, переход CHECK → DO увеличивает на 1, новая ревизия сбрасывает в 1.
Также ведется история дефектов. Она не стирается ни пересмотром планов, ни новой сессией, она нужна, чтобы не зациклиться на одной и той же ошибке.
Счетчики и история живут в статус-файле.
Оркестратор передает управление Эксперту, когда попытка исполнения n становится равной трем, т.е. Аудитор три раза отклонил реализацию. У Эксперта в таком случае есть два варианта:
-
Дать новую вводную для перепланирования (вернуть в PLAN). В этом случае r увеличивается, n сбрасывается.
-
Не найти решения и остановить цикл.
Если Аудитор принял реализацию, он выносит свой вердикт и Оркестратор переходит к шагу ACT, когда цикл завершается.
Пример реальной задачи
В одном большом и сложном проекте была задача, при реализации которой скилл pdca четыре раза возвращался к одной задаче:
Цикл 1
Оркестратор решил остановить работы, так как эскалация не нашла подтверждения от пользователя, что план одобрен.
Цикл 2
-
Аудитор три раза не принял юнит, произошла эскалация. Эксперт работу принял.
-
Следующий юнит также провалился три раза и в этот раз Эксперт работу не принял, задача осталась незавершенной.
Цикл 3
Я подключился к решению вопроса и указал, что тот критерий приемки, который провалил предыдущую ревизию, мы исключаем (с записью в статус-файл). Попросил продолжить работу дальше. Следующий юнит, который должен был выполнить другой замер, также был отклонен Аудитором. Опять случилась эскалация, при которой Эксперт вынес решение, что мы завершаем задачу как выполненную, но с записанными ограничениями.
Цикл 4
Задача опять попала ко мне, я опять переформулировал требования и отдал ее на доработку. С новой реализацией Аудитор на первой итерации нашел 6 дефектов и передал исполнителю на переделку. Повторный дефект исполнителя ушел в Эксперта, который принял работу частично и попросил перемерить один аспект. Измерения дали положительный результат, и задача наконец была окончательно закрыта.
Эксперимент
После того, как скилл более-менее устоялся, я захотел его проверить и устроил эксперимент. Взял одну и ту же задачу в проекте (довольно сложный проект, в котором нужно было добавить динамические колонки) и дал ее решить одной и той же модели (DeepSeek V4.1 Flash), в трех разных средах: в чистом виде без скиллов, со скиллом-инструкцией на восемь шагов (один из моих предыдущих очень успешных скиллов) и с новым скиллом pdca. Каждый эксперимент был в отдельном клоне репозитория, без истории и без готового ответа. Отдельно прогнал эталон (рабочие настройки ролей) на рабочей ветке: та же фича, сделанная тем же циклом, но с использованием дорогих моделей: планирование и проверка на средней модели, эскалация на сильной.
|
среда |
время |
файлов |
своих тестов |
P0-дефектов |
стоимость |
|---|---|---|---|---|---|
|
без скиллов |
16 мин |
32 |
2 |
5 |
$0.20 |
|
очень хороший скилл |
30 мин |
37 |
7 |
4 |
$0.33 |
|
цикл, все роли на дешевой модели |
78 мин |
55 |
19 |
2 |
$1.19 |
|
цикл с использованием дорогих моделей |
≈40 мин |
48 |
16 |
2 |
$0.76 |
Что мы видим: вайбкодинг безусловный лидер по времени исполнения, стоимости и количеству дефектов. Мой предыдущий скилл, который родился из промптов, несколько лучше сделал работу, но в два раза медленнее. А вот скиллы pdca чемпионы по качеству. Они написали значительно больше тестов и оставили вдвое меньше критичных дефектов. Также можно заметить, что обычный линейный скилл в два раза дешевле, чем скилл pdca, но и в два раза менее качественный.
Экономика тиров
Формализованный скилл дороже по времени, токенам и деньгам. Это верно, пока сравнение идет с одним-двумя промптами. На простых задачах, где контекст никуда не теряется, вайбкодинг дешевле, и цикл не нужен. На сложных цена вайбкодинга складывается из множества перезапущенных сессий, повторных объяснений задачи, ревью кода и часов разработчика на восстановление нити рассуждений. Чем сложнее задача, тем дороже и неэффективнее вайбкодинг. Поэтому, если мы хотим сравнить по деньгам, то сравнивать нужно не «промпт против цикла», а «день вайбкодинга против дня в цикле».
В хорошо декомпозированной задаче почти все токены уходят на механическую работу по чтению/правке файлов, прогону инструментов и т.д. Принятие решений случается редко и выражается в коротких ответах, поэтому сильные модели имеют меньший набор прав, чтобы не забивать контекст и не тратить токены на объемную и механическую работу.
Срез с моего реального использования: 12 часов работы, 159 сессий, 3829 сообщений, $7.34.
|
Тир |
Сообщений |
Вход, ток. |
Выход, ток. |
Стоимость |
Доля бюджета |
|---|---|---|---|---|---|
|
cheap |
3485 (91%) |
371.1M |
3.12M |
$4.44 |
60% |
|
medium |
113 (3%) |
3.36M |
116.5k |
$2.70 |
37% |
|
strong |
4 (0.1%) |
50.4k |
11.5k |
$0.20 |
3% |
Вход здесь: все входные токены, включая чтение и запись кэша; выход: ответ вместе с reasoning.
За двенадцать часов сильный тир понадобился только четыре раза. Он почти не работает по сравнению с другими ролями, поэтому его относительная дороговизна теряется в общих расходах. Средний тир подключался значительно больше. Это говорит о том, что было много проверок дешевого тира и большое количество раундтрипов и возвратов в DO. Это дорого, но тоже меньше 40% от общих расходов.
У дорогих моделей разница между записью в кэш и чтением из него кратная: в моем сетапе на strong чтение $0.2/M против записи $5/M, в 25 раз. Замер на живом сеансе: теплый повторный ход с полным попаданием в кэш обошелся в $0.0034 против $0.0794 у холодного, в 23 раза дешевле.
Наибольший источник расходов: собственно кодинг. И неудивительно, если посмотреть на количество токенов, которое он перелопатил за это время. Если предположить, что это бы делала средняя модель, то один кодинг за эти двенадцать часов стоил бы около $59 вместо $2.76, а вместе со скаутом около $75 вместо $3.74. На флагманских моделях это было бы уже около $150, и это без учета записи и чтения кэша, которые у дорогих моделей платные.
Выводы
Скилл выполнил большое количество боевых задач и успешно справился с их сложностью и размером. Он не стремится во что бы то ни стало удовлетворить запрос пользователя, просто он не говорит «готово», пока не проверит результат, потому что «готово» и «не готово» для него равнозначные итоги. Скилл пометит задачу incomplete, если определенные при планировании критерии приемки не прошли.
Работа над любой сложной задачей итеративна, вы не можете все сделать за один присест. Модель не исключение, она точно так же намного лучше справляется с задачами, когда их планируют, декомпозируют, проверяют, возвращают на доработку и извлекают уроки.
Скилл потребляет больше токенов. Работают несколько ролей, часть на среднем и дорогом тирах, а независимая проверка требует свежих прогонов. Скилл более сложен в плане устройства и в плане эксплуатации. Нужно поднять роли и тиры, следить за статус-файлом и гейтами. Порог входа выше, чем у одного промпта.
На маленькой разовой задаче цикл pdca не окупится: там проще подсказать модели вручную, что и где поправить. Цикл стоит брать для длинных задач с большим контекстом, где вам важен результат и качество.
Заключение
Результатам моей работы со скиллом я доволен. Конечно, в нем еще есть шероховатости, и почти каждый день я вношу в него изменения, но он уже предоставляет код сильно большего качества и реально экономит ресурсы, позволяя оставаться в лимитах подписок моделей.
Открытый код
Скиллы, о которых шла речь (pdca и прикладные pdca-coder, pdca-dotnet, pdca-collection), открыты: https://github.com/AlexeyShirshov/skills.
Автор: AlexeyShirshov

