Модель работает только с текстом: она не сходит в базу данных, не узнает курс валют и не оформит заказ. Зато она умеет сказать, какую функцию для этого нужно вызвать и с какими аргументами. Выполняет функцию приложение, результат возвращается модели, и та формулирует окончательный ответ.
- В запрос вместе с сообщениями передаётся описание доступных функций.
- Модель отвечает не текстом, а списком вызовов: имя функции и аргументы.
- Приложение выполняет вызов своими силами и получает результат.
- Результат отправляется следующим запросом, и модель отвечает уже с учётом данных.
Модель ничего не вызывает сама и не имеет доступа к коду. Она лишь сообщает, что хотела бы вызвать — решение остаётся за приложением.
Функции перечисляются в поле tools. У каждой есть имя, описание и схема аргументов в формате JSON Schema. По описанию модель понимает, когда функция уместна, поэтому формулировать его стоит внятно.
curl "https://api.proxyapi.ru/v1/chat/completions" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <КЛЮЧ>" \ -d '{ "model": "google/gemini-2.5-flash", "messages": [ {"role": "user", "content": "Какая погода в Иркутске?"} ], "tools": [{ "type": "function", "function": { "name": "get_weather", "description": "Текущая погода в городе", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "Название города"} }, "required": ["city"] } } }] }'
Если модель решила воспользоваться функцией, поле content приходит пустым, а finish_reason равен tool_calls. Сами вызовы лежат в массиве tool_calls:
{ "choices": [{ "message": { "role": "assistant", "content": null, "tool_calls": [{ "id": "call_a1b2c3", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\": \"Иркутск\"}" } }] }, "finish_reason": "tool_calls" }] }
Аргументы приходят строкой, а не объектом: поле arguments нужно разобрать как JSON. И проверить — модель может передать неожиданное значение или пропустить обязательное поле.
Результат отправляется следующим запросом. В messages добавляются два сообщения: ответ модели с вызовом — как есть, и результат в роли tool с тем же идентификатором tool_call_id.
{ "model": "google/gemini-2.5-flash", "messages": [ {"role": "user", "content": "Какая погода в Иркутске?"}, { "role": "assistant", "tool_calls": [{ "id": "call_a1b2c3", "type": "function", "function": {"name": "get_weather", "arguments": "{\"city\": \"Иркутск\"}"} }] }, { "role": "tool", "tool_call_id": "call_a1b2c3", "content": "{\"temperature\": -18, \"condition\": \"ясно\"}" } ] }
Описание tools передаётся и во втором запросе тоже: без него модель не поймёт, откуда взялось сообщение в роли tool. Цикл может повториться — ничто не мешает модели запросить ещё один вызов после первого результата.
| Параметр | Что делает |
|---|---|
tool_choice: "auto" | Модель решает сама, вызывать функцию или ответить текстом. Поведение по умолчанию |
tool_choice: "none" | Функции описаны, но вызывать их запрещено |
tool_choice: "required" | Ответить текстом нельзя, нужно выбрать хотя бы одну функцию |
tool_choice с именем функции | Обязать вызвать конкретную функцию |
parallel_tool_calls: false | Запретить несколько вызовов в одном ответе |
Поддержка этих параметров зависит от модели: не каждая умеет вызывать несколько функций сразу или подчиняться жёсткому tool_choice.
- Структурированный вывод — как получить JSON по схеме, если внешний вызов не нужен.
- Генерация текста — устройство запроса и ответа.
Частые вопросы
Модель сама выполняет функцию?
Нет. Она только сообщает имя функции и аргументы. Выполнить вызов и вернуть результат должно приложение — доступа к коду у модели нет.
Почему аргументы приходят строкой?
Так устроен формат: поле arguments содержит JSON в виде текста, который нужно разобрать самостоятельно. Значения стоит проверять — модель может ошибиться в типе или пропустить обязательное поле.
Работает ли вызов функций с моделями не от OpenAI?
Да, формат описания функций одинаковый для всех моделей каталога, которые умеют вызывать инструменты. Различаются только аккуратность выбора и поддержка нескольких вызовов за раз.
Сколько функций можно описать в одном запросе?
Ограничения на число нет, но каждое описание занимает место в контексте и оплачивается как входные токены. Чем длиннее список, тем чаще модель выбирает неподходящую функцию.
Последняя редакция: 2 сентября 2026 г.