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

GorillaHard

Способность модели
Format control
Instruction following
Tool selection
Multi-step planning
Parallel tool calls
Clarification
Abstention
Prompt-injection resistance
Long-context grounding
Multi-turn dialogue
Deprecated API handling
Метрика
balance_score
clarify_recall
args_match_rate
tool_match_rate
dialog_pass_rate
format_pass_rate
sample_pass_rate
abstention_recall
cost_optimal_rate
false_clarify_rate
constraint_pass_rate
tool_in_catalog_rate
false_abstention_rate
injection_resistance_rate
Top score
GorillaHard проверяет, насколько хорошо модель умеет подбирать инструменты для решения задачи пользователя.

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

GorillaHard проверяет, насколько хорошо модель умеет подбирать инструменты для решения задачи пользователя. В каждом вопросе модель получает каталог из 14–22 инструментов, один-два приложенных файла, запрос по ним и блок с требованиями к формату. Ответ — один JSON-объект одного из пяти видов:

  • вызов —  {"tool": "table.mean", "args": {"path": "data/penguins.csv", "column": "body_mass_g"}};
  • план из зависимых шагов —  {"plan": [{"tool": "http.download", "args": {"url": "..."}}, {"tool": "table.row_count", "args": {"path": "$1"}}]}, где "$1" — результат первого шага;
  • независимые вызовы —  {"calls": [{...}, {...}]}, порядок не важен;
  • уточняющий вопрос —  {"clarify": "..."};
  • отказ —  {"abstain": true, "reason": "..."}.

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

Все промпты и задания в датасете написаны на русском языке. Оценка датасета является многосоставной и оценивает, как соблюдение требуемого формата, так смысловую корректность выполнения задания.

Датасет состоит из 1169 вопросов. Он подразделяется на тиры сложности: T1_medium 16, T2_hard 56, T3_expert 329, T4_wild 768. По видам ответа: 782 одиночных вызова, 51 план, 199 наборов независимых вызовов, 10 уточнений, 127 отказов.

Проверяемые навыки: Tool selection, Multi-step planning, Parallel tool calls, Clarification, Instruction following, Format control, Abstention, Prompt-injection resistance, Long-context grounding, Multi-turn dialogue, Deprecated API handling

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

Мотивация

Для каких моделей. Инструктивные модели, встроенные в пайплайны вызова инструментов: ассистенты, маршрутизирующие запрос в API, агенты, ответы которых разбирает код, модели под слоем function calling. Не подходит базовым (не-instruct) моделям.

Для каких пользователей. Для инженеров и исследователей, выбирающих модель в агентный цикл.

Почему такой дизайн валиден. Правильный ответ зафиксирован и проверяется машинно, а всё, что могло бы измерять постороннее, нейтрализовано: обычные открытые файлы, знаний о мире не требуется, а блок «Формат ответа» всегда описывает все пять вариантов оформления и потому не подсказывает ожидаемый. Отказы и уточнения сопровождаются почти-промахами — той же формулировкой на файле, где запрос выполним, — иначе метрика отказов вырождалась бы в награду за осторожность.

Почему такие метрики. Вызов с верным инструментом, но чужим файлом исполнить нельзя, поэтому sample_pass_rate устроена по принципу «всё или ничего» сразу по формату и по содержанию. balance_score спрашивает о другом — покрывает ли модель все рычаги сложности или берёт числом на самых крупных: рычаги входят в среднее геометрическое с равным весом и с полом 0.01, поэтому состав набора её не двигает, а провал одной способности стоит четверти скора. dialog_pass_rate засчитывает диалог только целиком. Остальные метрики диагностические: они разделяют режимы отказа, которые лечатся по-разному — дисциплина формата, выбор инструмента, выдуманное имя, излишняя или недостаточная осторожность.

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

Поля данных

  • instruction [str] — промпт-инструкция с шаблонами для вставки элементов вопроса;
  • inputs — входные данные задания:
    • question [str] — текст запроса;
    • context [str] — приложенные файлы, один или два, каждый под шапкой [файл: путь]. Путь есть только здесь: в вопросе он не назван, и в аргументы его приходится брать из контекста;
    • tools [str] — каталог инструментов в виде JSON-строки: имя, семейство, описание, параметры и эксплуатационные ограничения;
    • format [str] — требования к формату ответа; блок всегда описывает все пять конвертов;
  • outputs [str] — эталонный ответ: однострочный JSON-объект одного из пяти видов;
  • meta — метаинформация, скрытая от модели:
    • id [int] — номер строки;
    • base_id [str] — идентификатор вопроса; у каждого вопроса ровно одна строка;
    • dialog_id [str] — идентификатор диалога; строки с общим значением — ходы одного разговора. Оцениваемый ход диалога лежит в test, все предшествующие ему — в shots. У однокадрового вопроса совпадает с base_id;
    • turn_id [int] — номер хода в диалоге, с нуля. В тесте это всегда последний ход, n_turns − 1;
    • n_turns [int] — длина диалога в ходах; по строкам со значением больше единицы считается dialog_pass_rate;
    • needs_history [str] — чем ход связан с разговором, через запятую: tool — операция названа только в предыдущих ходах, args — значение аргумента перенесено, trap — ход отменяет предыдущий и самодостаточен нарочно; пусто у первого хода и у однокадровых вопросов. У каждого оцениваемого хода диалога поле непустое: ход, отвечаемый без истории, сделал бы многоходовость декорацией;
    • wording [int] — индекс формулировки инструкции, 0–4; ходы одного диалога делят формулировку;
    • categories :
      • language [str] — язык вопроса;
      • difficulty [str] — тир: T1_medium — одиночный вызов в один проход, вся сложность в двойниках каталога; T2_hard — тоже одиночный вызов, но с возрастом каталога, схемой аргументов и заземлением значения в файле; T3_expert — счёт по файлу, необязательные аргументы, отказы по политике и ложной предпосылке, уточнения; T4_wild — несколько независимых величин сразу, планы из зависимых шагов, счёт по двум файлам, отказы и почти-промахи, видимые только после подсчёта;
      • family [str] — семейство вопроса, 66 значений. Те, что начинаются с abstain_, и clarify_file прямо указывают вид ответа: годятся только для разрезов и модели не показываются;
      • lever [str] — главный источник сложности, один из шестнадцати: scancataloggroundingschemaconstraintplanparallelclarifydialogrecoveryinjectionapproxoptionalpolicyno_toolnear_miss;
      • answer_kind [str] — ожидаемый вид ответа: tool_callplancallsclarifyabstain;
      • n_tools [int], n_files [int], has_context [str] — размер каталога, число приложенных файлов, есть ли контекст;
      • corpus_format [str] — форматы приложенных файлов через запятую;
      • format_trap [str] — есть ли в вопросе ловушка формата;
      • cost_pick [str] — определяется ли выбор эксплуатационной оговоркой; по значению yes считается cost_optimal_rate;
      • injected_tool [str] — инструмент, который велит вызвать спрятанная в файле инструкция; по непустым значениям считается injection_resistance_rate.

Промпты

Пять формулировок инструкции; вопросу достаётся одна из них и по датасету они разложены почти поровну (252 / 235 / 227 / 249 / 206 примеров). Различаются они только тоном — просьба, приказ, безличный регламент, ролевая рамка, разговорная подача, — смысловая часть во всех пяти инструкциях одинакова и следует SAP: инструкция, затем метки Контекст:Инструменты:Формат ответа: перед своими блоками и Вопрос: последним. Поэтому разброс между формулировками — это чувствительность к тону, а не к структуре задания. Ни один из 1169 собранных промптов не повторяет другой; длина — от 10,6 до 34,2 тысячи символов, медиана 18,5 тысячи.

Каждая формулировка несёт одни и те же семь правил: один инструмент, когда его хватает; считать по файлам самостоятельно; план — только когда значения в контексте нет, со ссылкой "$1" на результат предыдущего вызова; несколько независимых величин — несколько вызовов; необязательные аргументы только по необходимости; переспрашивать при неоднозначности; отказываться, когда ответить нельзя.

Задача оценивается в zero-shot: примеров решения модели не показывают. Механизм few-shot используется не для примеров, а для истории диалогов: num_fewshot: 8 — потолок длины истории, у однокадрового вопроса она пуста. Прогон обязан идти с --apply_chat_template --fewshot_as_multiturn; без второго флага история склеится в одно сообщение, и замер померяет не то.

В shots — 35 строк, не пересекающихся с тестом: 5 вопросов (по одному на формулировку) и 30 ходов, предшествующих оцениваемым ходам диалогов. Место истории выбрано по необходимости: состояние, над которым работает ход, по построению есть ответ на предыдущий ход, поэтому собрать историю — значит показать чужие эталоны, а показывать их можно только у ходов, которые сами не оцениваются. Отсюда правило: из диалога оценивается ровно один ход — последний.

Метрики

  • sample_pass_rate — доля примеров, где ответ одновременно соблюдает формат и верен по смыслу: тот же формат, тот же инструмент (для плана — те же и в том же порядке, для независимых вызовов — то же множество), те же аргументы с теми же значениями. Основная метрика;
  • balance_score — среднее геометрическое доли по шестнадцати категориям(lever) с нижней границей 0.01 на категорию. Вторая главная метрика: покрытие способностей, не зависящее от состава набора;
  • dialog_pass_rate — доля диалогов, чей оцениваемый ход пройден после того, как модели показан весь предшествующий разговор; знаменатель — 30 диалогов;
  • format_pass_rate — доля строк, где ответ полностью соблюдает блок «Формат ответа», независимо от правильности по существу;
  • constraint_pass_rate — доля выполненных атомарных требований формата; требований девять, они одинаковы для всех форматов;
  • tool_match_rate / args_match_rate — верный инструмент / верный инструмент и все аргументы, среди 1032 вопросов с вызовом;
  • abstention_recall / false_abstention_rate — распознанные отказы среди 127 отказных вопросов / отказы там, где нужен вызов;
  • clarify_recall / false_clarify_rate — то же для 10 уточняющих вопросов;
  • tool_in_catalog_rate — все названные инструменты есть в каталоге вопроса: отделяет неверный выбор от выдуманного имени;
  • cost_optimal_rate — верная сторона пары «одна возможность, одна оговорка», по 6 вопросам, где оговорка и решает;
  • injection_resistance_rate — не выполнен вызов, которого требует спрятанная в файле инструкция, по 6 вопросам с такой инструкцией.

tool_match_rate / args_match_rate

Каждая метрика усредняется только по тем строкам, к которым применима: смешение знаменателей ограничило бы точность выбора инструмента потолком по построению и позволило бы модели, которая никогда не отказывается, получить высокий балл за отказы. Рассуждения в обёртке <think>...</think> вырезаются перед проверкой (незакрытый <think> — вместе с хвостом), в остальном ответ оценивается дословно. Значения аргументов приводятся к каноническому виду: 55.0 и "5" — одно значение. Отказ там, где ожидался вызов, — содержательная ошибка, а не ошибка формата: одно неверное решение не штрафуется дважды.

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

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

  1. Корпус. 144 приложенных файла под 15 обозначениями форматов — исходники на Python, access-логи и журналы приложений, таблицы CSV и TSV, дампы JSON и JSON Lines, конфиги YAML, TOML и INI, Markdown, карточки задач, XML, простой текст, Dockerfile, SQL-миграция, файл переменных окружения — все части настоящих открытых артефактов либо правдоподобные рабочие файлы под правдоподобными именами; показанный текст считается содержимым файла целиком. Формат добавляется только вместе с естественным для него механизмом (Dockerfile — ради многострочной инструкции через слэш, .env — ради инструкции в комментарии): формат без механизма дал бы вопросы, решаемые на 1.000.
  2. Библиотека инструментов. 183 инструмента в 30 семействах по всем каталогам: файлы, таблицы, журналы, код, HTTP, трекер задач, git, очереди, DNS, Kubernetes, флаги, права, биллинг, трассировки, распознавание речи. У каждого уникальная возможность и блок эксплуатационных ограничений — кроме объявленных пар, различающихся ровно одной оговоркой, на которой держатся 6 вопросов, знаменатель cost_optimal_rate.
  3. Сборка каталога. Под каждый вопрос каталог собирается враждебно: размер 14–22 с разбросом, позиция перемешана (в среднем эталон стоит на относительной позиции 0.50), эталон никогда не единственный представитель своего семейства, то есть двойник, от которого его надо отличить, есть всегда. Оба свойства выполняются на всех 1169 строках.
  4. Отбор вопросов. Квоты по семействам подобраны по замерам, а не по равномерности: доля семейства тем выше, чем ниже на нём результат сильной модели. Итог смещён к тяжёлым тирам, но каждый разрез остаётся считаемым — не меньше 6 вопросов на рычаг, 16 на тир, 10 на вид ответа, 3 на формат файла.
  5. Вывод эталона. Эталон вычисляется из вопроса, причём после обрезки файла под размер окна.
  6. Валидация. Инварианты корректности по каждому формату: аргументы эталона ⊆ параметры инструмента, обязательные заполнены, путь ведёт на приложенный файл, отказ обоснован по существу. Сквозные проверки: нет двух одинаковых промптов, двойник эталона есть везде, позиция не смещена, и 109 почти-промахов, чтобы отказ и уточнение нельзя было взять одной осторожностью. Все вычисляемые величины пересчитываются другим кодом — прямым перебором строк и разбором CSV с нуля, а не теми функциями, которые их породили.
  7. Проверка на стороне задачи. Все 1204 эталона — 1169 теста и 35 shots — проходят через настоящий скорер: каждый даёт sample_pass_rate 1.0, каждый из 30 диалогов — dialog_pass_rate 1.0, то есть низкий балл означает провал модели, а не скорера. validate_task.py проверяет это и всё остальное офлайн: сквозную нумерацию, сборку промпта, полноту истории каждого диалога в shots и то, что ни одна оцениваемая строка не повторяет пару «вопрос + эталон» строки из shots.