После выполнения этой инструкции вы настроите базовый цикл Function Calling в OpenAI API по текущему официальному пути: через Responses API, выполнение функции на стороне вашего приложения и возврат результата через function_call_output с тем же call_id. В конце вы получите финальный ответ модели в response.output_text и сможете проверить, что инструмент действительно был вызван.
- Время: 25–40 минут
- Сложность: средний
- Стоимость: зависит от модели и числа токенов. На странице Models по состоянию на 2026-08-17 были указаны цены за 1 MTok input/output:
gpt-5.6-luna— $0.20/$1.20,gpt-5.6-terra— $2/$12,gpt-5.6-sol— $5/$30. Перед продакшеном перепроверьте живую страницу Models. - Что потребуется: доступ к OpenAI API, приложение, которое умеет вызывать Responses API, и одна функция, которую вы исполняете на своей стороне.
- Актуальная версия: документация OpenAI API по состоянию на 2026-08-17. Для новых реализаций текущий путь Function Calling — Responses API; Chat Completions остаётся документированным как legacy-путь для существующих интеграций.
Если базового вызова API у вас ещё нет, сначала соберите минимальную интеграцию по инструкции Как интегрировать OpenAI API в приложение (Python/JS). Если нужен быстрый контекст по термину, посмотрите объяснение API.
Практический вердикт. Если вы строите новый tool-use сценарий, ориентируйтесь на Responses API и на цикл «модель запросила функцию → приложение выполнило → приложение вернуло
function_call_output→ модель завершила ответ». Редакционное ограничение: ниже показан базовый сценарий с пользовательской функцией. Built-in tools, региональные режимы и SDK-хелперы стоит дополнительно сверять с живой документацией и changelog перед запуском в продакшен.
Текущая модель и выбор модели для примера
Официальная страница моделей по состоянию на 2026-08-17 перечисляет gpt-5.6-sol, gpt-5.6-terra и gpt-5.6-luna как доступные через Responses API и Client SDKs с поддержкой Functions. Для примера в этой инструкции используется gpt-5.6-terra как нейтральный вариант, но сам паттерн одинаков для любой поддерживаемой модели.
| Модель | Поддержка Functions | Цена input за 1 MTok | Цена output за 1 MTok |
|---|---|---|---|
gpt-5.6-luna |
Да, по странице Models | $0.20 | $1.20 |
gpt-5.6-terra |
Да, по странице Models | $2 | $12 |
gpt-5.6-sol |
Да, по странице Models | $5 | $30 |
Эти цифры и доступность могут меняться быстро. Для рабочих расчётов и закупки лимитов используйте только актуальную страницу Models.
Пошагово: как использовать Function Calling в OpenAI API
- Зафиксируйте Responses API как основной путь и выберите модель.
Для новых реализаций ориентируйтесь на Responses API. Именно его официальное руководство описывает как текущий цикл Function Calling: модель запрашивает функцию, вы исполняете её в приложении, затем возвращаете результат через
function_call_outputи продолжаете ход сprevious_response_id.Ожидаемый результат: вы строите интеграцию не вокруг legacy-паттерна Chat Completions, а вокруг Responses API.
- Опишите функцию как tool со строгой схемой.
Если вам нужны аргументы, строго соответствующие схеме, используйте Structured Outputs и задайте
strict: true. По текущим правилам каждый параметр должен быть перечислен вrequired, а для объекта нужно указатьadditionalProperties: false.const tools = [ { type: 'function', name: 'lookup_order_status', description: 'Возвращает статус заказа по идентификатору', strict: true, parameters: { type: 'object', properties: { order_id: { type: 'string', description: 'Идентификатор заказа' } }, required: ['order_id'], additionalProperties: false } } ];Ожидаемый результат: у вас есть одна функция с валидной строгой схемой, без необязательных полей и без лишних свойств.
- Отправьте первый запрос с tools в Responses API.
На первом ходе передайте пользовательский запрос, массив
toolsи режимtool_choice. Для стартового сценария используйтеtool_choice: 'auto'. Если вам нужно последовательное поведение, сразу задайтеparallel_tool_calls: false.let response = await client.responses.create({ model: 'gpt-5.6-terra', input: 'Проверь статус заказа A-1024 и ответь по-русски.', tools, tool_choice: 'auto', parallel_tool_calls: false });Ожидаемый результат: модель либо сразу завершит ответ, либо вернёт запрос на вызов функции.
- Исполните запрошенную функцию в своём приложении.
Function Calling не означает, что модель сама ходит в вашу систему. Она только формирует запрос к функции, а само действие выполняете вы. В минимальном примере достаточно маршрутизатора по имени функции.
async function runTool(name, args) { if (name === 'lookup_order_status') { return { order_id: args.order_id, status: 'shipped' }; } throw new Error(`Unknown tool: ${name}`); }Если модель вернула несколько вызовов, обработайте каждый. Официальное руководство отдельно отмечает, что на поддерживаемых GPT-5+ моделях возможны параллельные вызовы; если это ломает ваш сценарий, оставляйте
parallel_tool_calls: false.Ожидаемый результат: вы получили объект результата, который готовы отправить модели обратно.
- Верните результат функции через function_call_output с тем же call_id.
Критичный момент в текущем паттерне — не просто отдать результат в текстовом виде, а отправить элемент
function_call_output, связанный с исходным вызовом через тот жеcall_id. Следующий ход продолжайте черезprevious_response_id.response = await client.responses.create({ model: 'gpt-5.6-terra', previous_response_id: response.id, input: [ { type: 'function_call_output', call_id: call.call_id, output: JSON.stringify(result) } ] });Ожидаемый результат: цепочка ответа продолжается в рамках того же сценария, а модель получает машинно читаемый результат выполнения функции.
- Повторяйте цикл, пока модель не перестанет запрашивать функции.
Ниже — минимальный шаблон рабочего цикла по паттерну официальной документации и Node SDK-руководства. Он полезен как опорный каркас даже если затем вы перепишете его под свой фреймворк.
const tools = [ { type: 'function', name: 'lookup_order_status', description: 'Возвращает статус заказа по идентификатору', strict: true, parameters: { type: 'object', properties: { order_id: { type: 'string', description: 'Идентификатор заказа' } }, required: ['order_id'], additionalProperties: false } } ]; async function runTool(name, args) { if (name === 'lookup_order_status') { return { order_id: args.order_id, status: 'shipped' }; } throw new Error(`Unknown tool: ${name}`); } let response = await client.responses.create({ model: 'gpt-5.6-terra', input: 'Проверь статус заказа A-1024 и ответь по-русски.', tools, tool_choice: 'auto', parallel_tool_calls: false }); while (true) { const functionCalls = response.output.filter(item => item.type === 'function_call'); if (!functionCalls.length) { break; } const input = []; for (const call of functionCalls) { const args = JSON.parse(call.arguments); const result = await runTool(call.name, args); input.push({ type: 'function_call_output', call_id: call.call_id, output: JSON.stringify(result) }); } response = await client.responses.create({ model: 'gpt-5.6-terra', previous_response_id: response.id, input }); } console.log(response.output_text);Ожидаемый результат: цикл завершается без дополнительных function calls, а в
response.output_textпоявляется финальный ответ модели. - Зафиксируйте режим управления вызовами для продакшена.
Не оставляйте поведение на уровне «как получится». В текущих документах
tool_choiceможно задавать какauto,required, принудительно указывать одну конкретную функцию или ограничивать модель выбранным набором инструментов. Это удобно, когда вы переводите сценарий из эксперимента в предсказуемый рабочий поток.Ожидаемый результат: вы понимаете, должна ли модель сама решать, вызывать инструмент или нет, и нужен ли вам последовательный режим вместо параллельного.
Как проверить, что всё работает
- Запустите пример с запросом, который почти наверняка потребует функцию:
Проверь статус заказа A-1024 и ответь по-русски. - Убедитесь, что промежуточный ответ модели породил хотя бы один запрос функции, а ваше приложение реально вызвало
runTool(...). - Проверьте, что вы отправили назад элемент
function_call_outputс тем жеcall_id, который пришёл от модели. - Убедитесь, что продолжение шло через
previous_response_id, а не через новый изолированный запрос. - Проверьте финальный
response.output_text. Официальная Node SDK-документация показывает именно этот практический способ проверки завершённого цикла.
Если финальный текст появился, но инструмент ни разу не вызывался, это тоже проверяемый результат: значит, модель решила не использовать функцию. В таком случае ужесточите инструкцию в prompt или используйте другой режим tool_choice.
Частые ошибки и исправления
- Ошибка: модель возвращает валидный JSON, но аргументы не соответствуют вашей схеме. Исправление: не полагайтесь только на JSON mode. Для schema-locked аргументов включите
strict: true, перечислите все поля вrequiredи добавьтеadditionalProperties: false. - Ошибка: вы выполнили функцию, но модель не продолжает ответ. Исправление: верните результат как
function_call_outputс тем жеcall_idи продолжите ход черезprevious_response_id. - Ошибка: ваш backend ожидает строгую последовательность, а модель создаёт несколько вызовов. Исправление: на поддерживаемых GPT-5+ моделях отключите параллельное поведение через
parallel_tool_calls: false. - Ошибка: вы ориентируетесь на старые примеры Chat Completions и получаете расхождения с текущей документацией. Исправление: для новых проектов используйте Responses API, а Chat Completions держите только как legacy-путь для существующей интеграции.
- Ошибка: автоматизация ломается из-за региональных ограничений. Исправление: перепроверьте project-level data residency, eligibility/approval и учитывайте, что в EU для
/v1/responsesесть оговорка: нельзя использоватьbackground=True.
Безопасность и ограничения
- Функции исполняете вы в приложении, а не модель. Это даёт контроль, но и оставляет на вашей стороне ответственность за допуск к данным, проверку аргументов и побочные эффекты.
- Structured Outputs использует строгий поднабор JSON Schema. Для объектов сейчас требуется перечислить все поля в
requiredи добавитьadditionalProperties: false. - JSON mode гарантирует валидный JSON, но не гарантирует соответствие вашей схеме. Если вам нужна жёсткая схема аргументов функции, используйте Structured Outputs и
strict: true. - Региональные настройки хранения и обработки данных работают на уровне проекта и требуют eligibility/approval. Для автоматизаций в EU отдельно проверьте ограничение на
background=Trueу/v1/responses. - Цены, модели и SDK-хелперы могут меняться быстрее, чем базовый паттерн цикла. Перед продакшеном сверяйте страницу Models и Changelog.
Практическое ограничение инструкции: здесь не разбираются built-in tools, агентные надстройки и все возможные SDK convenience helpers. Если вам нужен только надёжный пользовательский Function Calling, приведённого цикла достаточно; если строите сложную оркестрацию, проверяйте живые примеры в документации и репозитории SDK.
Что делать дальше
- Если хотите оформить этот пример в полноценный клиентский слой, используйте базовую заготовку из инструкции Как интегрировать OpenAI API в приложение (Python/JS).
- Если вы строите мультивендорную обвязку и сравниваете паттерны tool use, посмотрите Как мигрировать с OpenAI API на Anthropic API.
- Если нужно зафиксировать термины для команды, добавьте в документацию ссылку на глоссарий API (Application Programming Interface).
Источники
- Function calling | OpenAI API
- Function Calling in the OpenAI API | OpenAI Help Center
- Models | OpenAI API
- Structured model outputs | OpenAI API
- Data controls in the OpenAI platform
- Changelog | OpenAI API
- openai-node/docs/tools.md at main · openai/openai-node · GitHub
Вопросы и ответы
Можно ли использовать Chat Completions вместо Responses API?
Да, этот путь всё ещё документирован для legacy-интеграций. Но текущий официальный how-to для Function Calling центрируется на Responses API, поэтому для новых реализаций лучше ориентироваться именно на него.
Достаточно ли JSON mode для аргументов функции?
Нет, если вам нужно строгое соответствие схеме. JSON mode гарантирует валидный JSON, но не соблюдение вашей схемы. Для schema-locked аргументов используйте Structured Outputs и strict: true.
Можно ли заставить модель обязательно вызвать инструмент?
Да. В текущих документах tool_choice можно ставить в auto, required, принудительно задавать одну конкретную функцию или ограничивать модель выбранным набором инструментов.
Как отключить параллельные вызовы функций?
На поддерживаемых GPT-5+ моделях, где доступны built-in tools, возможны параллельные вызовы. Если вам нужно строго последовательное поведение, задайте parallel_tool_calls: false.
Есть ли региональные ограничения для автоматизаций?
Да. Data residency настраивается на уровне проекта и требует eligibility/approval. В документации отдельно отмечено, что в EU для /v1/responses нельзя использовать background=True.