Разработка AI-приложений
Function calling в ChatGPT API: как подключить инструменты безопасно
Function calling в ChatGPT API помогает связать диалог с данными и действиями вашего продукта: проверить статус заказа, найти документ или создать черновик. Ключевое слово здесь — «связать», а не «дать модели доступ ко всему». Модель предлагает вызов, а приложение самостоятельно проверяет аргументы, права пользователя и допустимость операции. Такой контур делает автоматизацию полезной и контролируемой.
Что происходит при function calling
Обычный чат возвращает текст. В сценарии function calling клиент дополнительно передаёт список инструментов: имя, описание и схему аргументов. Если модель считает, что ей нужен инструмент, она возвращает структурированное предложение, например get_order_status с номером заказа. Сервер не обязан исполнять предложение. Он должен распарсить его, проверить JSON по схеме, сопоставить запрос с текущим пользователем и вызвать только тот внутренний метод, который явно разрешён.
После выполнения сервер возвращает модели результат инструмента в отдельном сообщении. Только тогда модель формирует понятный пользователю ответ. Важно не путать предложение вызова с подтверждённым фактом. Если база не ответила или пользователь не имеет права на объект, обработчик сообщает ограниченный безопасный результат; модель не должна «додумывать», что операция прошла. Это особенно важно для финансовых, кадровых, медицинских и любых действий с последствиями.
Начните с одного инструмента без побочных эффектов
Для первой интеграции выберите read-only задачу: поиск собственной статьи, статус фоновой задачи, список публичных событий. Не начинайте с перевода денег, отправки письма, удаления данных или изменения прав. Так проще измерить качество аргументов и понять, когда модель просит инструмент не по делу. Нужны отдельные тесты для пустых полей, длинной строки, чужого идентификатора, неподдерживаемого языка и повторной отправки одного запроса.
Описание инструмента должно быть конкретным. Вместо «получить информацию» напишите, какие данные принимает метод, что возвращает и чего не делает. Схема — не декоративный фрагмент prompt: она уменьшает неоднозначность, но не заменяет проверку. Любое значение, пришедшее от модели, считайте внешним вводом. Даже если JSON синтаксически корректен, он может содержать несуществующий номер, слишком широкий фильтр или попытку получить чужие данные.
Минимальная схема и серверная проверка
Пример ниже иллюстрирует структуру совместимого запроса. Он не гарантирует поддержку инструментов каждой моделью: до внедрения подтвердите её в каталоге RussiaAPI и документации выбранного endpoint. Ключ хранится только в переменной окружения сервера, а функция findArticle должна обращаться к вашей базе через подготовленный запрос или безопасный ORM-метод.
const tools = [{
type: 'function',
function: {
name: 'find_article',
description: 'Находит опубликованную статью по короткому запросу.',
parameters: {
type: 'object',
properties: { query: { type: 'string', minLength: 2, maxLength: 80 } },
required: ['query'], additionalProperties: false
}
}
}];
function validateArgs(args) {
return typeof args.query === 'string' && args.query.length >= 2 && args.query.length <= 80;
}
async function runTool(name, args, user) {
if (name !== 'find_article' || !validateArgs(args)) throw new Error('Tool call rejected');
if (!user.canReadPublishedArticles) throw new Error('Access denied');
return findArticle(args.query); // ваш серверный метод, не SQL из аргумента
}Этот код намеренно показывает два барьера: белый список имён и проверку аргументов. В production добавьте лимит времени, ограничение частоты, журнал аудита без секретов и корреляционный идентификатор. Не проксируйте аргументы напрямую в shell, SQL, URL для внутренних сервисов или шаблон письма. Не позволяйте модели выбирать hostname, роль пользователя, размер скидки, путь к файлу или название функции — такие решения остаются в коде продукта.
Права пользователя важнее текста модели
Фраза «я администратор» в диалоге не является полномочием. Контекст сессии должен приходить из вашей системы аутентификации, а не из messages. Если пользователь может читать только свои заказы, обработчик добавляет фильтр владельца самостоятельно и не принимает user_id от модели как источник истины. Аналогично, название организации, план подписки и среда deployment проверяются на сервере. Модель помогает интерпретировать намерение, но не принимает решения о доступе.
Для действий с последствиями применяйте подтверждение. Модель может подготовить черновик или показать, что будет сделано, а пользователь подтверждает операцию через обычный интерфейс. Обработчик получает одноразовый идентификатор подтверждения и проверяет его срок, владельца и содержимое. Это снижает риск того, что двусмысленная фраза, prompt injection из подключённого документа или ошибка модели превратятся в необратимое действие.
Обрабатывайте ошибки как данные, а не как текст для модели
Инструмент может вернуть тайм-аут, 404, 429 или отказ доступа. Не передавайте модели полный stack trace, внутренние URL, SQL-текст, заголовки или секреты: она не сможет их безопасно исправить, а вы расширите поверхность утечки. Преобразуйте ошибку в короткий код и сообщение для пользователя: «задача временно недоступна», «объект не найден» или «доступ не подтверждён». Подробности оставляйте в защищённой системе наблюдаемости.
Повторять вызов инструмента автоматически можно только для безопасных idempotent операций и с ограниченной политикой. О том, как не превратить временный лимит в лавину запросов, читайте в материале об ошибке 429 и backoff. Если модель получила невалидные аргументы, лучше вернуть ей структурированную ошибку схемы и разрешить один уточняющий ход, чем бесконечно пытаться угадать значение.
Тестируйте весь контур, а не только JSON
Успешный ответ в демо не доказывает безопасность. Подготовьте набор разговоров, в котором есть нормальные запросы, неясные формулировки, запрещённые действия и попытки навязать модели новую инструкцию из текста документа. Проверьте, что tool call не выполняется без прав, что аргументы с дополнительными полями отклоняются и что пользователь видит честный статус. Отдельно измеряйте долю предложенных и реально выполненных вызовов, ошибки валидации, задержку инструмента и отмены.
Следите за стоимостью. Один вопрос пользователя может включить несколько шагов: ответ модели, вызов инструмента и финальное резюме. Устанавливайте ограничение на число последовательных вызовов, размер возвращаемого результата и бюджет токенов. Не отправляйте в модель всю таблицу или весь документ, если достаточно десяти подходящих строк. Практики контроля контекста и бюджетов собраны в статье о стоимости LLM API.
Соберите контролируемый AI workflow
RussiaAPI помогает подключать совместимые модели через единый API, а границы инструментов, права и проверка аргументов остаются в вашем приложении. Сначала проверьте каталог моделей и настройте отдельный ключ для сервиса.
Открыть консоль RussiaAPIFAQ
Выполняет ли модель функцию сама?
Нет. Она возвращает предложение вызова и аргументы. Ваш сервер проверяет их, применяет права текущего пользователя, выполняет разрешённый метод и передаёт модели безопасный результат.
Можно ли передавать в tool arguments пароль или API Key?
Нет. Секреты остаются в серверном хранилище. Аргументы от модели — недоверенный ввод; они не должны содержать ключи, пароли или права доступа и не должны напрямую идти в SQL, shell или внутренние URL.
Что делать, если модель не поддерживает tools?
Сверьте текущий каталог и документацию, затем выберите поддерживаемую модель и endpoint либо используйте простой сценарий без инструментов. Не имитируйте поддержку фиктивным ответом.