# Растеризатор 2D-сцены Модели пишут на чистом Python растеризатор: он превращает описание сцены из прямоугольников, кругов, эллипсов, многоугольников и линий в пиксели. В сцене есть прозрачность, градиенты и аффинные преобразования. Картинку каждой модели сравнивают попиксельно с эталоном на 202 сценах и проверяют двумя замерами скорости. 29 октября 2026. Интерактивная версия: [report.html](report.html), все бенчмарки: [../index.html](../index.html) ## Полоса тестов ![Полоса тестов](charts/strip.svg) Каждая строка показывает один прогон модели, а каждое деление в ней означает один тест. Тёмное деление значит, что тест пройден, красное значит провал, серое значит, что код не запустился. Столбцы общие для всех прогонов и отсортированы от лёгких тестов к трудным. ## Как модели нарисовали контрольную сцену Это одна и та же сцена 320×200, увеличенная вдвое: закат с градиентом, полупрозрачные горы, звёзды с правилами заливки `nonzero` и `evenodd`, повёрнутый прямоугольник, скошенный круг и линии. Переключатель «Отличия от эталона» подсвечивает красным пиксели, которые не совпали с эталоном. **Эталон** ![Эталон](gallery/reference.png) **Claude Opus 5.5 (агент)**, совпало 100.0% пикселей ![Claude Opus 5.5 (агент)](gallery/opusagent.png) **Claude Opus 5.5 (агент, effort max)**, совпало 100.0% пикселей ![Claude Opus 5.5 (агент, effort max)](gallery/opusagentmax.png) **Qwen3.8-Max**, совпало 100.0% пикселей ![Qwen3.8-Max](gallery/qwen.png) **Kimi K3.1 Pro**, совпало 100.0% пикселей ![Kimi K3.1 Pro](gallery/kimi.png) **DeepSeek Flash (V4.1)**, совпало 100.0% пикселей ![DeepSeek Flash (V4.1)](gallery/dsflash.png) **GPT-6.1 Sol**, совпало 100.0% пикселей ![GPT-6.1 Sol](gallery/gpt.png) **Claude Opus 5.5 (effort max)**, совпало 100.0% пикселей ![Claude Opus 5.5 (effort max)](gallery/opusmax.png) ## Что выяснили **Правильно нарисовали все.** Все шесть моделей, которые сдали код, прошли 202 сцены из 202 и нарисовали контрольную сцену пиксель в пиксель с эталоном. Задача проще первой, и её ловушки (полуоткрытые границы, правила заливки, короткие записи цвета, округление на половине) никого не поймали. **Различает их скорость кода.** Opus-агент рисует 400 фигур за 0,10 секунды, Qwen за 0,14, Kimi за 0,20, DeepSeek Flash за 0,27, GPT за 0,28. Эталон делает это за 0,45, так что пять моделей из шести написали код быстрее нашего. Opus через API не отсекал фигуры по рамке и не уложился в лимит. **Быстрый код не значит быстрый ответ.** Qwen написал второй по скорости растеризатор, но думал над ним 27,5 минуты. DeepSeek Flash ответил за 2 минуты 20 секунд, и его код всего вдвое медленнее. **Глубина размышления снова решила спор двух Opus.** Агентом Opus думал около 10 минут и написал самый быстрый код. Через API с адаптивным мышлением он ответил за 34 секунды почти без рассуждения: код правильный, но медленный. **Шлюз мешает длинным ответам.** Партнёрский шлюз дважды оборвал поток посреди рассуждения: один раз у GPT, несколько раз у Grok. У прямых API провайдеров таких обрывов не было. ## Все прогоны | Место | Модель | Тесты | Ловушки | Случайные | Ошибки | Скорость | Время | Рассуждение | Всего токенов | Токенов/с | Строк кода | С правкой | |---|---|---|---|---|---|---|---|---|---|---|---|---| | 🥇 1 | Claude Opus 5.5 (агент) | 202 (100.0%) | 46/46 | 150/150 | 6/6 | 2/2 | 10 мин 29 с | 72K* | 82K | 130* | 777 | — | | 🥈 2 | Claude Opus 5.5 (агент, effort max) | 202 (100.0%) | 46/46 | 150/150 | 6/6 | 2/2 | 53 мин 16 с | 350K* | 355.6K | 111* | 602 | — | | 🥉 3 | Qwen3.8-Max | 202 (100.0%) | 46/46 | 150/150 | 6/6 | 2/2 | 27 мин 25 с | 55.9K | 66.5K | 40 | 1229 | — | | 4 | Kimi K3.1 Pro | 202 (100.0%) | 46/46 | 150/150 | 6/6 | 2/2 | 11 мин 42 с | 18K | 21.2K | 30 | 403 | — | | 5 | DeepSeek Flash (V4.1) | 202 (100.0%) | 46/46 | 150/150 | 6/6 | 2/2 | 2 мин 20 с | 23.3K | 26.5K | 190 | 426 | — | | 6 | GPT-6.1 Sol | 202 (100.0%) | 46/46 | 150/150 | 6/6 | 2/2 | 4 мин 28 с | скрыто | 11.6K | 43 | 348 | — | | 7 | Claude Opus 5.5 (effort max) | 202 (100.0%) | 46/46 | 150/150 | 6/6 | 1/2 | 34 с | 0 | 3.8K | 111 | 287 | — | В колонке «С правкой» указан результат того же кода после исправления одной-двух строк. В рейтинг он не входит. «Токенов/с» показывает, как быстро модель пишет: все токены ответа, включая рассуждение, делённые на полное время ответа. ## Время ответа ![Время ответа](charts/time.svg) ## Сколько модель написала ![Токены](charts/tokens.svg) Синим показано рассуждение, бирюзовым код и ответ. Серый цвет значит, что провайдер не показывает, сколько ушло на рассуждение. ## Разбор по участникам ### Claude Opus 5.5 (агент) 202 сцены из 202 и оба замера скорости, причём быстрее всех: 400 фигур на холсте 800×600 он рисует за 0,10 секунды, а крупные полупрозрачные фигуры с градиентом за 0,13. Это в 4–6 раз быстрее эталона. Агент работал вслепую: одно чтение задания, одна запись решения, код ни разу не запускался (протокол проверен). Прогон занял 10,5 минуты, код самый длинный, 777 строк: модель потратила их на быстрые пути для каждого типа фигуры. ### Claude Opus 5.5 (агент, effort max) 202 сцены из 202 и оба замера скорости, 0,08 и 0,22 секунды. Результат тот же, что у агента с уровнем по умолчанию, но думал он в пять раз дольше: 53 минуты и около 350 тысяч токенов рассуждения против 10 минут и 72 тысяч. Opus через API на том же `effort: max` за 34 секунды написал код, который не уложился во второй замер. Протокол соблюдён: одно чтение задания и одна запись решения. ### Qwen3.8-Max 202 сцены из 202 и оба замера скорости, 0,14 и 0,17 секунды: это второй по скорости код после Opus-агента. Зато ответ занял больше всех, 27,5 минуты, из них около 56 тысяч токенов ушло на рассуждение, а код вышел самым длинным среди API-моделей, 1229 строк. В первом тесте Qwen подвела одна опечатка, здесь ошибок нет. ### Kimi K3.1 Pro 202 сцены из 202 и оба замера скорости, 0,20 и 0,30 секунды, второе место по скорости кода. Ответ занял 11,7 минуты, из них около 18 тысяч токенов ушло на рассуждение. Код компактный, 402 строки. ### DeepSeek Flash (V4.1) 202 сцены из 202 и оба замера скорости, 0,27 и 0,41 секунды, это тоже быстрее эталона. После провала в первом тесте из-за опечатки здесь всё чисто. Ответ пришёл за 2 минуты 20 секунд, это самый быстрый из безошибочных прогонов, на рассуждение ушло 23 тысячи токенов. ### GPT-6.1 Sol 202 сцены из 202 и оба замера скорости, 0,28 и 0,60 секунды. Первая попытка оборвалась на стороне шлюза на 115-й секунде без ответа, вторая прошла за 4,5 минуты. Код 347 строк. ### Claude Opus 5.5 (effort max) 202 сцены из 202, но только один замер скорости из двух. Растеризатор правильный, однако каждая фигура проверяется по всему холсту без отсечения по её рамке, поэтому 400 фигур на 800×600 не уложились даже в 60 секунд. Ответ пришёл за 34 секунды, это самый короткий код (286 строк), и адаптивное мышление снова почти не включалось. ## Задача Нужно написать функцию `render(scene)`, которая возвращает картинку как список строк пикселей `(r, g, b)`. Пиксель закрашивается, если его центр лежит внутри фигуры. Фигуры бывают пяти видов: прямоугольник с полуоткрытыми границами, круг, эллипс, многоугольник с правилами заливки `nonzero` и `evenodd` и толстая линия. Цвет задаётся в форматах `#rgb`, `#rgba`, `#rrggbb` и `#rrggbbaa`, у фигуры может быть `opacity`, линейный градиент и аффинное преобразование. Цвета смешиваются по формуле `floor(src*α + dst*(1-α) + 0.5)`. Полный текст: [task/task.md](task/task.md) ## Как проверяли - 46 ручных сцен с ловушками. Среди них полуоткрытые границы прямоугольника и включительная граница круга, короткие записи цвета `#abc` и `#f808`, самопересекающаяся звезда с разными правилами заливки, вершины ровно на центрах пикселей, вырожденное преобразование, круг под масштабом, который становится эллипсом, толщина линии под масштабом, градиенты с обрезкой, со ступенькой и с совпадающими точками, а также смешивание цветов ровно на половине, где `round()` в Python даёт другой ответ. - 150 случайных сцен из генератора с фиксированным seed, в каждой от 2 до 9 фигур с прозрачностью, градиентами и преобразованиями. - 6 сцен, которые обязаны закончиться ошибкой `ValueError`: неверные цвета, неизвестный тип фигуры, многоугольник из двух точек, градиент без остановок. - 2 замера скорости: 400 небольших фигур на холсте 800×600 и несколько крупных полупрозрачных фигур с градиентом на холсте 640×480. На каждый даётся 4 секунды, эталон укладывается в 0,5 и 0,8 секунды. - Картинка сравнивается с эталоном попиксельно. Разница в 1 единицу по каналу допускается, потому что формулы можно записать по-разному. Сцена засчитывается, если не совпало не больше 0,1% пикселей, но не меньше трёх, это запас на центры пикселей ровно на границе фигуры. - Сам стенд проверен эталоном: он проходит 202 сцены из 202 и оба замера скорости. ## Условия - Участвуют модели, которые дали рабочий код в первом тесте, плюс Grok 4.7. Каждая получила задание слово в слово, одним сообщением, без системного промпта и без инструментов, и не могла запустить свой код. - Параметры рассуждения такие же, как в первом тесте: у Qwen включён `enable_thinking`, у GPT и Grok `reasoning_effort: high`, Opus через API получал `thinking: adaptive` и `effort: max` через нативный `/v1/messages`, Kimi и DeepSeek работали в режиме по умолчанию. - Opus 5.5 дополнительно решал задачу агентом Claude Code с чистым контекстом. Ему разрешено одно чтение файла задания и одна запись решения, запускать код нельзя. - В зачёт идёт код как есть. Вариант с правкой одной строки считается отдельно, только для понимания. - Время считается от отправки запроса до последнего токена и зависит от загрузки серверов провайдера. ## Нюансы - Эталонный растеризатор написан по тексту задания, и стенд проверен им самим: 202 сцены из 202 и оба замера скорости за 0,45 и 0,83 секунды. - При одинаковом числе сцен и замеров место определяет суммарное время двух замеров скорости. - Первая попытка GPT-6.1 Sol оборвалась на шлюзе на 115-й секунде без ответа, засчитана вторая. - Grok 4.7 через партнёрский шлюз не смог закончить ни одну задачу: его потоки обрывались посреди рассуждения, поэтому он в разделе исключённых. - Время и токены Opus-агента оценочные, по объёму кэша контекста. Протокол агента проверен: одно чтение задания и одна запись решения. - Opus-агент с `effort: max` добавлен 29.10.2026, после основного прогона, по тому же протоколу: одно чтение задания и одна запись решения, без запуска кода. Его запустили, чтобы сравнить с Opus через API на том же `effort: max`: через партнёрский шлюз модель рассуждает заметно меньше. ## Исключены из рейтинга - **Grok 4.7** (0 из 202): Партнёрский шлюз каждый раз обрывал поток посреди рассуждения, и модель не успевала выдать ни строки кода. Это проблема доступа, а не модели. Grok стоит проверить через прямой API xAI. Две попытки оборвались на 652-й и 840-й секунде. ## Участники | Модель | Разработчик | ID | Доступ | Лимит ответа | |---|---|---|---|---| | Claude Opus 5.5 (агент) | Anthropic | `claude-opus-5-5` | субагент Claude Code, чистый контекст, без запуска кода | — | | Claude Opus 5.5 (агент, effort max) | Anthropic | `claude-opus-5-5` | субагент Claude Code, `effort: max`, чистый контекст, без запуска кода | — | | Kimi K3.1 Pro | Moonshot AI | `kimi-k3.1-pro` | API api.moonshot.ai (через VPN роутера) | 128K | | GPT-6.1 Sol | OpenAI | `gpt-6.1-sol` | партнёрский шлюз, `reasoning_effort: high` | 128K | | Qwen3.8-Max | Alibaba | `qwen3.8-max` | API token-plan.maas.qwencloudapi.com | 131.1K | | Claude Opus 5.5 (effort max) | Anthropic | `claude-opus-5-5` | партнёрский шлюз, нативный `/v1/messages`, `thinking: adaptive`, `effort: max` | 128K | | DeepSeek Flash (V4.1) | DeepSeek | `deepseek-flash` | API api.deepseek.com | 384K | | Grok 4.7 | xAI | `grok-4.7` | партнёрский шлюз, `reasoning_effort: high` | 128K | ## Файлы | Путь | Что это | |---|---| | `README.md` | отчёт в формате Markdown | | `report.html` | страница отчёта с графиками и галереей | | `bench.json` | метаданные: участники, условия, нюансы и выводы, из них собирается отчёт | | `task/task.md` | задание, которое получили модели | | `harness/test_raster.py` | скрытые тесты и эталонный растеризатор | | `gallery/` | контрольная сцена в исполнении каждой модели и карты отличий | | `answers/.json` | ответ модели целиком: код, рассуждение, токены и время | | `solutions//solution.py` | код, который написала модель | | `grades/.txt` | результаты тестов и список падений |