Вернуться к списку задач

SOB-Hard

Способность модели
Structured output
Format conversion
Format control
Instruction following
Long-form exact generation
Метрика
balance_score
task_pass_rate
format_pass_rate
sample_pass_rate
content_pass_rate
constraint_pass_rate
Top score
SOBHard измеряет структурированный вывод между машинными нотациями

Описание задачи

SOBHard измеряет структурированный вывод между машинными нотациями. Модель получает настоящий документ — иногда два — и должна выдать документ в другой нотации, упакованный ровно так, как требует промпт.

825 вопросов на русском языке: 11 семейств работ × 3 уровня сложности × 25 вопросов в клетке. Эта сетка — единственная ось, выровненная точно; нотации, длины и корпус не выровнены намеренно, см. «Где баланс есть, а где нет». Пятнадцать нотаций-источников (csvfwfhtmlinijsonjsoncjsonlloglinemdtablepropertiesscsvtomltsvxmlyaml) и шесть целевых (jsonjsonlyamltomlproperties, SQL INSERT).

Семейство Что требуется
convert тот же документ в другой нотации, данные без изменений
extract собрать значения по перечисленным путям в один объект
repair починить сломанный документ, затем переписать его по правилу
transform переписать документ по правилу из нескольких шагов подряд
schema_gen схема в стиле draft-07 для того, во что документ превратится после правила
patch применить нумерованный список операций set / delete / insert
diff различия двух версий объектом added / removed / changed
apply_diff применить такой объект изменений к версии 1
merge соединить два источника по заданному ключу
template развернуть по строке на запись по текстовому шаблону
session цепочка шагов, растянутая на несколько ходов разговора

Сложность — это длина плюс композиция: лёгкий вопрос — одна операция над примерно 7 000 символов, тяжёлый — цепочка шагов над 16 500. Почти половина исходников переваливает за 12 000 символов, самый длинный — за 62 741; чуть больше чем в четверти вопросов ответ длиннее исходника.

Ни одна проверка не выполняется моделью-судьёй. Каждое требование промпта проверяется отдельным детерминированным верификатором — 31 ограничение в четырёх слоях: упаковка (4), разбор целевой нотации (1), сверка значений (3), семантика самого семейства (23). Конвенция чтения каждой нотации написана в промпте, поэтому знание чужих стандартов не требуется, а прогон воспроизводится точно.

У девяти вопросов из 825 эталонный ответ дословно содержится во входном документе: это вопросы, где корректное действие — вернуть уже правильный фрагмент без изменений. Такие вопросы намеренно оставлены в наборе: они проверяют, что модель не ломает валидные данные.

Проверяемые навыки: Structured output, Format conversion, Format control, Instruction following, Long-form exact generation

Авторы: Артем Червяков

Мотивация

Для кого. Для инструктивных моделей, которые ставят в конвейер обработки данных, и для тех, кто решает, можно ли поставить модель между двумя системами, где формат нарушать нельзя. Такой читатель понимает sample_pass_rate как долю документов, которые пройдут дальше по конвейеру без ручной правки, а balance_score — как ответ на другой вопрос: есть ли класс работ, который модель не умеет совсем. Базовым моделям и моделям с коротким контекстом набор не подходит.

Что оценивает. Не понимание текста, а удержание структуры при переписывании: прочитать документ по объявленной конвенции, применить объявленную операцию, выписать результат в другой нотации целиком и без единого расхождения. Композиция и удержание промежуточного состояния между ходами оцениваются отдельно. Поскольку ответ — целый документ, оценка не сводится к угадыванию: ошибка в одном значении из тысячи видна и названа, а обходные пути набирают ровно ноль — вернуть вход, выдать пустой документ, бросить цепочку на полпути.

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

Описание датасета

Сплитов два, и делятся они по роли, а не по размеру. В test лежат 825 оцениваемых вопросов. В shots — 203 строки, которые можно показывать вместе с ответами: десять демонстраций и 193 ранних хода 75 разговоров. Их ответы и есть та история, которую продолжает оцениваемый ход.

Где баланс есть, а где нет

Точно выровнена одна ось, остальные — нет. Считать долю по невыровненной оси нормально там, где уровень большой, и обманчиво там, где он мал, поэтому вот числа.

Точно. Семейство × сложность: 33 клетки ровно по 25 вопросов, по 275 на уровень сложности. Именно по этой сетке усредняется balance_score, и это единственный срез, где клетки можно сравнивать друг с другом напрямую.

Ровно с точностью до вопроса. Речевой регистр: пять регистров, и в 30 клетках из 33 каждый встречается ровно пять раз. Три клетки session неровные — от четырёх до шести на регистр, — потому что разговор говорит одним голосом, регистр принадлежит всей цепочке, а 25 ходов клетки складываются из 25 цепочек разной длины. По всему сплиту пять регистров дают от 164 до 167.

Неровно намеренно. Длина документа, потому что длина — это половина того, что здесь значит сложность: 50 коротких, 275 средних, 500 длинных, и смесь меняется с уровнем — на лёгком 50/145/80, на среднем 0/100/175, на тяжёлом 0/30/245. Средний вход растёт с 9 700 до 14 000 и 17 200 знаков.

Неровно, и выравнивать нечего. Нотации идут за тем, что может дать корпус:

больше всего меньше всего
источник yaml 153, json 134, jsonl 88 ini 8, properties 4
цель yaml 273, json 242, jsonl 157 SQL  INSERT 37, properties 3

Доля по properties как цели считается по трём вопросам и не значит ничего; ini и properties как источники — немногим больше. Корпус неровен так же: 114 файлов, медиана пять вопросов на файл, и одна таблица стоит за 93 из них.

Поля данных

  • instruction [str] — шаблон промпта с местами для вставки частей вопроса
  • inputs [dict] — четыре блока промпта: task (что за работа и в каких нотациях), input_data (исходный документ или два под фиксированными метками), format (требования к упаковке и правила сверки), question (конкретная инструкция)
  • outputs [str] — эталонный ответ в блоке кода с нужным тегом. Заполнен в. shots, у оцениваемых строк пуст
  • meta [dict] — id и base_idfence_tag, тег, который должен нести блок ответа; reference, эталонный документ сырым текстом — скоринг читает эталон отсюда, а не из outputs — и его reference_sha256task_meta и checks, JSON-строки с параметрами самого вопроса и каноническими структурами, из которых верификаторы выводят ответ; dialogue_idturn_indexn_turns — координаты хода в разговоре и null в остальных случаях; и categories — семейство, сложность, язык, нотации источника и цели, длина, речевой регистр, файл корпуса

Промпты

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

Задача:
<что за работа и в каких нотациях>

Входные данные:
<исходный документ>

Формат ответа:
<требования к упаковке и правила сверки>

Инструкция:
<конкретное задание>

20 шаблонов: пять речевых регистров — casualrequestspecformalcommand — по четыре редакции каждый. Как они распределены — в разделе «Где баланс есть, а где нет».

Многоходовые вопросы

Семейство session — 75 разговоров на 268 ходов: тридцать шесть по три хода, тридцать пять по четыре, четыре по пять. Первый ход показывает документ, каждый следующий работает над результатом предыдущего, который в промпте не повторяется.

Оценивается один ход разговора, и это последний. Это не выбор, а следствие: состояние, с которого ход начинает, — это ответ на предыдущий ход, поэтому оценить два хода одного разговора значило бы опубликовать ответ на один из них. 193 ранних хода лежат в shots вместе с ответами, и few-shot-сэмплер воспроизводит их как историю оцениваемого хода.

Под многоходовостью ход (turn) — обычный вопрос обычного семейства: 165 ходов из 268 — работа patch, 103 — transform, — и проверяется ограничениями этого семейства плюс одним: ответ, который лишь повторяет уже лежащее на столе состояние, не принимается.

Такой прогон обязан запускаться с --apply_chat_template --fewshot_as_multiturn. Число few-shot — верхняя граница числа воспроизводимых ходов, а не количество примеров: история достаётся только оцениваемым ходам разговоров, а остальные 750 вопросов при той же команде остаются одноходовыми.

Создание датасета

Источники. 114 настоящих файлов из открытых репозиториев — конфигурации, выгрузки данных, таблицы, схемы, — прочитанных как 139 различных документов: большой файл берётся через одно из своих поддеревьев. Отбор шёл за байтовую грязь: эмодзи и суррогатные пары, экранированные кавычки и переводы строк внутри значений, числа-строки, почти одинаковые ключи. Документ допускается, только если его модель данных укладывается в две-три фразы, которые можно написать в промпте; всё, что читается неоднозначно — смешанное содержимое в XML, скаляры, чью типизацию YAML решает по-своему, — отвергается, а не объясняется. Сколько вопросов даёт каждый файл, не выравнивалось: медиана — пять, самая большая таблица стоит за 93.

Сборка. Для каждого вопроса документ приводится к исходной нотации, операция применяется, эталон выписывается и читается обратно: если разбор не совпал со структурой, из которой он собран, вопрос выбрасывается. Затем эталон оценивается теми же проверками, которыми потом оценивается модель, и принимается только при 1.0 по всем применимым ограничениям. Семантика каждого диалекта реализована дважды и независимо, и обе сводятся на каждом вопросе.

Перед выпуском. Про каждое ограничение показано, что оно не только принимает эталон, но и что-то отвергает; метрики лежат в своих границах; а порядок ключей, переводы строк, BOM и хвостовые пробелы не меняют вердикт там, где вопрос их не оценивает. Одна проверка есть ровно про разделение по ролям: ни один оцениваемый ответ не встречается нигде в shots — ни ответом, ни внутри промпта раннего хода.

Оценка

Метрики

  • sample_pass_rate — доля вопросов, где выполнены сразу все применимые ограничения. Главная метрика.
  • balance_score — геометрическое среднее по 33 клеткам «семейство ×. сложность». Клетка с нулём учитывается как 0.01, поэтому одна мёртвая клетка умножает балл на 0.87, а не обнуляет его. Модель с ровными 0.60 во всех клетках получает 0.60; модель со средним 0.64 и тремя мёртвыми клетками — 0.48.
  • constraint_pass_rate — доля выполненных ограничений; частичный зачёт отделяющий одно нарушенное правило от проигнорированного формата.
  • format_pass_rate — упаковка: один блок кода, верный тег, ничего снаружи, тело разбирается как целевая нотация.
  • content_pass_rate — содержание: структура совпадает с эталоном, числа в пределах относительного допуска 1e-6, строки побайтово.
  • task_pass_rate — собственная семантика семейства: то, чего сверка с эталоном не видит.