Материал подготовлен автоматически по первоисточникам: ссылки на них — в конце статьи.
Локальный сервер может исказить оценку агента ещё до того, как модель получит запрос. Lijuan Tang и Yuemeng Zheng в работе, которая не прошла рецензирование и приводит числа, полученные самими авторами, показали, как отказ сервера превращается в правдоподобные 0% корректных вызовов. Для сравнения локальных моделей теперь недостаточно зафиксировать веса и задачу: сервер, шаблон запроса и разборщик вызовов входят в измеряемую систему.
Как сервер подменяет ответ модели
Перед выполнением действия агент должен выдать вызов инструмента: указать доступное имя и передать аргументы по заданной схеме. Модель выбирает действие, но между ней и тестовой обвязкой стоит сервер, который преобразует описание инструментов в подсказку и затем разбирает ответ.
При работе через совместимый с OpenAI API список инструментов передают в поле tools=. Сама модель это поле напрямую не видит. Сначала сервер проверяет шаблон выбранной модели, решает, поддерживает ли он инструменты, и только затем запускает генерацию.
В Ollama запросы к Qwen2.5-Coder принимались, но вызовы возвращались как текст. Llama-3.2 выдавал их через отдельное структурированное поле. Запросы к Phi-3 и Gemma-3 сервер отклонял с ошибкой HTTP 400 до запуска модели.
Использованная тестовая обвязка повторяла отклонённый запрос, а после исчерпания попыток сохраняла обычную строку ошибки как реплику ассистента. Тип сбоя в журнале не оставался. Последующий анализ видел реплику без вызова инструмента и относил её к ошибкам модели, хотя модель не сгенерировала ни одного токена.
Та же путаница возникала при пустом ответе или исчерпании повторных попыток. Поэтому долю корректных вызовов нужно считать только среди ответов, которые действительно произвела модель, а отказы сервера, тайм-ауты и пустые ответы выводить отдельными категориями.
Один запрос даёт разные результаты в разных стеках
Авторы сравнили Ollama, llama.cpp, vLLM и SGLang. Одинаковый запрос с теми же инструментами один стек отклонял, другой принимал как текст, а третий требовал явно включить разборщик вызовов. Веса Phi-3 и Gemma-3, которые Ollama не запускал, отвечали через llama.cpp.
Отдельный эксперимент разделил способ передачи схемы и содержание подсказки. Сервер продолжал получать tools=, но в текст запроса дополнительно включали список инструментов, допустимые имена и формат аргументов. У принятых сервером моделей доля корректных вызовов выросла: слабый результат стандартного режима отражал не только способности модели, но и отсутствие явной инструкции.
Единого лучшего режима не оказалось. Llama-3.2 достигал 82% со встроенным каналом и текстовой подсказкой, но при полном переходе на текстовый протокол показатель снижался до 44%. Унификация интерфейса убрала поддержку, которой модель уже умела пользоваться.
Способ усреднения тоже менял вывод. У младшей Qwen в текстовом режиме общая доля по всем репликам составляла 85%, а среднее по отдельным эпизодам — 34%: один цикл длиной 41 реплику заполнил выборку повторными корректными вызовами. Такой агент хорошо соблюдал формат, но не завершал задачу.
Ограниченное декодирование, которое разрешает генерировать только допустимую структуру, убрало ошибки разбора. Однако слабые модели начинали бесконечно вызывать инструменты. Формальная корректность вызова поэтому не заменяет проверку завершения всего агентного цикла.
Основные замеры охватывали модели Qwen2.5-Coder разных размеров, Llama-3.2, Phi-3 и Gemma-3 на задачах по коду; поведение шлюза дополнительно проверили на HumanEval. Полные серии запускали в Ollama 0.30.8, а проверки vLLM и SGLang ограничили парами с Qwen и Phi-3. Конкретные правила допуска зависят от версии сервера, поэтому результаты не образуют рейтинг моделей.
Что менять в плане оценки локального агента
Работа меняет план эксперимента, если команда выбирает локальную модель по доле успешных вызовов инструментов. Сравнивать нужно либо модели через полностью одинаковый интерфейс, либо готовые пары «модель — сервер» с подходящими для каждой пары шаблонами и разборщиками. Смешивать эти цели в одной таблице нельзя.
Для воспроизводимого сравнения стоит зафиксировать сервер и его версию, шаблон диалога, способ передачи схемы, разборщик вызовов и параметры генерации. Простого названия модели недостаточно: обновление сервера может изменить решение ещё до запуска весов.
- Сохранять структурированные сбои. Отказ запроса, тайм-аут, пустой ответ и ошибка разбора не должны превращаться в обычную реплику модели.
- Разделять выбор и формат. Отдельно проверять, выбрала ли модель правильный инструмент, сформировала ли допустимые аргументы и принял ли вызов сервер.
- Считать по эпизодам. Каждый запуск задачи должен иметь одинаковый вес, иначе длинный цикл создаст видимость высокой точности.
- Проверять завершение. Ограничение формата может гарантировать корректный JSON, но не способность остановиться после выполнения задачи.
Если тест показывает нулевую долю вызовов, сначала нужно проверить транспортную ошибку и журнал повторных попыток, затем конфигурацию разборщика и только после этого — ответы модели. Такой порядок не улучшает агента, но не позволяет отбраковать подходящие веса из-за политики сервера.
Источники
Иллюстрация: рисунок из статьи «Measuring the Serving Stack Instead of the Model: Hidden Confounds in Local Tool-Use Evaluation», Lijuan Tang, Yuemeng Zheng, CC BY 4.0
Похоже на вашу задачу?
Расскажите, что собираете. За полчаса разложим на этапы и назовём сроки — это бесплатно и ни к чему не обязывает.



