---
title: "Разговоры ничего не стоят. Код тоже"
date: 2026-04-15
---

<zoom-img src="/img/blog/2026/20260416-01-cost-of-ai-code.png"
        alt="Разговоры ничего не стоят. Код тоже" width="100px"></zoom-img>

В наше время известное изречение Линуса Торвальдса "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
(<a href="https://www.npmjs.com/package/@flancer32/spotify-playlist"
target="_blank" rel="noopener">@flancer32/spotify-playlist</a>). И
покажу, что будет, если на базе одного и того же контекста
(спецификации) сгенерировать код одним и тем же агентом (Codex, GPT-5.4)
с разным уровнем reasoning'а (high, medium, low).

## Предыстория

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

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

## История

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

Оказалось, что аутентифицироваться в 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-модулей требованиям своей
платформы я верифицировал по скиллу <a
href="https://www.npmjs.com/package/@flancer32/skill-teqfw-esm-validator"
target="_blank" rel="noopener">teq-esm-validator</a>.

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

## Последствия

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

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

Для демонстрации этой идеи я опубликовал оригинальный код, созданный
Codex-агентом (GPT5.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   Каталоги в 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

Можно зайти <a
href="https://www.npmjs.com/package/@flancer32/spotify-playlist?activeTab=versions"
target="_blank" rel="noopener">по ссылкам</a> и посмотреть на
получившийся код - он не идентичен. Можно установить любую из версий,
получить токен аутентификации со Spotify и создать плейлисты -
<a href="https://www.npmjs.com/package/@flancer32/spotify-playlist"
target="_blank" rel="noopener">@flancer32/spotify-playlist</a> работает
одинаково.

## Замечания

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

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

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

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

    Файлы в ctx   53
    Каталоги в ctx 27
    Строк всего   5378
    Пустых        1869

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

    Файлы в ctx   152Kb
    src v1 (high) 48Kb
    src v2 (medium) 42Kb
    src v3 (low) 36Kb

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

## Скиллы

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

Когда я столкнулся с упорным желанием агентов создавать классический
исходный код (с ранним связыванием кода при помощи статических
импортов), мне пришлось сделать свой скилл - <a
href="https://www.npmjs.com/package/@flancer32/skill-teqfw-esm-validator"
target="_blank" rel="noopener"><code>teqesm-validator</code></a>. Его,
кстати, тоже делал Codex-агент по той же методологии ADSM. После этого
было достаточно в промпте указать, что нужно использовать этот скилл для
проверки исходников, и проблема со связыванием очень сильно уменьшилась.
По крайней мере, в этом проекте с помощью создания плейлистов в Spotify
она не возникла ни разу.

## Заключение

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

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

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

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

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

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