Как оценить библиотеку для ИИ-агентов без слепой проверки финального ответа

от автора

Benchmarking transformers revisions across different metrics

Сравниваем ревизии transformers по разным метрикам

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

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

В этой статье я расскажу про бенчмарк для конкретного инструмента, который оценивает, как агент нашёл ответ, а не только сам результат. Заодно покажу простую реализацию такого стенда оценки: он целиком работает на открытых моделях под управлением ИИ-агента для программирования pi. Все комбинации «модель × ревизия × задача» распределяются между задачами Hugging Face Jobs, поэтому каждый прогон выполняется на одинаковом железе.

Но как сделать ПО удобным для ИИ-агентов?

Мы твёрдо верим в два принципа разработки ПО:

  • Если что-то не протестировано, значит, это не работает.

  • Если что-то не задокументировано, значит, этого не существует.

Для инструментария, оптимизированного для работы с ИИ-агентами, это по-прежнему верно — и здесь эти два принципа напрямую связаны.

Хотите, чтобы ваш инструмент вообще существовал для агента, — сделайте его легко находимым. API должен быть понятным, документация — подробной. Всё это нужно организовать так, чтобы агент быстро находил нужные файлы и примеры. А если хотите, чтобы агент действительно мог пользоваться инструментом, проверяйте его пригодность для использования ИИ-агентами.

Тестируем ПО на пригодность для использования ИИ-агентами

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

Мы предполагали, что работу с transformers можно радикально упростить несколькими изменениями: добавить CLI, пакет инструкций Skill и самодостаточные примеры для конкретных задач. Похожий подход недавно применили к CLI hf, который переработали для работы с ИИ-агентами: агенты стали расходовать в 1,3–1,8 раза меньше токенов, а в отдельных случаях — до 6 раз меньше. Мы хотели понять, распространяется ли такой эффект на другие инструменты и будет ли он полезен для transformers.

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

Успех успеху рознь

Два агента могут выдать правильную метку в задаче классификации тональности, но один из них:

  • пишет Python-скрипт на 40 строк;

  • импортирует transformers;

  • отлаживает ошибку с размерностью тензора;

  • дважды запускает код заново;

  • и только затем выводит ответ;

а другой:

  • вводит transformers classify --model ... --text "...";

  • и получает результат одним вызовом.

Оба приходят к POSITIVE (0.9999), но вот какими путями агенты действительно прошли эту конкретную задачу:

# Задача: определить тональность фразы «I absolutely loved the movie, it was fantastic!»- # один агент: передаёт скрипт в python через канал и разбирает вывод- python - <<'PY'- from transformers import AutoTokenizer, AutoModelForSequenceClassification- import torch- import torch.nn.functional as F-- model = AutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased-finetuned-sst-2-english")- tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased-finetuned-sst-2-english")- inputs = tokenizer("I absolutely loved the movie, it was fantastic!", return_tensors="pt")- with torch.no_grad():-     logits = model(**inputs).logits- probs = F.softmax(logits, dim=1)- idx = torch.argmax(probs, dim=1).item()- print(model.config.id2label[idx], probs[0][idx].item())- PY+ # другой агент: одна команда+ transformers classify \+   --model distilbert/distilbert-base-uncased-finetuned-sst-2-english \+   --text "I absolutely loved the movie, it was fantastic!"

Оба способа дают один и тот же результат. Но по затратам, задержке, расходу токенов и числу сбоев их профили сильно различаются.

Если при оценке вы проверяете только итоговую строку, вы не увидите ни этих различий, ни того, помогло ли агентам изменение, которое вы внесли в библиотеку: улучшение CLI, более понятные сообщения об ошибках или пакет инструкций Skill.

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

Как мы запускаем оценку

Коротко о том, как здесь оцениваются агенты.

Каждую задачу мы запускаем в трёх вариантах, или «режимах»: агент получает три разных способа работать с transformers.

bare     pip install transformers, and nothing elseclone    the full transformers source, checked out in the working directoryskill    a packaged Skill: the CLI's docs + task examples, loaded in context

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

Ещё несколько решений:

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

  • Каждый прогон выполняется как отдельная задача в Hugging Face Jobs — по одной на комбинацию «модель × ревизия × задача». Поэтому вся матрица запусков обрабатывается параллельно на одинаковом железе, что позволяет честно сравнивать результаты даже в крупном масштабе.

  • Результаты и трейсы выполнения агентов сохраняются в Hugging Face Bucket: это быстрое хранилище без необходимости в версионировании, рассчитанное на очень высокую параллельность записи.

С какими моделями сравниваться

Не все модели, управляющие агентами, одинаковы. Их различия влияют и на то, на какие показатели стоит смотреть при оценке.

Крупные открытые модели

С одной стороны находятся самые большие и сильные открытые модели. На достаточно типичных задачах они в итоге должны выдавать правильный ответ. Для них успешное выполнение задачи быстро выходит на плато около 100% и перестаёт многое говорить о качестве вашего инструмента. Гораздо важнее измерять, сколько усилий потребовалось агенту: сколько он сделал шагов, израсходовал токенов и секунд, шёл ли он прямым путём или использовал устаревшие API.

Локальные модели

Локальные модели сильно различаются по размеру, а вместе с ним — и по возможностям. Для них метрики вроде «доли совпадений» важнее, чем для крупных моделей: по ним видно, как размер и способности модели влияют на результаты при работе именно с вашим инструментом.

Этот стенд оценки не только помогает сопровождающим библиотек понять, как улучшить репозиторий для взаимодействия с ИИ-агентами. Он также позволяет оценивать, насколько разные агенты и модели справляются с задачами, которые важны пользователям.

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

  • доля совпадений: содержит ли итоговый ответ ожидаемый результат; правило проверки задаётся для каждой задачи отдельно — поиск подстроки без учёта регистра, регулярное выражение или точное совпадение, и всё это явно указано в отчёте;

  • медианное время и медианное число токенов: отдельно учитываются новые, кэшированные и сгенерированные токены;

  • доля прогонов с ошибкой: включая защитную проверку, которая помечает прогоны без какого-либо результата — с нулём выходных токенов, без вызовов инструментов и без ответа, — чтобы тихие сбои не выглядели как «0»;

  • доля запусков со сработавшим маркером: маркеры поведения, определённые для конкретного инструмента; ниже разберём, что это такое.

Все результаты попадают в отчёт, который можно изучать напрямую.

А поскольку стенд сохраняет исходные трейсы выполнения агента для каждого прогона, цифры — это только начало: можно буквально прочитать, что делал агент, команду за командой. Трейсами можно делиться через интерфейс просмотра agent-traces на Hub:

A run rendered in the Hub's agent-traces viewer: MiniMax-M2.7 on the answer-question task

Прогон в интерфейсе просмотра agent-traces на Hub: MiniMax-M2.7 выполняет задачу answer-question.

Перед результатами коротко напомним устройство эксперимента. В каждом прогоне меняются четыре параметра: модель, управляющая агентом, ревизия transformers, задача и режим (bare / clone / skill). Как мы уже говорили, для двух категорий моделей мы смотрим на разные метрики.

Крупные открытые модели: фиксируем модель, меняем ревизию

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

Естественный эксперимент здесь — зафиксировать одну сильную модель и менять ревизии инструмента: последовательные Git-версии transformers, которые мы сравниваем, — от релизных тегов вроде v5.8.0 и v5.9.0 до конкретного коммита, добавляющего CLI и пакет инструкций Skill. Нас интересует, растёт или снижается нагрузка, которую инструмент создаёт для агента. Мы применили стенд оценки к transformers, чтобы проверить, действительно ли отдельный CLI и Skill облегчают агентам работу.

Для трёх крупных моделей, использованных в наших тестах, среднее время выполнения всех задач показывает, что коммит с Skill сокращает время работы над задачами:

Median time per revision, by tier

Медианное время по ревизиям и режимам: коммит с Skill отмечен зелёной точкой и даёт самый быстрый результат.

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

Median new tokens per revision, by tier

Медианное число новых токенов по ревизиям и режимам: в варианте clone расход резко растёт после появления CLI в репозитории.

Трейсы выполнения в режиме clone объясняют, почему так происходит. Коммит добавляет команду, но вместе с ней в репозиторий попадают реализация CLI и набор примеров использования из cli/agentic/*.py.

В режиме clone перед агентом лежит полная рабочая копия transformers, и примерно в трети прогонов он изучает новый интерфейс — дерево /cli/ и скрипты-примеры, — прежде чем вызвать CLI. Поэтому медианный объём входного контекста растёт примерно с 4 тыс. до 6,4 тыс. токенов.

Получается, что эти две диаграммы показывают разные стороны одного компромисса. Коммит сокращает время работы крупных моделей: вместо отладки Python-кода они обращаются к CLI. Но за это приходится платить токенами, потому что модели читают код, из которого узнают о CLI. Такой компромисс полезно увидеть до слияния PR.

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

Небольшие модели: фиксируем ревизию, меняем модель

Открытые модели позволяют точно контролировать переменные, которые здесь особенно важны: размер, конфигурацию, квантизацию, провайдера, обучение и всё остальное, что отличается от модели к модели. Кроме того, именно для них особенно важен удобный интерфейс инструмента. Небольшая модель, которой в минимальной среде предложили «использовать transformers для задачи X», может угадать API, изменившийся несколько релизов назад, сделать лишние вызовы инструментов или вообще получить неверный результат.

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

Match % across models, by tier

Доля совпадений для разных моделей и режимов: skill улучшает результаты более крупных моделей, но снижает их у небольших.

И это, похоже, также связано с числом токенов, которые модель получает на вход.

Median new tokens across models, by tier

Медианное число новых токенов для разных моделей и режимов.

Небольшое замечание о честном сравнении: простое усреднение по задачам вводит в заблуждение, когда покрытие неравномерно. Например, модель, которая завершила только самые быстрые задачи, будет выглядеть быстрой. В отчёте есть переключатель shared tasks only: он позволяет сравнивать только общие выполненные задачи — между моделями, ревизиями или и теми и другими. А тепловая карта покрытия показывает, какие именно ячейки «задача × ревизия × модель» действительно были выполнены.

Дорабатываем инструмент: маркеры и результаты

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

Что такое маркер?

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

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

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

Для transformers мы определили несколько маркеров, но здесь рассмотрим два наиболее важных:

  • cli: агент вызвал инструмент командной строки transformers — например, transformers classify … — вместо того чтобы писать Python-код;

  • pipeline: агент использовал высокоуровневый API pipeline(...) на Python.

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

CLI adoption by tier across models

Использование CLI по режимам для разных моделей: к нему обращаются только в режиме skill, причём с ростом модели всё чаще.

Использование CLI — новый паттерн: сам CLI появился в одном коммите, его ещё нет в обучающих данных ни одной модели и он лишь поверхностно описан в документации. Эффект хорошо виден: именно вариант skill, в котором есть документация CLI, действительно начинает использовать этот интерфейс — в 55,3% случаев.

Помогает ли коммит с CLI и Skill?

Сравнение коммита на моделях разного размера показывает, что CLI вместе с Skill помогает более крупным моделям. В режиме skill Kimi и другие крупные агенты начинают обращаться к CLI и завершают задачи за меньшее число шагов. В clone они сначала тратят больше входных токенов, изучая новый код CLI, как мы уже видели выше, поэтому выигрыш проявляется во времени и числе шагов, а не в чистом расходе токенов.

Kimi-K2.6, GLM-5.1, and MiniMax-M2.7 across revisions

Kimi-K2.6, GLM-5.1 и MiniMax-M2.7 на разных ревизиях.

Но в некоторых конфигурациях с небольшими моделями изменения, похоже, ухудшают результат. Одно из возможных объяснений: небольшие модели сильнее опираются на запомненные шаблоны API и воспроизводят фрагменты с pipeline(...), которые встречали в обучающих данных. Новые сущности становятся для них дополнительным интерфейсом, в котором проще ошибиться. Это хорошо видно в стенде оценки: снижается доля совпадений, растёт число повторных попыток, а маркер cli почти не срабатывает. Особенно заметен эффект на Qwen3-4B: Skill почти не меняет её долю совпадений, но существенно влияет на распределение затрат.

Почти весь этот эффект связан с режимом clone. В рабочей копии теперь лежат реализация CLI и примеры cli/agentic/*.py, и агент на 4B-модели массово читает их: медианное число новых токенов растёт примерно с 2,4 тыс. до 23 тыс. При этом резко увеличиваются и время, и объём вывода — без какого-либо выигрыша в точности.

Qwen3-4B cost distributions across revisions: elapsed, new tokens, repeat tokens, out tokens

Qwen3-4B на разных ревизиях. Коммит с CLI и Skill резко расширяет распределение затрат: в режиме clone агент массово читает добавленный исходный код CLI — примерно в 10 раз больше новых токенов, — но доля совпадений не растёт. (repeat tokens остаётся неизменным: в этой конфигурации не используется кэширование промптов.)

Иногда Skill и вовсе ломает корректность. Это видно, например, по трейсам Qwen3-14B: после добавления Skill её общая доля совпадений падает с 67% в bare до 43%, а на простейших задачах просадка особенно заметна. Для classify-sentiment результат в clone составляет 100%, а с Skill падает до 0%.

Qwen3-14B classify-sentiment match % by tier across revisions

Qwen3-14B на classify-sentiment по режимам: в clone (синий) результат остаётся на уровне 100% на всех ревизиях, а вариант skill (зелёный) на ревизии с CLI и Skill падает до 0%.

По трейсам видно, что модель принимает CLI за инструмент, который можно вызвать напрямую, как инструмент в стенде для агентов — например, web-search. Но Skill — не исполняемый инструмент, а документация, загруженная в контекст агента. Сам CLI transformers предполагается запускать только из оболочки, через bash, поэтому такой подход не сработает.

Qwen3-14B читает Skill и в 39 из 56 прогонов с Skill либо генерирует вызов transformers(command="classify", ...) — инструмента, который никто не регистрировал, — либо не находит ничего похожего среди доступных ей read / bash / edit / write, решает, что не может запустить модель, и сдаётся. В обоих случаях вместо того, чтобы перейти к однострочному вызову pipeline(...), который давал 100% в рабочей копии clone, она объявляет задачу невыполнимой.

Qwen3-14B gives up on classify-sentiment under the Skill variant

Qwen3-14B на classify-sentiment в режиме skill: модель рассуждает, что read / bash / edit / write не позволяют запустить модель, и прекращает попытки.

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

Это также намекает на возможное решение: вместо того чтобы вручную написать Skill, а затем проверять его задним числом, можно сразу генерировать и валидировать его на более слабых моделях.

Именно так работает Upskill: он превращает решение сильной модели в Skill, только если оно измеримо помогает более слабым моделям.

Попробуйте сами

Стенд оценки запускается одной CLI-командой — agent-eval. Установите инструмент, выполните набор задач, распределите комбинации «модель × ревизия» через HF Jobs и опубликуйте отчёт как Space на Hugging Face.

Только для использования в доверенной локальной среде. Стенд запускает ИИ-агента для программирования с отключёнными ограничениями доступа и выполняет код из любой указанной вами ревизии. Кроме того, трейсы могут содержать промпты, вывод команд и локальные пути. Прежде чем запускать инструмент на чужом коде или делиться результатами, ознакомьтесь с SECURITY.md.

Полная и актуальная конфигурация, а также инструкции по использованию находятся в README.

Подведем итоги

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

На transformers он выявил то, что мы могли бы выпустить, просто доверившись интуиции: CLI и Skill помогают самым крупным открытым моделям, но ухудшают работу самых небольших. Полезно узнать об этом до слияния PR.

Стенд построен на профилях и рассчитан на адаптацию: укажите свою библиотеку, опишите несколько задач и ожидаемые ответы — и получите такой же отчёт. Код и задачи лежат в репозитории, трейсы доступны на Hub. Расскажите, если попробуете инструмент в своём проекте!

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

  • 21 июля в 20:00. «Разработка ИИ-приложений с Claude Code». Записаться

  • 23 июля в 20:00. «Когнитивные архитектуры: ReAct, Reflection и RAG». Записаться

Больше бесплатных уроков июля смотрите в дайджесте.

ссылка на оригинал статьи https://habr.com/ru/articles/1057418/