Исследования ИИ

Детерминированный tool-routing: почему LLM — плохой диспетчер инструментов

Статистический tool-calling ненадёжен: модель пропускает очевидные вызовы или выдумывает несуществующие инструменты. Skilly PGP предлагает детерминированный слой маршрутизации между намерением агента и вызовом инструмента.

27 марта 2026 г.
6 мин чтения
tool-callingLLMAI-агентыSkillyPGPдетерминизммаршрутизация инструментовMCP

Проблема, которую все видят, но мало кто называет

Вы подключили к агенту десяток инструментов через MCP. Описали каждый в системном промпте. Протестировали — вроде работает. Выкатили в прод — и начался хаос.

Модель забывает вызвать калькулятор, когда пользователь просит посчитать. Вызывает API погоды вместо поиска по базе. Выдумывает инструмент validate_email, которого нет в реестре. Уверенно возвращает результат «вызова», который никогда не происходил.

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

Как работает tool-calling сегодня

Стандартная схема: LLM получает список доступных инструментов (function definitions), промпт пользователя и должна решить — вызывать инструмент или отвечать текстом. Если вызывать — какой именно, с какими параметрами.

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

Три типовых сбоя

Пропуск вызова (false negative). Пользователь спрашивает: «Сколько будет 1847 × 293?» Модель уверенно отвечает «541,171» вместо вызова калькулятора. Правильный ответ — 541,371. Разница в одну цифру, и поймать её невозможно без проверки.

Фантомный вызов (hallucinated tool). Модель генерирует вызов инструмента, которого нет в реестре. Если фреймворк не валидирует имя — получаем ошибку на уровне runtime. Если валидирует — модель пытается «объяснить» пользователю, почему инструмент недоступен, хотя его никогда не существовало.

Неправильный выбор (wrong dispatch). Из пяти инструментов поиска модель выбирает search_web, когда контекст однозначно указывает на search_internal_docs. Решение зависит от того, как описаны инструменты, от длины контекстного окна и от фазы луны.

Почему prompt engineering не решает проблему

Первая реакция — дописать в системный промпт: «ВСЕГДА используй калькулятор для математических вычислений». Это помогает в конкретном случае, но создаёт хрупкую систему правил.

При 20 инструментах нужно 20 правил. Правила конфликтуют. Модель интерпретирует их по-разному в зависимости от контекста. При обновлении модели правила перестают работать. Это как писать бизнес-логику комментариями к коду, надеясь, что компилятор их прочитает.

Skilly PGP: детерминированный слой маршрутизации

Идея Skilly (Pattern-Guided Parsing) — вынести решение о маршрутизации из LLM в отдельный детерминированный слой. Модель по-прежнему общается с пользователем, понимает контекст и формулирует намерение. Но решение «какой инструмент вызвать» принимает не она.

Слой 1: Извлечение намерения

LLM анализирует запрос и возвращает структурированное описание того, что пользователь хочет сделать. Не название инструмента — а семантику задачи: «вычислить арифметическое выражение», «найти документ по ключевым словам», «получить текущую погоду для города X».

Слой 2: Детерминированный маршрутизатор

Набор правил (pattern matching, decision tree, конечный автомат), который по структурированному намерению определяет инструмент и валидирует параметры. Этот слой — обычный код. Его можно тестировать, версионировать, покрывать unit-тестами.

Слой 3: Исполнение и интеграция

Вызов инструмента, получение результата, передача обратно в LLM для формулировки ответа.

Что это даёт

  • Детерминизм на критическом участке. Если правило говорит «арифметика → калькулятор», вызов произойдёт всегда — неважно, какая модель за слоем 1.
  • Тестируемость. Маршрутизатор — это код. К нему пишут тесты: «при намерении X вызывается инструмент Y с параметрами Z».
  • Модель-агностичность. Можно менять LLM-провайдера, не трогая маршрутизацию.
  • Аудитируемость. Каждое решение — запись в логе с чётким обоснованием.

Когда детерминированный routing оправдан

Не везде. Для чатбота-игрушки статистический tool-calling приемлем. Но как только появляется хотя бы одно из условий — routing нужно выносить:

  • Финансовые операции. Неправильный вызов API = потеря денег.
  • Медицина и здоровье. Пропуск вызова диагностического инструмента — не «забавный баг».
  • Продуктовые агенты. Пользователь платит за результат.
  • Мультимодельные системы. Нужен единый маршрутизатор.
  • Больше 10 инструментов. Точность статистического выбора падает нелинейно.

Реальные цифры

Исследование «Reducing Tool Hallucination via Reliability Alignment» (2025) показало, что даже frontier-модели при работе с 20+ инструментами допускают: 3–7% фантомных вызовов, 8–15% неверного выбора, 5–12% пропуска вызова.

Для агента, обрабатывающего 1000 запросов в день, это 50–300 ошибок. Каждый день.

Как это вписывается в экосистему MCP

Model Context Protocol стандартизировал обнаружение, описание и вызов инструментов. Но MCP не решает вопрос «кто принимает решение о вызове». По умолчанию — LLM.

Skilly-подход не противоречит MCP, а дополняет его. MCP описывает инструменты, маршрутизатор использует эти описания для построения правил. Это похоже на то, как в микросервисной архитектуре API Gateway не заменяет сервисы — он решает, какому сервису направить запрос. LLM — это сервис понимания языка. Маршрутизатор — это gateway.

Практические шаги

  • Шаг 1. Аудит ошибок. Логируйте каждый tool-call: запрос → решение модели → результат. Через неделю посчитайте процент ошибок по трём категориям.
  • Шаг 2. Классификация намерений. Составьте таблицу: «тип задачи → инструмент».
  • Шаг 3. Промежуточный вариант — валидация. Модель решает, какой инструмент вызвать, а детерминированный код проверяет, разрешён ли этот вызов в данном контексте. Это уже устраняет фантомные вызовы.
  • Шаг 4. Полный routing. Когда валидация покажет регулярные ошибки в выборе — переносите решение в код.

Заключение

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

Skilly PGP — один из первых проектов, явно формализующих этот принцип. Архитектурный паттерн «детерминированный слой между намерением и вызовом» — это направление, в котором двинется вся индустрия агентных систем. Вопрос не в том, перейдём ли мы на детерминированный routing, а в том, сколько ошибок допустим, прежде чем перейдём.

Автор: Алик Завалишев

Эксперт по ИИ и автоматизации процессов

Больше статей