Когда изображение создаётся с помощью ИИ-модели, единственный способ на него повлиять — промпт. Напрямую редактировать картинку нельзя: любое изменение требует возврата к модели и нового запроса. Именно это ограничение стало отправной точкой проекта. Разработчик вместе с другом Кэмероном обучили языковую модель создавать изображения путём написания кода — с помощью reinforcement learning. В этом случае артефактом становится сам код, а код можно редактировать: результат работы модели поддаётся более тонкой правке, чем повторный промпт.
Более глубокий вопрос, который поднимает проект, — как применять reinforcement learning к творческим и дизайнерским задачам. RL работает, когда награду можно проверить: математическая задача решена верно или нет, игра выиграна или проиграна. Эстетическое качество не подпадает ни под одну из этих категорий. Дизайнерская задача превращается в задачу построения функции награды и критериев, которые должен применять судья. Слишком жёсткие критерии — и модель сходится к однообразному результату. Слишком мягкие — и модель дрейфует в произвольную сторону.
[Видео презентации дипломной работы с контекстом проекта]
Вклад автора
Дизайн, разработка, исследования в области RL.
Команда
Сурья, Кэмерон Франц, Алекс Ванг.

Акварельная картина гибискуса, созданная кодом.
Как это работает
Система представляет собой цикл из четырёх шагов, повторяемый тысячи раз во время обучения.
Модель получает промпт вроде «нарисуй персиковый гибискус акварелью» и пишет полный скетч на JavaScript с использованием библиотеки p5.brush. Скетч рендерится в изолированном окружении Puppeteer, на выходе получается PNG. Изображение сравнивается с двумя случайными эталонными картинами из вручную размеченного пула, а отдельная модель-судья выбирает более удачную акварель. Решение судьи превращается в сигнал награды, GRPO обновляет модель, и цикл повторяется.
Неочевидные решения касаются того, что именно оценивается, как выносится суждение, что входит в пул эталонов и как написан системный промпт. Каждому из этих вопросов посвящён отдельный раздел ниже.
Функции награды
Первая версия критериев оценки включала девять отдельных сигналов: гейт компиляции, проверку, что код действительно использует p5.brush, а не нативный p5, ограничение по длине кода на уровне около 3000 токенов, HPSv3 (модель человеческих предпочтений), соответствие промпту, которое оценивал совет из GPT-5.4 и Gemini, и ещё четыре судьи качества: узнаваемость, эстетику, технику, глубину.
Модель вышла на плато около 0,65 награды и застряла там. Каждый прогон выглядел одинаково: плоский клипартный цветок с пятью округлыми лепестками. Награда продолжала расти, но способности модели, судя по всему, не улучшались.
Диагноз поставили, изучив отдельные компоненты награды. Четыре судьи качества плюс соответствие промпту коррелировали друг с другом на уровне 0,85–0,95 — они измеряли одно и то же пять раз подряд. Длина кода, дающая примерно треть общей награды, насытилась к тридцатому шагу и дальше не давала градиента. HPSv3 — единственный сигнал с реальной дисперсией — имел вес всего 0,10. Составленная система критериев раз за разом сообщала модели одно и то же.
Исправление состояло из двух частей.
Замена абсолютной оценки на попарное сравнение. Изначальная система просила судью оценивать каждый прогон по шкале от нуля до десяти. Оценки сжимались около нуля. Попарное сравнение задаёт другой вопрос: судье показывают результат прогона, два эталона из пула и один промпт — «какая из этих акварелей лучше передаёт гибискус?» Наградой становится доля выигранных сравнений. Динамический диапазон расширяется: модель-судья справляется с относительным вопросом надёжнее, чем с абстрактной шкалой.
Построение пула эталонов из вручную размеченных примеров. 1664 изображения оценивались по одному на категории «нравится», «нормально» и «нет». 117 примеров категории «нравится» стали основой пула для сравнения. С этого момента каждый прогон оценивался относительно того, что было заранее признано хорошим. Следующим шагом — до которого дело не дошло — стало бы обучение небольшой модели награды непосредственно на оценках (полноценный RLHF), чтобы применять понятие «хорошо» без необходимости каждый раз сравнивать с пулом.
Новая система критериев свелась к четырём компонентам: бинарный гейт «компилируется и использует brush» (0,05), бинарная проверка длины (0,05), HPSv3 (0,30) и попарное сравнение с пулом эталонов (0,60). При той же базовой модели и тех же обучающих данных следующий запуск достиг прежнего плато втрое быстрее, продолжил расти и дальше, а код сжался с 13 500 токенов до менее чем 2000. Модель научилась тому, что выигрышные композиции не требуют многословного кода.

Срез пула эталонов, сгруппированный по цвету.
Пул эталонов
Пул содержит 581 эталонную картину: все они — результат ручной разметки из 1664 сгенерированных изображений, из которых 117 попали в категорию «нравится», 266 — в «нормально», а 198 — дополнения из отдельного прогона генерации, использованные для расширения набора сравнения в цветовых диапазонах, где размеченных вручную примеров было мало.
Каждое изображение в пуле — вывод модели: набрать достаточно примеров, созданных людьми, не удалось, поскольку используемая библиотека — нишевый инструмент для художников. Генерация проходила через два пайплайна. Первый — AutoResearch, где Opus 4.6, GPT-5.4 и Gemini 3.1 Pro итеративно работали относительно эталонных фотографий под наблюдением VLM-судьи, дающего оценки и обратную связь. Второй — более крупный пакетный прогон на Gemini 3.1 Pro. Оба пайплайна использовали системный промпт, который сам был выведен методом GEPA — о нём речь пойдёт дальше.
Эволюция системного промпта
Системный промпт тоже потребовал доработки. Ранние версии включали 400-строчный справочник по API p5.brush. Модель выдавала уверенный, аккуратно отформатированный код, который использовал несуществующие функции API.
Исправление сделали с помощью GEPA — библиотеки оптимизации промптов, которая эволюционирует промпт относительно функции оценки. Провели 200 итераций против судьи с 7 примерами, откалиброванного под нужный вкус. Оптимизация сошлась к промпту со строгим списком из восьми разрешённых методов кисти, без документации по API и без примеров. Первый случай, когда три из трёх генераций дали узнаваемые формы гибискуса, произошёл именно на версии, написанной после полного отказа от 400-строчного справочника.
Выводы оказались общими: подробная справочная документация в системном промпте заставляет модели галлюцинировать API, а короткий, чётко очерченный список разрешённого ограничивает вывод лучше, чем исходная спецификация.

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

Несколько любимых результатов.
Заключение
Reinforcement learning требует проверяемой награды. Математическая задача решена верно или нет, игра выиграна или проиграна. Эстетическое предпочтение не подходит ни под одну из этих категорий. Чтобы применить RL к субъективной работе, награду приходится составлять вручную и проектировать достаточно аккуратно, чтобы она обобщалась. Слишком узкая — и модель научится лишь копировать оценённые примеры. Слишком широкая — и не научится ничему конкретному. RL для творческих задач — это, по сути, задача проектирования структуры, позволяющей вкусу обобщаться до предпочтений пользователей.
Я не считаю, что это лучший способ создавать изображения — он, по сути, гораздо медленнее. Но когда проект только начинался, меня раздражало, что единственный способ участвовать в создании изображения с помощью ИИ — это промпт. Проект позволил распределить внимание и усилия между промптом, моделью и самим артефактом.
Работа продолжается: планируется ещё один финальный обучающий прогон, направленный на исправление обнаруженных проблем. Полный технический отчёт выйдет в июне 2026 года.

Что возможно в рамках этого медиума.