Нужна ли умная модель для рутины? Разбор пяти задач на четырёх моделях
Автор прочитал сотни комментариев под спором о том, нужны ли программисту самые умные ИИ-модели, и не нашёл ни одного замера на одинаковых задачах. Он взял четыре модели из одного семейства и прогнал пять типовых задач по два раза каждую. Результат показал, что разница в цене почти не влияет на качество рутины, но критична для задач с неочевидными требованиями.
На этой неделе в сообществе разработчиков разгорелась дискуссия о том, оправдано ли использование самых дорогих и умных ИИ-моделей для повседневных задач. Один из авторов Хабра опубликовал пост под названием «Я перестал пользоваться самыми умными ИИ-моделями», где утверждал, что для рутинных операций достаточно дешёвых вариантов, а главным узким местом становится скорость. Под статьёй собралось почти триста комментариев, но, как заметил другой разработчик, ни в одном из них не было реальных замеров на одинаковых задачах. Тогда он решил провести собственный эксперимент, чтобы проверить, действительно ли старшие модели дают преимущество там, где всё кажется простым.
Для теста были отобраны пять типовых задач на Python, которые обычно делегируются агенту: исправление ошибки пагинации (off-by-one), переименование функции во всём проекте с подвохом в виде строкового вызова через getattr, нормализация российского номера телефона по словесному описанию, рефакторинг функции с тройным копипастом для соответствия лимиту в двадцать строк без изменения вывода и делёж счёта на n человек с корректной обработкой отрицательных сумм. В эксперименте участвовали четыре модели одного семейства: Haiku 4.5, Sonnet 5, Opus 5 и Fable 5.1. Все прогоны выполнялись в одинаковых условиях: агент Claude Code в режиме -p, отключённый MCP, единый промпт и чистая папка для каждого запуска. Каждая задача прогонялась дважды на каждой модели, итого сорок запусков, а проверка осуществлялась скрытым скриптом, который модели не видели.
Автор сразу оговаривает ограничения: задачи мелкие, по два прогона на клетку — статистически незначимо, семейство одно, поэтому это скорее замер на коленке, чем полноценный бенчмарк. Тем не менее результаты оказались показательными. Самая дорогая модель продемонстрировала наименьшее время выполнения — 341 секунда против 395 у самой дешёвой. При этом младшая модель потратила 18 754 токена на размышления за десять прогонов, тогда как старшая — всего 2 674. Несмотря на более высокую скорость генерации токенов у дешёвой модели, их общее количество оказалось настолько велико, что в сумме она работала дольше. Интересно, что вторая по стоимости модель Opus 5 оказалась самой медленной из четырёх, что опровергает прямую зависимость «дороже — значит быстрее».
Четыре из пяти задач были успешно решены всеми моделями в обоих прогонах. Пагинация, переименование с подвохом, нормализация телефона и рефакторинг дали 32 успешных результата из 32 возможных. Это означает, что для подобной рутины девятикратная разница в цене не даёт никаких преимуществ. Вся разница проявилась только на пятой задаче, связанной с дележом счёта и обработкой отрицательных сумм. Здесь модели споткнулись не на коде, а на чтении требований. Первое, что приходит в голову при решении такой задачи — использовать divmod и распределить остаток по первым элементам списка. Для положительной суммы это работает идеально: 1000 на троих даёт [334, 333, 333]. Однако при возврате -1000 деление в Python округляет вниз, и получается [-333, -333, -334], то есть лишняя копейка уезжает в конец списка, что противоречит требованию «лишние копейки достаются первым».
Младшая модель Haiku написала именно такой код оба раза, Sonnet ошиблась один раз из двух, а Opus и Fable все четыре раза делили модуль суммы, а знак возвращали потом, явно объясняя в отчёте, что при делении отрицательного числа лишняя копейка падает в конец, а требования говорят об обратном. Fable в одном из прогонов даже написала скрипт, перебравший все суммы от -300 до 299 при n от 1 до 11, хотя её об этом не просили. Особенно показательным оказался отчёт младшей модели, где она поставила две галочки: «Остаток достаётся первым в списке» и «Работает для возвратов: split_bill(-100, 3) = [-33, -33, -34]». Вторая строка опровергает первую, но видимый тест зелёный, отчёт бодрый, а баг вылезет на первом же возврате. Справедливости ради, требование про возвраты можно трактовать по-разному, и некоторые разработчики могут счесть такое поведение допустимым. Однако старшие модели увидели эту развилку и объяснили свой выбор, тогда как младшая просто поставила галочку.
На основе эксперимента автор сформулировал практические рекомендации. Задачи, где всё чётко расписано и есть тесты, он теперь отдаёт младшей модели: 32 из 32 успешных прогонов при почти десятикратной экономии. Если же в требованиях появляются слова «и для отрицательных», «и для пустого», «как было раньше», он берёт старшую модель. Код дешёвая модель пишет нормально, но она пропускает сам вопрос, требующий анализа неочевидных условий. Кроме того, автор советует не доверять отчёту «всё работает» без собственной проверки: один скрытый тест на граничный случай дешевле любой модели. Этот вывод перекликается с общим трендом на рынке ИИ-инструментов, где разработчики всё чаще ищут баланс между стоимостью, скоростью и качеством, а не гонятся за максимальной мощностью. Для российских команд, использующих зарубежные API, такая экономия может быть особенно актуальна из-за сложностей с оплатой и ограничений доступа. В перспективе, вероятно, появятся более специализированные модели, заточенные под конкретные типы рутинных задач, что позволит ещё точнее настраивать пайплайны. Открытым остаётся вопрос, насколько результаты масштабируются на другие языки и более сложные проекты, но сам подход — измерять, а не верить — заслуживает внимания.