llmbench.ru

format() без format()

Модели пишут на Python функцию fmt(value, spec), которая для целых и дробных чисел символ в символ повторяет встроенную format(), но без неё самой, без f-строк, % и repr. Задание короткое, а ловушек много: округление по точному двоичному значению, заполнение нулями вместе с разделителями разрядов, флаг z, NaN, бесконечности и разбор строки формата. Ответ сравнивается с настоящим CPython на 502 случаях и двумя замерами скорости.

29 октября 2026. 6 прогонов, 4 модели, ещё 1 исключён из рейтинга.

тест пройденпроваленкод не запустился
1Claude Opus 5.5 (агент, effort max)502из 5022Claude Opus 5.5 (агент)502из 5023DeepSeek Flash (V4.1)478из 5024GPT-6.1 Sol422из 5025Qwen3.8-Max402из 5026Claude Opus 5.5 (effort max)0из 50285 ручных ловушек400 случайных форматов17 форматов с ошибкой
Каждое деление означает один тест. Столбцы общие для всех прогонов и отсортированы так, что слева стоят тесты, которые прошли почти все, а справа те, что не дались никому.

Что выяснили

Без единой ошибки справился только Opus агентом.Оба агентских прогона, с уровнем рассуждения по умолчанию и с effort: max, прошли 502 случая из 502 и оба замера. Ближе всех из моделей через API DeepSeek Flash с 478, у GPT-6.1 Sol 422, у Qwen3.8-Max 402.

Через шлюз Opus думает в разы меньше и нарушил запрет.Opus через API с effort: max рассуждал 9,5 тысячи токенов против 55 и 240 тысяч у агентов на той же модели и отформатировал порядок числа f-строкой, которую задание запрещает. В зачёт идёт ноль, с правкой было бы 447.

Главные ловушки: нули с разделителями, ноль при явном выравнивании и проценты.fmt(1234, '08,') в Python даёт 0,001,234, шире заданной ширины, и это не угадала ни одна модель через API. <05 у всех, кроме агентов, дал пробелы вместо нулей. DeepSeek и GPT умножают на 100 точно, а CPython умножает во float, поэтому 1e308 с % даёт inf%.

Короткое задание различает модели лучше длинного.Спецификация занимает одну страницу, но результаты разошлись от 402 до 502. В прошлых тестах сильные модели почти все проходили 100%, и места решала скорость кода.

Пустая строка входит в любую строку.Qwen проверял тип как typ in "eEfFgG%", а для пустого типа это истинно, и целое без типа уходило в ветку для float. Ровно на это же мы наткнулись в своей реализации для стенда.

Все прогоны

МестоМодельТестыЛовушкиСлучайныеОшибкиСкоростьВремяРассуждениеВсего токеновТокенов/сСтрок кодаС правкой
🥇 1Claude Opus 5.5 (агент, effort max)502 (100.0%)85/85400/40017/172/235 мин 24 с241.3K*244.9K115*456—
🥈 2Claude Opus 5.5 (агент)502 (100.0%)85/85400/40017/172/28 мин 51 с54.8K*58.8K111*489—
🥉 3DeepSeek Flash (V4.1)478 (95.2%)83/85379/40016/170/27 мин 23 с70K74.3K168673—
4GPT-6.1 Sol422 (84.1%)75/85332/40015/170/211 мин 40 сскрыто19.5K28512—
5Qwen3.8-Max402 (80.1%)65/85322/40015/171/240 мин 43 с92.8K96.6K40524416, скорость 1/2
6Claude Opus 5.5 (effort max)0 (0.0%)0/850/4000/170/22 мин 36 с9.5K14.9K96468447, скорость 0/2

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

Время и токены

Время ответа

От отправки задания до последнего символа ответа. Зависит и от загрузки серверов провайдера.

0 мин10 мин20 мин30 мин40 мин50 минClaude Opus 5.5 (агент, effort max)35 мин 24 сClaude Opus 5.5 (агент)8 мин 51 сDeepSeek Flash (V4.1)7 мин 23 сGPT-6.1 Sol11 мин 40 сQwen3.8-Max40 мин 43 сClaude Opus 5.5 (effort max)2 мин 36 с

Сколько модель написала

рассуждениекод и ответпровайдер скрывает разбивку
0K20K40K60K80K100K120K140K160K180K200K220K240K260KClaude Opus 5.5 (агент, effort max)244.9KClaude Opus 5.5 (агент)58.8KDeepSeek Flash (V4.1)74.3KGPT-6.1 Sol19.5K, разбивка скрытаQwen3.8-Max96.6KClaude Opus 5.5 (effort max)14.9K

Разбор по участникам

Claude Opus 5.5 (агент, effort max)Anthropic, claude-opus-5-5
Тоже 502 из 502 и оба замера, 0,05 и 0,01 секунды. С effort: max агент думал вчетверо дольше, 35 минут и около 240 тысяч токенов, и написал код короче, 456 строк, но результат тот же: задача уже решалась полностью и на обычном уровне. Протокол соблюдён.
Claude Opus 5.5 (агент)Anthropic, claude-opus-5-5
502 из 502 и оба замера скорости, 0,06 и 0,01 секунды. Единственный, кто прошёл все ловушки с первого раза: точное округление, нули с разделителями, z, NaN, % во float и разбор строки формата. Работал вслепую 9 минут, около 55 тысяч токенов рассуждения, код 489 строк. Протокол соблюдён: одно чтение задания и одна запись решения.
DeepSeek Flash (V4.1)DeepSeek, deepseek-flash
478 из 502, лучший результат среди моделей через API, но оба замера скорости провалены: замер засчитывается, только если все ответы в нём верны. % умножает число на 100 точно, а не во float, поэтому 1e308 даёт 300 цифр вместо inf%, и крупные числа в процентах расходятся в последних знаках. Не учтён 0 при явном выравнивании (<05 даёт 5 вместо 50000), а при выравнивании = нули не ставятся. Ответ за 7,4 минуты, 70 тысяч токенов рассуждения.
GPT-6.1 SolOpenAI, gpt-6.1-sol
422 из 502, оба замера провалены из-за неверных ответов. Как и DeepSeek, считает % точно, а не во float. Печатает -nan с минусом, теряет % у nan, ставит на один ноль больше при заполнении нулями с разделителями, не группирует _ у шестнадцатеричных и на .0g даёт 2e+02 вместо 1e+02. Первая попытка оборвалась на шлюзе через 298 секунд без ответа, вторая заняла 11,7 минуты, код начался только на 624-й секунде.
Qwen3.8-MaxAlibaba, qwen3.8-max
402 из 502 и один замер из двух. Думал дольше всех, 40 минут и 93 тысячи токенов рассуждения, и попался на ловушку, на которой споткнулись и мы при написании стенда: проверка typ in "eEfFgG%" для пустого типа истинна, поэтому целое без типа уходит в ветку для float и падает. С правкой этой строки было бы 416. Остальные ошибки настоящие: флаг z не работает, у -inf с z получается -0.0, нули с разделителями и заполнение нулями у inf неверны.
Claude Opus 5.5 (effort max)Anthropic, claude-opus-5-5
0 из 502: решение нарушает запрет задания. Порядок числа форматируется f-строкой f"{abs(exp):02d}", то есть встроенным форматированием, ещё две f-строки стоят в текстах ошибок. Если заменить их, было бы 447 из 502: ломаются наименьшее денормализованное число (деление на ноль), флаг z, +nan, нули с разделителями и 0 при явном выравнивании. Через шлюз Opus с effort: max рассуждал всего 9,5 тысячи токенов и ответил за 2,6 минуты, а агентом на той же модели думал 55 и 240 тысяч.

Как устроен тест

Задание

Нужно повторить мини-язык формата Python для int и float: заполнение и выравнивание, знак, флаги z, # и 0, ширину, разделители , и _, точность и типы d, b, o, x, X, e, E, f, F, g, G, %. Где format бросает ValueError, функция тоже должна его бросить. Встроенное форматирование запрещено, разрешены math, fractions, float.as_integer_ratio() и str() от целого.

Напиши на Python 3.12 модуль с функцией

```python
def fmt(value, spec: str) -> str:
    ...
```

которая для чисел повторяет встроенную функцию `format(value, spec)` из CPython 3.12. Результат должен совпадать с `format` символ в символ. Если `format` бросает `ValueError`, функция тоже должна бросить `ValueError` (текст сообщения не важен).

## Что поддерживается

`value` имеет тип `int` или `float` (не `bool`). Строка формата устроена так:

```
[[fill]align][sign]["z"]["#"]["0"][width][grouping]["." precision][type]
```

- `fill`: любой символ; `align`: `<`, `>`, `^` или `=`.
- `sign`: `+`, `-` или пробел.
- `z`, `#`, `0`: флаги, как в Python.
- `width` и `precision`: десятичные числа, `width` не больше 200, `precision` не больше 1100.
- `grouping`: `,` или `_`.
- `type` для `int`: пустой, `d`, `b`, `o`, `x`, `X` или любой из типов для `float` ниже.
- `type` для `float`: `e`, `E`, `f`, `F`, `g`, `G`, `%`.

Значения `float` бывают любыми, в том числе `-0.0`, бесконечности, NaN и денормализованные числа. Целые бывают до 10^40 по модулю. Типы `c` и `n`, а также `float` с пустым типом в проверке не встречаются.

## Ограничения

Встроенным форматированием пользоваться нельзя: функцией `format`, методами `str.format` и `__format__`, f-строками, оператором `%` для строк, функцией `repr`, а также `str()` от `float`. Нельзя импортировать `decimal`, `locale`, `string` и сторонние пакеты. `str()` от целого числа можно, `math`, `fractions` и `float.as_integer_ratio()` тоже. Решение, которое нарушает ограничение, получает ноль.

Скорость важна: 20 000 вызовов со случайными форматами должны укладываться в 1 секунду, и 600 чисел с точностью около 1000 знаков тоже в 1 секунду.

## Формат ответа

Сначала продумай решение, затем ответь модулем в одном блоке ```python.
Как проверяли
  • 85 ручных ловушек. Среди них округление половины к чётному по точному значению (2.675 с .2f даёт 2.67), перенос порядка при округлении, денормализованные числа с точностью до 1100 знаков, граница записи у g, заполнение нулями с разделителями шире заданной ширины (fmt(1234, '08,') даёт 0,001,234), # как символ заполнения, флаг z у нуля, но не у -inf, NaN без знака, %, который умножает во float и поэтому превращает 1e308 в inf%, и целые, которые для дробных типов сначала переводятся во float.
  • 400 случайных форматов из генератора с фиксированным seed: случайные заполнение, выравнивание, знак, флаги, ширина, разделитель, точность и тип на целых до 10^40 и на дробных, включая числа рядом с половинами при округлении и точные двоичные дроби.
  • 17 строк формата, которые обязаны закончиться ValueError: точность у целого, запятая с x и b, оба разделителя, z у целого типа, флаги не по порядку, неизвестный тип, точка без точности, разделитель после точности и лишние символы.
  • 2 замера скорости, на каждый 1 секунда: 20 000 вызовов со случайными форматами и 600 чисел с точностью около 1000 знаков. Своя реализация стенда без format() укладывается в 0,06 и 0,01 секунды.
  • Ограничения проверяются по коду решения (f-строки, вызовы format и repr, % для строк, запрещённые модули), а builtins.format на время прогона подменяется заглушкой. Нарушение даёт ноль.
  • Сам стенд проверен дважды: обёрткой над настоящей format() и своей реализацией без неё, обе дают 502 из 502 и проходят замеры.
Условия
  • Участвуют те же модели, что в прошлых тестах. Каждая получила задание слово в слово, одним сообщением, без системного промпта и без инструментов, и не могла запустить свой код.
  • Параметры рассуждения такие же, как раньше: у Qwen включён enable_thinking, у GPT reasoning_effort: high, Opus через API получал thinking: adaptive и effort: max через нативный /messages партнёрского шлюза, Kimi и DeepSeek работали в режиме по умолчанию.
  • Opus 5.5 дополнительно решал задачу агентом Claude Code с чистым контекстом, дважды: с уровнем рассуждения по умолчанию и с effort: max. Протокол один: одно чтение задания и одна запись решения, без запуска кода.
  • Задание заканчивается фразой «Сначала продумай решение, затем ответь модулем», которая не отключает размышление у адаптивных моделей.
  • В зачёт идёт код как есть. Вариант с правкой считается отдельно, только для понимания.
Нюансы
  • Стенд проверен двумя способами: обёрткой над настоящей format() и своей реализацией без неё. Обе дают 502 из 502, своя укладывается в замеры за 0,06 и 0,01 секунды. При её написании мы сами попались на две ловушки, "" in "boxX" и z у -inf, обе вошли в ручные тесты.
  • Замер скорости засчитывается, только если все ответы в нём верны. Медленных решений не было: все правильные укладываются в сотые доли секунды, а замеры проваливаются из-за неверных ответов.
  • Запрет на встроенное форматирование проверяется по коду и подменой builtins.format, а str() от float проверен отдельно подменой str на 3000 случаях: так не делает ни одно решение.
  • Первая попытка GPT-6.1 Sol оборвалась на шлюзе через 298 секунд без ответа, засчитана вторая.
  • Время и токены Opus-агентов оценочные: время по журналу агента, выходные токены по счётчикам API, рассуждение как выходные токены за вычетом кода.
  • Kimi K3.1 Pro исключён: Moonshot был перегружен с 10:05 до последней проверки в 12:21.
Исключены из рейтинга

Эти прогоны не попали в рейтинг: результат определила не модель, а условия запуска. Ответы и код сохранены в папке.

  • Kimi K3.1 Pro (0 из 502): Провайдер перегружен: с 10:05 до 12:21 Moonshot отвечал ошибкой 429 engine_overloaded на все 10 попыток отправить задание и на все пробные запросы из одного слова. Это сбой доступа, а не модели. Попытки сохранены в answers/kimi-busy*.json.
Участники и доступ
МодельРазработчикIDДоступЛимит ответа
Claude Opus 5.5 (агент)Anthropicclaude-opus-5-5субагент Claude Code, чистый контекст, без запуска кода—
Claude Opus 5.5 (агент, effort max)Anthropicclaude-opus-5-5субагент Claude Code, effort: max, чистый контекст, без запуска кода—
Kimi K3.1 ProMoonshot AIkimi-k3.1-proAPI api.moonshot.ai (через VPN роутера)128K
Qwen3.8-MaxAlibabaqwen3.8-maxAPI token-plan.maas.qwencloudapi.com131.1K
GPT-6.1 SolOpenAIgpt-6.1-solпартнёрский шлюз, reasoning_effort: high128K
DeepSeek Flash (V4.1)DeepSeekdeepseek-flashAPI api.deepseek.com384K
Claude Opus 5.5 (effort max)Anthropicclaude-opus-5-5партнёрский шлюз, нативный /v1/messages, thinking: adaptive, effort: max128K