Разговоры ничего не стоят. Код тоже. adsm.. adsm. agents.. adsm. agents. cdd.. adsm. agents. cdd. codex.. adsm. agents. cdd. codex. llm.. adsm. agents. cdd. codex. llm. искусственный интеллект.

В наше время известное изречение Линуса Торвальдса “Talk is cheap. Show me the code.” можно переиначить в виде “Code is cheap. Show me the spec.” Меня зовут Алекс Гусев и в этой публикации я постараюсь показать, почему я так считаю.

У меня есть несколько статей на Хабре, объединённых общей темой: ADSM (Agent Driven Software Management). По сути, это моя попытка формализовать свой личный опыт в Spec-Driven Development (SDD) в какое-то подобие методологии. Под катом я поделюсь результатами применения SDD-подхода (в его ADSM виде) к разработке простого приложения – помощника в создании плейлистов в Spotify. И покажу, что будет, если на базе одного и того же контекста (спецификации) сгенерировать код одним и тем же агентом (Codex, GPT-5.4) с разным уровнем reasoning’а (high, medium, low).

Разговоры ничего не стоят. Код тоже - 1

Предыстория

Нам для одного из семейных мероприятий понадобился плейлист на 4-5 часов на определённую тему. ChatGPT хорошо справился с задачей и выдал список из 100 музыкальных произведений с названиями и авторами. Оставалось сформировать плейлист для Spotify. Раньше мы делали это вручную и времени уходило порядком, но сейчас такие вещи легко поддаются автоматизации через ИИ-агентов.

Я уверен, что кто-то может навайбкодить подобное приложение за полчаса, а то и за десять минут. Но во-первых, я не умею вайбкодить, во-вторых, я умею SDDевелопить. Поэтому, на создание первой версии приложения у меня ушло 2 часа чистого времени.

История

До того, как я занялся реализацией этого проекта, я вообще был не в курсе о каких-либо возможностях интеграции Spotify с внешними приложениями. ChatGPT подсказал мне адрес https://developer.spotify.com/ и объяснил, что и где нужно прописать, чтобы зарегистрировать своё приложение.

Оказалось, что аутентифицироваться в Spotify нужно по протоколу OAuth. А для этого нужно иметь свой домен и TLS-сертификат. Домен у меня был, сертификат делается через Let’s Encrypt. Я уже давно пишу только на JavaScript, поэтому выбор ЯП был безальтернативен. Как и выбор платформы – только TeqFW, только хардкор!

Создал приватный репозиторий на GitHub’е, склонировал на локалку. Добавил в контекст (./ctx/spec/) типовой код для nodejs-приложений на базе моей библиотеки @teqfw/di. Где-то около часа с небольшим я в VSCode обсуждал в диалоге с Codex-агентом детали будущей реализации – как запускать, как конфигурировать, какие зависимости тянуть. Агент всё это аккуратно фиксировал в контексте проекта (каталог ./ctx/docs/). Затем я попросил агента создать ./package.json, bootstrap-файл ./bin/cli.mjs и головной скрипт приложения ./src/Main.mjs. После чего попросил создать в две итерации: 1) интеграционные тесты и код для получения и сохранения токена аутентификации через веб-сервер; 2) загрузку и парсинг текстового файла с музыкальными композициями, поиск произведений в Spotify и формирование плейлиста (тоже интеграционные тесты и исходники). Соответствие формата es6-модулей требованиям своей платформы я верифицировал по скиллу teq-esm-validator.

Я проверял работу приложения по частям (каркас – просто запуск; получение токена аутентификации; разбор файла и поиск композиций; создание плейлиста и добавление в него найденных композиций). Итого, чуть больше, чем через два часа чистого времени в моём Spotify этим приложением был создан новый плейлист из 80+ композиций. Остальные композиции из списка не были обнаружены в Spotify.

Последствия

Я время от времени вижу в комментах на Хабре, что коллеги высказывают мысль, что LLM-агенты неприменимы в разработке, потому что от них нельзя получить детерминированный результат. Но для меня до сих пор программирование – это всё ещё отчасти искусство. Если бы Леонардо да Винчи рисовал свою Джоконду десять раз, то он бы нарисовал десять разных картин, на которых была бы изображена одна и та же женщина. Если любой программист десять раз реализует достаточно сложное приложение, то это будет десять разных приложений с одним и тем же, заданным, функционалом.

детерминированность результата” != “детерминированность кода

Для демонстрации этой идеи я опубликовал оригинальный код, созданный Codex-агентом (GPT-5.4, high reasoning) под версией 1.0.0. Только код, контекст я специально вырезал. Затем я попросил Codex-агента (GPT-5.4, medium reasoning) удалить папки ./src/ & ./test/ и на основе того же самого, неизменённого контекста из папки ./ctx/ создать с нуля тесты и исходники (для экономии я оставил прежние package.json и boostrap-файл). Получилась версия 2.0.0. Затем то же самое проделал на GPT-5.4, low reasoning – версия 3.0.0.

Промпт для перегенерации исходников

Удали все файлы из каталогов src, test. Подними в package.json версию до 3.0.0. Ознакомься с документами контекста (./ctx/). Посмотри, как запускается приложение. Создай интеграционные тесты для продукта (ctx/spec/code/platform/teqfw/quality/testing/overview.md). После этого создай полнофункциональный код продукта (согласно правилам платформы TeqFW), проверь по интеграционным тестам. Проверь код в src/ через скилл teq-esm-validator. Исправь найденные ошибки и снова проверь по интеграционным тестам. Собери юнит-тесты для проверки исходников (ctx/spec/code/platform/teqfw/quality/testing/unit.md). Обнови README.md с учётом, что это третья версия приложения, созданная агентом Codex GPT-5.4 на reasoning-уровне Low. Не надо поднимать прошлую реализацию из git-истории. Проектируй с нуля. В этом смысл этой итерации.

Вот сводка по созданным исходникам, сделанная агентом:

Версия

Файлы в src

Каталоги в src

Строк всего

Код

Комментарии

Пустые

1.0.0

23

9

1546

983

404

159

2.0.0

18

10

1436

844

462

130

3.0.0

20

10

993

665

274

54

Можно зайти по ссылкам и посмотреть на получившийся код – он не идентичен. Можно установить любую из версий, получить токен аутентификации со Spotify и создать плейлисты – работает одинаково.

Замечания

У меня ушло довольно много времени (месяцы) на создание спецификаций для моего стиля разработки (./ctx/spec/code/platform/teqfw/) и я всё ещё продолжаю развитие этой документации. Но это часть контекста, переиспользуемая между всеми моими проектами. И мне потребовалось пару часов на описание продукта (создание документов в пространстве ./ctx/docs/). Но на генерацию тестов и кода каждой из версий у агента ушло в районе 10 минут. И что интересно, вне зависимости от reasoning-уровня у меня ушло порядка 4% недельной квоты от plus-подписки на ChatGPT на генерацию каждой из версий.

Все три версии затупили с созданием плейлиста в Spotify. Dry-запуск они проходили и треки искались, но при попытке добавления треков в плейлист все три раза агент использовал устаревший API и приходилось ему каждый раз указывать на эту ошибку. Если бы я не старался делать более-менее чистый эксперимент, я бы внёс в когнитивный контекст требование использовать новый API от Spotify, но я специально выполнял генерацию кода на одном и том же контексте. Так что помимо детерминированности результирующего функционала также проявилась и детерминированность ошибок прочтения контекста агентом.

Третья версия, которая делалась low-reasoning агентом, не справилась с запуском веб-сервера. Вернее, справилась – веб-сервер стартовал, но приложение сразу же его глушило, не дожидаясь получения токена аутентификации от Spotify. На уровнях high & medium такой проблемы не возникло.

Для понимания соотношения объёма документов контекста (ctx) к результирующему коду (см. таблицу выше):

Файлы в ctx

Каталоги в ctx

Строк всего

Пустых

53

27

5378

1869

Что касается объёма в байтах, то сводка такая:

Файлы в ctx

src v1 (high)

src v2 (medium)

src v3 (low)

152Kb

48Kb

42Kb

36Kb

Да, это моя осознанная позиция: документы контекста по объёму должны быть в разы больше результирующего кода.

Скиллы

Отдельно нужно выделить скиллы. Моя платформа использует позднее связывание исходников в момент выполнения. Все зависимости внедряются через конструктор. А это значит, что во всех файлах из каталога ./src/ нет статических импортов. Ни одного. Это довольно нетрадиционный подход к JS-кодированию и агенты очень плохо в него умеют.

Когда я столкнулся с упорным желанием агентов создавать классический исходный код (с ранним связыванием кода при помощи статических импортов), мне пришлось сделать свой скилл – teq-esm-validator. Его, кстати, тоже делал Codex-агент по той же методологии ADSM. После этого было достаточно в промпте указать, что нужно использовать этот скилл для проверки исходников, и проблема со связыванием очень сильно уменьшилась. По крайней мере, в этом проекте с плейлистом в Spotify она не возникла ни разу.

Заключение

Я сравниваю поведение LLM-агентов при генерации кода с поведением дождевой воды, которая следуя изгибам рельефа, собирается в струйки, в ручьи, в реки и стремится к океану. Так же и агент генерирует код – следует по пути наименьшего сопротивления. Документы контекста в этой аналогии играют роль плотин и каналов, а скиллы и тесты я бы сравнил с насосами, забрасывающими воду на другой уровень (шлюзование). Оттуда вода опять может течь вниз, но уже по другому пути.

Основные затраты в таком подходе – это инфраструктура (те самые плотины, каналы, шлюзы). Но зато потом, после создания этой инфраструктуры, вода в большинстве случаев попадёт туда, куда было задумано строителями. Код в моём представлении – это не конечный артефакт, а производный. Результат взаимодействия когнитивного контекста и агента.

Именно исходя из этих соображений я и считаю, что контекст проекта (те самые 53 файла в ./ctx/), важнее самого кода (18-23 файла в ./src/). Ведь когда у тебя есть контекст, агент тебе сделает нужный код в течение минут. Даже такой экзотический, как TeqFW.

Вы можете свободно изучать код всех трёх версий – он дешёвый. Но если вы хотите увидеть контекст проекта – стучите в личку. Я дам контекст бесплатно, в обмен на обратную связь о возможности применимости данного подхода в ваших проектах.

P.S.

И немножко прекрасного. ИИ-агенты спокойно вытягивают “бойлерплейт” и делают ненужными множественные зависимости в ./node_modules/:

Зависимости в node_modules

Зависимости в node_modules

Им ничего не стоит захардкодить Web API и перехардкодить его в случае изменений. В моём приложении всего две зависимости для режима runtime (мои собственные библиотеки) и ещё две зависимости для dev-режима (разрешение типов Node.js).

Автор: flancer

Источник