ESPNIs Seahawks offensive coordinator Brian Fleury a 'home run' hire? How the rookie playcaller is faringBollywood HungamaRajpal Yadav deposits Rs 2 crores in cheque bounce case; Supreme Court refers dispute to mediationPunchNBA probes mismanagement claims of ₦100m Imo govt gift to Owerri branchRTP DesportoPalmeiras a um passo de mais uma final da LibertadoresThe Jerusalem PostBasij female unit commander assassinated in latest attack targeting Iranian armed forcesDaily MaverickIndustry Influence: Experts call for ‘big food’ ban at future SA Nutrition CongressesInquirerDTI: Prices of water, basic goods stable amid looming ‘Super El Niño’ZDF heuteEntdecken Sie das ZDF-NachrichtenstudioObservador DesportoAs notícias das 19hThe South African’13th cheque please’: SASSA grant recipients share their Christmas wish listGlobo EsporteCom Falcão, Brasil e Polônia se enfrentam pelo Legends Game Brasil em SC20 MinutenTödlicher Achterbahn-Unfall – sparte Six Flags bei Wartung?
The Daily Newsstand · Free, Always
Thursday, October 15, 2026

Все 179 ответов были SURE. Четыре из них не прошли тесты

Translate

Идея была простая, почти наивная: если попросить модель в конце ответа честно написать, уверена она в своём коде или нет, можно ли по этой метке заранее отлавливать плохие решения? Не гонять тесты, не читать код глазами, а просто смотреть на последнюю строку.

Я прогнал 20 небольших задач на Python через три модели, по три повтора на задачу, и собрал 179 ответов. Все 179 закончились строкой CONFIDENCE: SURE. Вариант UNSURE в промпте был, им не воспользовался никто. При этом четыре решения завалили скрытые тесты. Одно превращало 1024 байта в 1.0 MiB, другое падало на разнице между двумя самыми обычными датами. Под обоими стояло SURE.

Дальше расскажу, как это было устроено, покажу все четыре ошибки и честно перечислю, чего из этого эксперимента вытащить нельзя (а нельзя многое).

Что я спрашивал

20 задач, в каждой нужно написать одну функцию на Python 3.9, только стандартная библиотека. Условия я специально сделал с подвохами, которые легко прочитать и не заметить: соседние, но не пересекающиеся интервалы объединять нельзя; в IPv4 допустимы только ASCII-цифры; если при округлении размера файла получается 1024, надо переходить к следующей единице, а не оставлять 1024.0 KiB.

На эти 20 задач у меня 247 тестовых случаев. В промпт они, разумеется, не попадали. Скрипт вытаскивал код из ответа, запускал тесты нужной задачи, и зачёт ставился только за все пройденные.

Модель код запускать не могла: ей давали задачу и просили в том же ответе, после блока с кодом, написать одну из двух строк:

CONFIDENCE: SURE
CONFIDENCE: UNSURE

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

Write SURE only if you are certain the function meets every requirement above and would pass strict hidden tests that cover all of them.

То есть планка для SURE задана высоко: «только если уверен, что выполнены все требования и код пройдёт строгие скрытые тесты». Никакого отдельного «ты точно уверен?» вторым сообщением я не задавал, оценка шла сразу в том же ответе.

Запросы ходили через сторонний API-агрегатор, не через официальные API разработчиков. Названия моделей ниже — это ровно то, что я писал в поле model. Какой бэкенд на самом деле отвечал под каждым именем, я не проверял и проверить не могу.

Цифры

Идентификатор в API

Ответов

Прошли тесты

SURE

UNSURE

SURE с ошибками

gpt-6.1-sol

60

60

60

0

0

claude-haiku-5-5

60

59

60

0

1

glm-5.3-flash

59

56

59

0

3

Всего

179

175

179

0

4

Четыре ошибки на 179 ответов, примерно 2,2%. Немного. Но если бы я действовал по исходной идее и отправлял на дополнительную проверку только код с меткой UNSURE, то очередь на проверку была бы пустой, а все четыре бага уехали бы дальше.

Теперь про то, почему 179, а не 180. План был ровный: 3 модели × 20 задач × 3 повтора. Но часть запросов падала, я их перезапускал, и в итоговую таблицу для каждой тройки «модель, задача, номер повтора» брал последнюю запись. Один результат glm-5.3-flash так и остался с тайм-аутом после всех попыток. Реальных запросов, соответственно, было заметно больше 180.

Тут есть неприятный момент в учёте, о котором надо сказать прямо. В ранних записях я не сохранял причину завершения ответа (finish reason), поэтому «полным» скрипт считал любой ответ, где нашлась метка уверенности. В основной серии ответов без метки было шесть, их я выбросил и запросил заново: четыре пустых и два обрезанных. Один обрывается прямо внутри блока кода, второй — на слове CONFIDENCE после закрытого блока. Ни одного законченного ответа, где модель просто решила не писать оценку, среди них нет. Так что «179 из 179 SURE» — это про итоговую выборку после перезапросов, а почему те шесть оборвались, по сохранённым логам уже не восстановить.

Ошибка 1: days_between режет строку не там

glm-5.3-flash. Функция принимает две даты в формате YYYY-MM-DD и считает разницу в днях. Сначала она добросовестно проверяет формат регуляркой, в комментариях упомянуты лишние пробелы, Unicode-цифры и несуществующие даты. Видно, что модель думала про граничные случаи. А потом разбирает строку так:

year = int(s[0:4])
month = int(s[4:6])
day = int(s[6:8])

Это срезы для YYYYMMDD без дефисов. Для YYYY-MM-DD месяц сидит в [5:7], день в [8:10]. На самом первом нормальном вызове с 2024-01-01 и 2024-01-31 получаем:

ValueError: invalid literal for int() with base 10: '1-'

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

Ошибка 2: два .. схлопнулись в ничего

Задача на нормализацию пути. По условию начальные .. в относительном пути надо сохранять: ../../a должен остаться ../../a, потому что мы не знаем, что лежит выше текущего каталога. glm-5.3-flash в двух из трёх повторов возвращал просто a.

Причём в одном из этих ответов стоял абсолютно правильный комментарий:

# Relative path: unresolvable ".." must be kept.

Код под комментарием делал вот что. Первый .. честно клал в стек. На втором проверял только, что стек не пустой, и снимал верхний элемент. Проверки «а не .. ли там лежит» не было. В результате два подъёма к родителю аннигилировали друг друга, и от ../../a оставалось одно a.

Ошибка 3: единица измерения уехала на одну позицию

claude-haiku-5-5, единственный промах у этой модели. format_bytes(1024) возвращает 1.0 MiB вместо 1.0 KiB. Число байтов делилось на нужную степень 1024, а индекс в массиве единиц оказался на единицу больше, чем надо. Классический off-by-one, только не в цикле, а в подписи.

Здесь посыпалось почти всё: 11 из 14 тестов. Вместе с датами и двумя ответами про пути это и есть все четыре провала из таблицы. И под каждым из четырёх, напомню, стояло SURE.

Чего отсюда вытащить нельзя

Многого.

Ранжировать модели по этой таблице нельзя. Задач всего 20, а три повтора одной задачи — это не три разные задачи. Я не пробовал другие формулировки промпта, не задавал вопрос об уверенности отдельным сообщением и не давал моделям запускать код. Любой из этих вариантов мог бы изменить картину, я просто не знаю, в какую сторону.

С тестами тоже не всё чисто. Задачи, тесты и эталонные решения я готовил с помощью Claude. Эталоны проходят все 247 случаев, но это не исключает, что в условии и в проверке зашита одна и та же ошибка, и я её просто не вижу. Возможное преимущество модели из той же семьи (claude-haiku-5-5 решает задачи, которые помогал составлять Claude) я отдельно не изучал. Проверяющий скрипт ещё и довольно снисходительный: списки и кортежи считает эквивалентными, при необходимости сам добавляет from _ _future_ _ import annotations.«Прошло тесты» в таблице значит ровно «прошло мою проверку со всеми её допущениями», не больше.

И с условиями на стороне API мутно. Медиана входных токенов, которую возвращал интерфейс: около 4527 для gpt-6.1-sol, 315 для claude-haiku-5-5 и 219 для glm-5.3-flash. Это по основной выборке, только по тем записям, где статистика вообще была. Промпт у всех один и тот же, откуда разница на порядок, я не знаю, могу только гадать. Полного серверного контекста в логах нет. Поэтому утверждать, что модели работали в одинаковых условиях, я не могу. Температуру и seed в клиенте я явно не задавал, это тоже минус.

Была ещё серия с deepseek-v4-flash, но она развалилась: из 60 запланированных результатов по тому же правилу в выборку попал только 31. Все 31 — SURE, все прошли тесты. Остальное — 18 тайм-аутов и 11 ответов без метки уверенности. С такой дырой в данных я не стал тащить её в основную таблицу, просто упоминаю.

Что я из этого забираю

Самое полезное для меня здесь не процент, а сами ошибки. Обычная дата. Два .. подряд. Подпись единицы. И ни одна из этих ошибок не помешала ответу закончиться словом SURE при явной инструкции писать его только при полной уверенности.

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

Следующий заход начну с починки учёта: ответы без самооценки сохранять отдельной категорией, а полноту ответа определять по finish reason, а не по наличию метки. Потом можно сравнить два варианта: отдельное сообщение «перепроверь» и агент с возможностью запустить код. Данных по ним у меня пока нет, так что обещать ничего не буду.

А у вас было наоборот: модель сама засомневалась в своём коде ещё до тестов? Интересно, что для этого пришлось спросить.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.