i
ДАТАИСТ
Обзор · 2026-07-31

Что помогает ИИ лучше писать код с нуля

Обложка: Что помогает ИИ лучше писать код с нуля

Сначала понять, потом писать

ИИ-агенты уже неплохо чинят код, дописывают функции и разбираются в чужих репозиториях. Но если попросить их собрать программу с нуля, ситуация резко меняется. Особенно когда исходников нет, а есть только README и готовый бинарник, который можно запускать как черный ящик. На таких задачах даже лучшие на данный момент модели часто проваливаются.

Авторы работы SpecFirst предлагают идею: прежде чем писать код, сначала разберись, что программа вообще должна делать. Не по верхам, не на лету, а в отдельной фазе. Сначала спецификация поведения, потом реализация.

И это меняет результат заметно сильнее, чем можно было ожидать от такого простого шага.

В чем проблема у обычных агентов

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

На бумаге это выглядит разумно. На практике ломается сразу в нескольких местах.

🟠 Агент слишком рано начинает писать код и не успевает нормально исследовать поведение программы.
🟠 По ходу длинной сессии он теряет важные детали, которые сам же выяснил в начале.
🟠 Ранняя ошибка в понимании задачи тянется через весь проект и заражает последующие решения.

Авторы показывают это на бенчмарке ProgramBench. Там задача жесткая: нужно восстановить программу с нуля, имея только текстовое описание и исполняемый файл без исходников. Скрытые тесты потом проверяют, насколько новая реализация повторяет поведение оригинала.

Результат отрезвляет: даже очень сильные модели полностью решают меньше 1% задач. То есть дело не в том, что моделям не хватает «еще немного интеллекта». Проблема в самом способе работы.

Что предлагает SpecFirst

Идея SpecFirst проста: разделить одну большую задачу на две отдельные.

Сначала работает специальный агент спецификации. Его единственная цель — понять поведение программы. Он читает документацию, запускает бинарник разными способами, вызывает команды с разными флагами, проверяет ошибки, редкие случаи, формат вывода. И по итогам пишет структурированный файл `SPEC.md`.

Потом подключается агент для программирования. Он получает документацию, бинарник и уже готовую спецификацию поведения. И только после этого начинает писать реализацию.

Схема SpecFirst: поверх обычного конвейера добавляется отдельный агент спецификации, который сначала собирает требования к поведению программы.

В обычном режиме агенту приходится одновременно исследовать систему и строить ее копию. В SpecFirst эти роли разведены. Один агент отвечает за понимание, другой — за код.

Зачем это нужно:

🟣 Спецификация становится внешней опорой. Важные детали не растворяются в длинном контексте.
🟣 Неясности в документации можно снять до начала реализации.
🟣 Агент для программирования меньше гадает и больше реализует уже выясненное поведение.
🟣 Если что-то было понято правильно на раннем этапе, это остается в `SPEC.md` и не теряется через 50 ходов.

Как агент собирает спецификацию

Авторы не ограничились общей идеей «пусть агент поизучает бинарник». Они описали, как именно он это делает.

Агент спецификации работает через обычную оболочку. Он запускает программу с разными аргументами, подает ввод через стандартный поток, читает `stdout`, `stderr` и код завершения. Для интерактивных программ используют виртуальный терминал.

Главное здесь — сами шаблоны исследования. Агент не просто хаотично тыкает в команды, а целится в те зоны, которые документация почти всегда описывает плохо.

🟠 Проверка границ: пустой ввод, слишком длинные строки, специальные символы, предельные значения.
🟠 Проверка ошибок: неверные аргументы, конфликтующие флаги, отсутствующие обязательные параметры.
🟠 Проверка сочетаний флагов: что происходит, когда опции используются вместе.
🟠 Уточнение формата вывода: порядок полей, разделители, пробелы, переводы строк.

Итогом становится не сырая стенограмма сессии, а компактный структурированный документ из шести разделов: обзор, флаги, ввод, формат вывода, ошибки, редкие случаи.

Это важно, потому что для следующего агента нужна не просто куча наблюдений, а рабочая инструкция по поведению программы.

Авторы отдельно запрещают короткие пути. Агент не может искать исходники в сети, скачивать пакет из реестра, запускать декомпиляторы или как-то анализировать бинарник изнутри. Только черный ящик: запускай, смотри, записывай выводы. Иначе задача теряет смысл.

Как это проверяли

Оценка сделана на всех 200 задачах ProgramBench. Это реальные консольные программы из открытых проектов: от утилит на Go и Rust до более крупных инструментов вроде SQLite, FFmpeg и интерпретатора PHP.

Сравнение честное: один и тот же базовый агент, те же модели, те же условия. Меняется только одно — есть ли перед написанием кода отдельная фаза спецификации.

Проверяли четыре модели:

🟣 Qwen3.5-397B-A17B
🟣 Qwen3.6-35B-A3B
🟣 GPT-5.5-high
🟣 GPT-5.4-mini

Главная метрика — доля скрытых тестов, которые проходит восстановленная программа. Это разумный выбор: полное совпадение с оригиналом здесь редкость, поэтому важно видеть и частичный прогресс.

Что получилось

Результат у SpecFirst стабильно лучше на всех четырех моделях. Прирост по средней доле пройденных тестов составил от 6,9% до 21,3%.

🟠 Qwen3.5-397B33,66%40,84%
🟠 Qwen3.6-35B27,51%31,40%
🟠 GPT-5.5-high59,02%65,14%
🟠 GPT-5.4-mini39,09%41,78%

У GPT-5.5-high картина особенно интересная не только по среднему баллу. SpecFirst заметно увеличивает долю почти идеальных решений:

🟣 задач с результатом не ниже 90% стало 16,5% вместо 5,5%
🟣 задач с результатом не ниже 95% стало 6,5% вместо 1,5%

То есть подход не просто немного поднимает среднее. Он чаще доводит решения до состояния, когда программа повторяет почти все поведение оригинала.

Почему это работает

Авторы показывают, что дело не только в «дополнительном шаге», а в изменении поведения агента во время работы.

Во-первых, SpecFirst действительно исследует программу шире. Для этого измеряли покрытие исследования: какую долю строк в исходной программе агент вообще затронул через свои запросы к бинарнику. Понятно, что агент не видит исходники, но исследователи инструментировали эталонные программы и смотрели, какие участки кода были реально вызваны во время зондирования.

SpecFirst выигрывает и здесь: итоговое покрытие исследования выше на 9,4–18,5% в зависимости от модели.

🟠 У Qwen3.5-397B суммарное покрытие: 59,8% против 51,9%
🟠 У Qwen3.6-35B: 58,3% против 49,2%
🟠 У GPT-5.5-high: 60,3% против 55,1%
🟠 У GPT-5.4-mini: 58,6% против 52,1%

Важно и то, откуда берется этот прирост. Его дает именно агент спецификации. Агент для программирования потом исследует меньше, потому что ему уже есть на что опереться.

Размер восстановленной кодовой базы по ходу работы: с предварительной спецификацией агент раньше начинает писать код и дольше держится в фазе реализации.

Во-вторых, меняется сам ритм работы. Когда у агента есть `SPEC.md`, он начинает писать код раньше и пишет его дольше, без постоянных возвратов в режим разведки. Грубо говоря, обычный агент много мечется между «еще чуть-чуть проверить» и «пора уже писать код». SpecFirst убирает эту дерготню.

Авторы измерили это по росту размера кодовой базы в ходе сессии. С предварительной спецификацией кривая роста поднимается раньше, а итоговый размер реализации получается больше. Финальные кодовые базы были на 7–29% крупнее в зависимости от модели. Это похоже не на бессмысленный раздув, а на более полную реализацию функций.

Пример, где обычный подход путается

В статье есть показательный случай с утилитой `gomplate`. Это шаблонизатор командной строки с кучей пространств имен, функций, флагов и вариантов поведения. README описывает общую идею, но не может перечислить все детали: сигнатуры, ошибки, особенности формата, совместимость флагов.

Обычный агент в таких задачах часто цепляется только за примеры из документации и не идет дальше. Он может исследовать `env` и `data`, но почти не трогать другие пространства имен. Или один раз увидеть важную информацию, а потом просто забыть про нее через десятки ходов.

SpecFirst в таком случае сначала собирает карту поведения и фиксирует ее в `SPEC.md`: какие есть функции, как работают флаги, какие сочетания запрещены, какие ошибки и где печатаются. После этого агент для программирования получает уже не расплывчатое описание, а рабочую спецификацию.

В четырех примерах с GPT-5.5 видно, что без отдельной спецификации агент дольше исследует и позже переходит к реализации.

Где остаются проблемы

При всех улучшениях задача все еще далека от решения. Авторы вручную разобрали 50 провалов и увидели несколько типов ошибок.

🟣 Спецификация что-то не нашла вовсе.
🟣 Спецификация описала поведение неверно.
🟣 Спецификация нашла поведение, но описала его слишком расплывчато.
🟣 Реализация не смогла точно выполнить даже корректную спецификацию.
🟣 Часть ошибок связана со средой выполнения, а не с самим агентом.

Самый частый случай — последний шаг все равно ломается на реализации. То есть знать поведение программы недостаточно: нужно еще аккуратно и полно перенести это знание в код.

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

Цена вопроса

За улучшение приходится платить. SpecFirst почти всегда дороже обычного режима, потому что добавляет еще одного агента и еще одну фазу инференса.

В среднем рост стоимости на задачу составил от 48% до 130% в зависимости от модели. Для GPT-5.5-high разница особенно заметна: много денег уходит именно на фазу спецификации.

Но тут важен нюанс. Базовый агент не упирался в лимит ходов. Он почти всегда завершал работу сам раньше времени. Значит, проблема была не в недостатке бюджета как таковом. Просто дать обычному агенту еще больше шагов — не то же самое, что дать ему отдельную фазу понимания задачи.

Почему это важно

В программировании с нуля это почти очевидно: сначала требования, потом код. Для ИИ-агентов мы почему-то долго делали наоборот и надеялись, что модель сама удержит все в голове по ходу длинной сессии.

SpecFirst показывает более общий принцип. Если задача длинная, неоднозначная и требует исследования среды, полезно выносить понимание задачи в отдельный артефакт. Не держать все в контексте, а создавать внешний документ, на который можно опираться дальше.

Это может быть полезно не только для восстановления программ по бинарнику.

🟠 Для работы с API, где документация неполная и многое приходится выяснять экспериментально.
🟠 Для миграции старых систем, когда поведение живет в работающем сервисе, а не в исходниках.
🟠 Для тестирования и интеграции, где нужно сначала понять контракт системы.
🟠 Для сложных мультиагентных конвейеров, где один агент собирает требования, а другой реализует.

Вывод

Если вы хотите, чтобы ИИ-агент писал программу с нуля, мало просто дать ему README и доступ к терминалу. Нужна отдельная фаза, где агент сначала выясняет, что именно должна делать программа, и фиксирует это в явном виде.

SpecFirst показывает, что такая декомпозиция дает стабильный выигрыш: больше покрытие исследования, раньше старт реализации, крупнее и полнее кодовая база, выше доля пройденных тестов. Причем эффект виден на разных моделях и на задачах разной сложности.

В длинных задачах программирования ИИ-агенту нужен не только код, но и память в виде спецификации. Без нее он запутывается в собственных шагах. С ней у него появляется опора, от которой уже можно строить реализацию.

ИИ-обзоры простыми словами

Каждый день читаем свежие статьи об ИИ и пересказываем главное естественным языком — без хайпа и воды. Если хотите понимать, куда движутся ИИ-агенты раньше остальных, — подписывайтесь.

Новые обзоры — каждый день

В Telegram