Function calling или tool use — это механизм, при котором языковая модель не исполняет действие сама, а возвращает структурированное намерение вызвать внешний инструмент: API, функцию, поиск, калькулятор, CRM-операцию или запрос к базе. Практически это нужно для задач, где важны точные параметры, проверяемый результат и контроль доступа. Метод плохо подходит там, где достаточно обычного текста, где нет надежных инструментов на стороне приложения, или где нельзя допускать даже единичные ошибки в выборе действия без дополнительной проверки человеком.
Простыми словами
Обычная LLM отвечает словами. Модель с tool use может сказать не только «вот ответ», но и «для ответа мне нужно вызвать функцию с такими аргументами». Дальше уже не модель, а ваше приложение решает, выполнять этот вызов или нет.
Это важное различие. Модель не получает магическую способность ходить в интернет, списывать деньги или менять записи в системе. Она лишь предлагает структурированное действие. Исполнение всегда остается за внешним контуром: сервером, оркестратором, агентом или приложением.
- Модель выбирает инструмент и подготавливает аргументы.
- Приложение валидирует аргументы, проверяет права и выполняет вызов.
- Результат инструмента возвращается модели или пользователю.
Поэтому function calling — это не «автономность», а способ сделать поведение модели более структурированным и управляемым.
Как это работает
На практике вы описываете модели набор доступных инструментов: имя, назначение и схему аргументов. Обычно схема задается через поля, типы и обязательные параметры. Затем модель получает пользовательский запрос и решает одно из двух: ответить напрямую или запросить вызов инструмента.
- Разработчик регистрирует инструменты, например
get_order_status,search_docs,create_ticket. - Для каждого инструмента задается контракт: какие аргументы допустимы, какие обязательны, какие значения запрещены.
- Пользователь пишет запрос, например:
«Проверь статус заказа 12345». - Модель возвращает не свободный текст, а структуру вроде:
tool=get_order_status,order_id=12345. - Ваш backend валидирует параметры, проверяет права доступа и делает реальный вызов API.
- Результат можно либо отдать пользователю сразу, либо вернуть модели для финального объяснения человеческим языком.
Ключевая идея — разделение ответственности. Модель хороша в интерпретации намерения пользователя, но не должна быть источником истины для критических действий.
| Подход | Что делает модель | Где риск |
|---|---|---|
| Обычный ответ текстом | Пишет вероятный ответ | Галлюцинации, непроверяемые факты |
| JSON без инструментов | Форматирует вывод по схеме | Нет явной связи с реальным действием |
| Function calling / tool use | Выбирает инструмент и аргументы | Ошибочный выбор инструмента, неверные параметры, небезопасное исполнение без валидации |
Во многих стеках модель после вызова инструмента делает еще один проход: получает результат и формирует итоговый ответ. Это удобно, когда API возвращает технические поля, а пользователю нужен краткий вывод. Но для некоторых операций лучше отвечать без второго прохода модели, чтобы не добавлять лишнюю латентность и не терять точность.
Зачем нужно
Function calling решает несколько прикладных проблем, которые обычный чат-ответ решает плохо.
- Интеграция с внешними системами. Можно связать модель с CRM, ERP, каталогом товаров, тикетной системой, корпоративным поиском.
- Структурированный ввод. Вместо попытки парсить текст регулярными выражениями приложение получает аргументы в ожидаемых полях.
- Снижение галлюцинаций. Для фактических ответов модель опирается на результат инструмента, а не на свою память.
- Контроль и аудит. Легко логировать: какой инструмент был запрошен, с какими параметрами, кто подтвердил выполнение.
- Безопасность по контуру. Права, лимиты и бизнес-правила можно навесить на исполнение, не доверяя модели окончательное решение.
Для практиков главный плюс в том, что LLM перестает быть только генератором текста и становится интерфейсом к функциям системы. Это особенно полезно в саппорте, внутренних ассистентах, аналитических интерфейсах и полуручных рабочих процессах.
Но если задача тривиальна и не требует внешних данных или действий, tool use только усложнит систему: добавит сеть, ошибки интеграции, задержку и необходимость схем.
Пример
Представим внутреннего ассистента интернет-магазина для операторов поддержки. Оператор пишет: «Проверь, где заказ 541920 и есть ли просрочка по доставке».
У приложения есть два инструмента:
get_order_status(order_id)— возвращает текущий статус заказа и трек доставки.get_delivery_eta(tracking_id)— возвращает плановую дату доставки и факт просрочки.
Хороший сценарий выглядит так:
- Модель определяет, что прямого ответа у нее быть не может, потому что данные лежат во внутренних системах.
- Она запрашивает вызов
get_order_statusс аргументомorder_id=541920. - Backend проверяет, что оператор имеет доступ к заказу, и вызывает внутренний API.
- API возвращает статус и
tracking_id. - Модель или оркестратор делает второй вызов:
get_delivery_eta(tracking_id=...). - Финальный ответ формируется уже по фактическим данным: заказ в пути, ожидаемая дата такая-то, просрочка есть или нет.
Критически важно, что приложение не должно выполнять произвольные вызовы только потому, что модель их предложила. Для order_id нужна проверка типа, формата и принадлежности данных пользователю или роли оператора. Если модель подставит неверный идентификатор, система должна вернуть ошибку валидации, а не молча делать запрос куда попало.
В более чувствительном варианте, например при команде «отмени заказ», лучше ввести подтверждение человеком или жесткие правила: отмена возможна только в определенном статусе, только для определенных ролей и только после явного подтверждения. Tool use помогает построить такой поток, но не заменяет бизнес-логику.
Заблуждения и ограничения
- «Модель сама вызывает API». Нет. Она лишь формирует предложение о вызове. Реальный вызов делает ваше приложение.
- «Если есть схема, ошибок не будет». Схема снижает число ошибок, но не убирает неверный выбор инструмента, пропуск обязательного шага или логическую путаницу.
- «Tool use автоматически безопасен». Нет. Если результат инструмента или текст пользователя содержит вредоносные инструкции, модель может быть подвержена prompt injection. Нужны фильтрация, изоляция доверенных и недоверенных данных, а для опасных операций — отдельные подтверждения.
- «Это всегда лучше, чем обычный чат». Нет. Для FAQ, редактуры, суммаризации и многих творческих задач инструменты не нужны.
- «Можно убрать всю прикладную логику и доверить агенту». Это плохая идея для продакшена. Идемпотентность, права, лимиты, транзакции и аудит должны жить вне модели.
Есть и технические ограничения:
- Дополнительная латентность: каждый вызов инструмента — это отдельный шаг.
- Хрупкость длинных цепочек: чем больше инструментов и промежуточных состояний, тем выше шанс на сбой.
- Необходимость хороших схем: расплывчатое описание инструмента резко ухудшает выбор и качество аргументов.
- Сложность тестирования: нужно тестировать не только подсказки, но и контракт инструментов, ошибки API и ветки отказа.
Метод особенно плохо подходит для задач, где нельзя допустить неправильное действие даже с малой вероятностью: финансовые операции без двойного контроля, необратимые изменения данных, юридически значимые решения без человека в контуре.
Частые вопросы
Чем function calling отличается от просто JSON-ответа?
JSON-ответ лишь форматирует текст модели. Function calling задает семантику действия: модель выбирает конкретный инструмент из разрешенного списка, а приложение может безопасно обработать этот выбор как часть рабочего процесса.
Нужно ли давать модели прямой доступ к базе данных?
Обычно нет. Безопаснее дать ограниченные инструменты с узкими контрактами: поиск заказа, чтение карточки клиента, создание тикета. Прямой доступ к БД усложняет контроль, аудит и управление правами.
Что делать, если модель выбрала не тот инструмент?
Нужны валидация, ретраи по правилам и явные критерии маршрутизации. Для критичных сценариев полезны принудительный выбор из малого набора инструментов, дополнительные проверки на стороне кода и отказ с просьбой уточнить запрос.
Когда лучше не использовать tool use?
Когда ответ можно дать из контекста без внешних данных, когда цена ошибки слишком высока, или когда проще и надежнее сделать обычную форму, фильтр или кнопку вместо интерпретации естественного языка.
Связанные понятия
- Structured output — выдача по схеме, не обязательно связанная с вызовом инструмента.
- Schema validation — проверка типов, обязательных полей и допустимых значений перед исполнением.
- Agent — более широкий шаблон, где модель может планировать несколько шагов и использовать инструменты в цепочке.
- RAG — получение внешних знаний через поиск и подстановку контекста; часто используется вместе с tool use, но не равен ему.
- MCP — протокол для стандартизированного подключения моделей к инструментам и данным.
- Human-in-the-loop — подтверждение человеком перед рискованным действием.
Если нужен практический ориентир, думайте о function calling не как о «магии агента», а как о строго описанном интерфейсе между вероятностной моделью и детерминированной системой. Чем уже набор инструментов, чем лучше их схемы и чем жестче контроль исполнения, тем полезнее этот подход в продакшене.