Главная / Статьи

ToolCallingAgent против CodeAgent на локальных моделях Qwen2.5 14B

ToolCallingAgent против CodeAgent в smolagents на Mac M4: скорость и точность маршрутизации с использованием локальных моделей Qwen2.5 14B для генерации инструкций и кода при различных температурах.

Издатель: REACTAPP.TOP4 мин чтения848 слов

Источники: ToolCallingAgent vs. CodeAgent: Which Performs Better on a Local LLM?

Настройки локальных агентов быстро выявляют слабые места. Устройство, использовавшееся в эксперименте, представляло собой базовый Mac с процессором Apple M4 и 16 ГБ объединенной памяти; в нем отсутствовали возможности обработки данных в облаке и дополнительная VRAM для резерва, поэтому даже умеренный размер окна контекста мог привести к замене данных в оперативной памяти. Два стиля агентов из библиотеки smolagents — ToolCallingAgent и CodeAgent — тестировались с использованием двух локально размещенных моделей: qwen2.5-coder:14b и qwen2.5:14b-instruct. Обе модели имеют размер 14 миллиардов параметров и одинаковую базовую архитектуру, причем обе работали на одном и том же устройстве.

  • Qwen2.5:14b-instruct — это универсальная модель из серии 14 миллиардов параметров, отрегулированная на основе обширных данных инструкций и диалогов, что позволяет ей хорошо выполнять команды.
  • qwen2.5-coder:14b использует ту же основную архитектуру, но прошла дополнительную предварительную обучающую обработку на большом объеме кода, а также доработку, направленную на улучшение ее способностей к обработке кода.

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

Конфигурация

Был проведен тест на изменение температуры в значениях 0, 0,1, 0,3 и 0,6 для обоих типов агентов при выполнении одной задачи: найти пять лучших пиццерий в Сиэтле, проверить время ожидания в каждой из них и порекомендовать только те, где время ожидания ниже установленного клиентом порога. Функции, вычисляющие время ожидания и сравнивающие его с порогом, являются детерминированными.

@tool
def get_wait_time(restaurant_name: str) -> int:
    """Current wait in minutes for a restaurant. Deterministic, not a live lookup."""

@tool
def restaurants_in_wait_limit(wait_time: int, wait_threshold: int) -> bool:
    """True if the wait is within the customer's threshold."""

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

Отслеживались три показателя: задержка, завершение выполнения и точность маршрутизации, определяемая как доля всех этапов инструментальной цепочки, выполненных правильно при каждом вызове. Рассматривайте эти цифры как индикаторы, поскольку речь не идет о формальном тесте производительности.

В чем разница между двумя агентами

При использовании ToolCallingAgent каждый шаг генерирует один JSON-запрос к инструменту. Модель передает аргументы, фреймворк выполняет инструмент, после чего начинается следующий шаг. Пять ресторанов и две функции в сумме дают десять отдельных запросов, каждый из которых представляет собой новую возможность нарушить структурированный результат.

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

Результаты

На модели Qwen2.5:14b-instruct

Оба агента показали хорошие результаты. CodeAgent сохранял точность маршрутизации 1,00 при любой температуре, а ToolCallingAgent — от 0,95 до 1,00. В плане корректности между ними не было значительной разницы.

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

На модели Qwen2.5-coder:14b

Здесь оба агента резко отличались по производительности. ToolCallingAgent никогда не достигал уровня точности маршрутизации 50 процентов ни при каких настройках температуры, оставаясь в диапазоне от 0,40 до 0,50. Он работал быстрее, чем на модели для выполнения инструкций, но это не было хорошим признаком. Он действовал быстро потому, что сдавался. Как только поток обработки терялся, он прекращал отправку запросов и завершал работу раньше, сделав меньше работы.

CodeAgent одержал полную победу, добившись точности маршрутизации 1,00, что совпадает с лучшими показателями в тестах instruct. Это ожидаемо, поскольку он запрашивает у модели-кодера код на Python, а не структурированный JSON.

Что можно извлечь из этого

Преимущество CodeAgent в использовании циклов действительно существует. В тестах instruct, где оба агента показали точность маршрутизации 1,00, более эффективная обработка задач сделала CodeAgent в два раза быстрее, чем ToolCallingAgent.

Qwen2.5:14b-instruct представляет собой надежного универсала, хорошо справляющегося как с запросами в формате структурированного JSON, так и с простым кодом. Qwen2.5-coder:14b лучше использовать для сложных задач по программированию, поскольку он может давать ненадежные результаты при генерации структурированного JSON и при поддержании этого уровня качества во всей цепочке вызовов.

Открытый вопрос

Остается ещё один вопрос. Агенты отличаются двумя аспектами: CodeAgent объединяет свою работу в одну программу и использует Python вместо структурированного JSON. Следующий эксперимент может разграничить эти факторы, заставив CodeAgent генерировать структурированные запросы к инструментам при сохранении пакетной обработки. Результат покажет, происходит ли преимущество в основном благодаря циклам или потому, что модели считают создание кода проще, чем серию длинных JSON-запросов.