Function calling против промптов: как правда работают агенты
Разница между агентом с function calling и агентом на голых промптах — это не стиль кода, а разница между 95% и 60% успешных вызовов инструментов. Разбираем, где какой подход экономит деньги и нервы.

Когда OpenAI в июне 2023 года добавила в API поле functions (позже переименованное в tools), это разделило разработчиков LLM-агентов на два лагеря. Одни переписали парсинг ответов модели на структурированный вызов функций. Другие остались на подходе «попросим модель вернуть JSON в тексте и разберём его сами». Оба подхода работают. Но ведут себя по-разному под нагрузкой, стоят разных денег и ломаются в разных местах.
Что такое function calling на самом деле
Function calling — это не магия и не отдельный движок. Модель по-прежнему генерирует текст. Разница в том, что провайдер (OpenAI, Anthropic, Google) дообучил модель отдавать вызов инструмента в отдельном структурированном поле ответа, а не внутри свободного текста. Вы передаёте описание доступных функций в формате JSON Schema, модель решает, какую вызвать, и возвращает имя функции и аргументы отдельным объектом.
Ключевое слово — дообучил. Модель с function calling видела при обучении тысячи примеров, где после описания инструментов нужно выдать корректный вызов. Модель без него вы уговариваете сделать то же самое промптом вроде «верни ответ строго в формате JSON». Первое — это натренированное поведение, второе — надежда на то, что модель послушается инструкции.
Function calling не делает модель умнее. Он делает её предсказуемее в одном узком месте — там, где текст должен превратиться в машинно-читаемую команду.
Как выглядит «без function calling»
Классический подход до 2023 года и до сих пор рабочий вариант для моделей без нативной поддержки инструментов (многие локальные модели, старые версии): вы описываете инструменты прямо в системном промпте и просите модель отвечать в согласованном формате. Дальше вы сами регулярным выражением или JSON-парсером вытаскиваете нужное.
Проблема в том, что модель может обернуть JSON в markdown-блок, добавить перед ним фразу «Конечно, вот вызов функции», поставить запятую после последнего элемента или галлюцинировать поле, которого нет в вашей схеме. Каждый такой случай — это ветка обработки ошибок в вашем коде.
Где проходит реальная граница
Спор «с function calling или без» на практике сводится к трём вопросам: насколько надёжно модель попадает в формат, сколько вы за это платите токенами и что происходит, когда что-то идёт не так.
| Критерий | С function calling | Без (промпт + парсинг) |
|---|---|---|
| Валидность формата | Высокая: провайдер гарантирует структуру, часто с валидацией схемы | Зависит от модели и промпта, ниже на длинных и сложных схемах |
| Работает на любой модели | Только там, где провайдер поддерживает tools | Да, включая локальные и старые модели |
| Расход токенов на схему | Схема считается во входных токенах, но обрабатывается эффективно | Описание инструментов вручную раздувает промпт |
| Параллельные вызовы | Многие провайдеры отдают несколько вызовов за один ответ | Нужно городить формат самому |
| Контроль и отладка | Меньше видно, почему модель выбрала инструмент | Всё в тексте, легче логировать рассуждения |
Надёжность формата: главный аргумент
Основная причина, по которой большинство продакшн-агентов сегодня используют function calling, — это стабильность парсинга. На простой функции с двумя строковыми аргументами разница между подходами почти незаметна: любая приличная модель вернёт корректный JSON и по промпту. Разрыв растёт с ростом сложности схемы — вложенные объекты, массивы, перечисления, необязательные поля.
OpenAI пошла дальше и в 2024 году добавила режим Structured Outputs, который гарантирует соответствие ответа переданной JSON Schema на уровне декодирования — модель физически не может сгенерировать токен, нарушающий схему. Это снимает целый класс ошибок парсинга. Похожие механизмы структурированного вывода есть и в других экосистемах. Точные названия режимов и их доступность по моделям сверяйте в актуальной документации провайдера — они меняются от версии к версии.
Когда function calling не нужен или мешает
Есть сценарии, где нативные инструменты не дают выигрыша или даже вредят:
- Локальные и open-source модели без нативной поддержки. Многие модели, которые вы запускаете сами, либо не обучены на function calling, либо делают это хуже, чем через грамотный промпт с примерами. Здесь ручной формат честнее.
- Один инструмент и простой аргумент. Если модель всегда вызывает одну функцию с одним полем, накладные расходы на описание схемы не окупаются. Проще попросить вернуть строку.
- Нужна цепочка рассуждений перед выбором. В некоторых реализациях модель, переключившись в режим вызова инструмента, хуже «думает вслух». Подход ReAct — где модель сначала пишет рассуждение в тексте, а потом действие — иногда даёт лучший результат на сложных задачах, чем прямой вызов.
- Портируемость между провайдерами. Форматы tools у OpenAI, Anthropic и Google не идентичны. Если вам важно менять провайдера без переписывания, абстракция поверх промпта иногда проще, чем поддержка трёх диалектов схемы.
Гибрид как норма
На практике зрелые агентские фреймворки — LangChain, LlamaIndex и им подобные — не заставляют выбирать. Они дают единый интерфейс инструментов, а под капотом используют нативный function calling там, где он есть, и падают на промпт-парсинг там, где его нет. Разработчик описывает инструмент один раз, фреймворк решает, как его передать конкретной модели.
Цена вопроса в токенах и деньгах
Описание инструментов — это входные токены, за которые вы платите на каждом запросе. Схема из десяти функций с подробными описаниями полей легко съедает тысячу-полторы токенов на каждый вызов. При тысячах запросов в день это заметная строка в счёте. Здесь у подходов паритет: и нативная схема, и ручное описание в промпте одинаково тратят токены на объяснение инструментов модели.
Разница в другом — в стоимости ошибок. Каждый невалидный JSON при промпт-подходе — это либо retry (ещё один платный запрос), либо упавшая цепочка агента. Если ваш парсер спотыкается на 5% ответов, а вы делаете повторный вызов, вы платите за 105% запросов вместо 100%. Function calling с гарантией схемы сводит эту наценку почти к нулю.
Что выбрать под свою задачу
- Работаете с GPT, Claude или Gemini через официальный API и вам нужны инструменты — берите нативный function calling. Это дефолт, который экономит вам код обработки ошибок.
- Нужна железобетонная структура ответа — включайте режим гарантированного соответствия схеме, если провайдер его поддерживает для вашей модели.
- Гоняете локальную модель — проверьте, обучена ли она на tools. Если нет, промпт с несколькими примерами формата (few-shot) часто надёжнее кривого function calling.
- Строите агента на несколько провайдеров — берите фреймворк с абстракцией инструментов, чтобы не поддерживать три формата схемы руками.
Вывод простой: function calling выиграл спор в продакшене не потому, что он «правильнее», а потому что он снимает с вас ответственность за самое хрупкое место агента — превращение текста в команду. Но это инструмент под конкретную экосистему. Как только вы выходите за пределы больших коммерческих API, старый добрый промпт с парсером снова становится рабочим и иногда единственным вариантом.
Prompt-инженер: Идеальные запросы для Midjourney, ChatGPT и других моделей.
Спросить за 15 ₽Источники: OpenAI Platform — Function calling and Structured Outputs, Anthropic — Tool use (function calling)
Частые вопросы
Function calling делает ответы модели точнее по смыслу?
Можно ли использовать function calling с локальной моделью?
Сколько токенов добавляет описание инструментов?
Structured Outputs и function calling — это одно и то же?
Что будет, если модель вернёт невалидный JSON без function calling?
Форматы tools у разных провайдеров совместимы?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.