ChatGPT API: как подключить модель к сайту, боту или приложению

Пользователь вводит текст на сайте, нажимает кнопку и получает ответ модели. Со стороны это похоже на один запрос из интерфейса. Но безопасное подключение требует промежуточного слоя: браузер не должен знать API-ключ, а модель не должна самостоятельно решать, какие данные принимать и что возвращать пользователю.

Сначала уточним название. Фраза «ChatGPT API» распространена в поиске. В официальной документации разработческий интерфейс называется OpenAI API. ChatGPT является готовым пользовательским продуктом, а через OpenAI API разработчик вызывает модели из собственного серверного кода. Дальше будем использовать официальное название.

Начните с одной функции, а не с «умного ассистента»

До создания ключа опишите одно действие продукта. Например: пользователь вставляет заметку, а приложение возвращает краткое резюме из трёх пунктов. У такой функции есть наблюдаемый вход и выход. Её можно проверить на пустом тексте, обычной заметке, слишком длинном вводе и временной недоступности внешнего сервиса.

Формулировка «добавить ИИ в продукт» слишком широка. Она не отвечает на вопросы:

• откуда берётся исходный текст;

• можно ли отправлять его внешнему сервису;

• какой формат ответа нужен интерфейсу;

• что произойдёт при ошибке или долгом ожидании;

• должен ли результат сохраняться;

• может ли ответ сразу влиять на деньги, права или пользовательские данные.

Для первой версии лучше выбрать вспомогательное действие, где человек видит результат до его дальнейшего использования. Это не гарантирует точность модели, но ограничивает последствия ошибки.

Как проходит запрос

Минимальная архитектура выглядит так:

клиент → ваш сервер → OpenAI API → ваш сервер → клиент

Клиентом может быть веб-страница, мобильное приложение или бот. Он отправляет на ваш сервер текст и необходимые параметры функции. Сервер проверяет вход, добавляет инструкцию для модели, вызывает API и получает ответ. Затем он извлекает нужную часть результата, при необходимости проверяет её и возвращает клиенту понятный объект или ошибку.

Этот слой нужен не для красоты схемы. API-ключ даёт доступ к вашему проекту OpenAI и должен оставаться в доверенной среде. Официальные рекомендации прямо запрещают встраивать ключ в браузерное или мобильное приложение: пользователь может извлечь его из собранного кода или сетевого запроса. Переменная с названием вроде VITE_OPENAI_API_KEY не становится секретной, если её значение попадает во фронтенд.

Серверная граница также позволяет централизованно:

• ограничить длину и тип входа;

• выбрать инструкцию и модель для конкретной функции;

• установить тайм-аут и обработать ошибку;

• контролировать частоту запросов пользователя;

• записать технический идентификатор запроса без публикации ключа;

• решить, какие данные сохранять, а какие удалять.

Сама модель не знает правил вашего продукта. Эти правила живут до и после вызова: в проверке входа, серверной инструкции, ограничениях доступных действий и обработке результата.

Поэтому первый технический результат: не чат с десятком режимов, а один серверный метод. Он принимает один заранее определённый вход, делает один вызов OpenAI API и возвращает один понятный результат. Следующий раздел покажет минимальную иллюстрацию такого вызова на JavaScript.

Минимальный вызов из серверного JavaScript

Ниже не готовый сервер для копирования в production, а иллюстрация основного вызова по текущему OpenAI Developer Quickstart. Она показывает официальный SDK, переменные окружения, Responses API и чтение текстового результата. Маршрут HTTP, авторизация пользователей, тайм-ауты и журналирование зависят от вашего фреймворка и добавляются вокруг этой функции.

1. Создайте проектный ключ

Создайте API key в панели OpenAI Platform. Для локальной разработки сохраните его в переменной окружения OPENAI_API_KEY. Официальный SDK читает её автоматически, поэтому ключ не нужно передавать в конструктор и тем более записывать строкой в исходный файл.

Идентификатор модели тоже удобно вынести в окружение, например в OPENAI_MODEL. Это уже часть нашей серверной обвязки, а не требование SDK. Такой подход позволяет выбирать модель по актуальному каталогу и менять конфигурацию без редактирования функции. Не копируйте название модели из старой статьи: доступность и свойства моделей меняются.

Пример локальных переменных:

Команды по порядку: export OPENAI_API_KEY="ваш_ключ" и export OPENAI_MODEL="актуальный_model_id".

Не добавляйте реальные значения в Git. Для размещённого приложения задайте их в секретах или переменных окружения выбранной платформы.

2. Установите официальный SDK

Для серверного JavaScript в Node.js, Deno или Bun Quickstart предлагает официальный пакет:

Команда для этого шага: npm install openai.

Установка пакета и создание клиента относятся к официальному примеру. Проверка аргументов и выбор инструкции ниже относятся к конкретной функции нашего условного продукта.

3. Сделайте одну функцию вызова

import OpenAI from "openai"; const client = new OpenAI(); const model = process.env.OPENAI_MODEL; export async function summarizeNote(text) { if (typeof text !== "string" || text.trim().length === 0) { throw new Error("EMPTY_TEXT"); } if (!model) { throw new Error("OPENAI_MODEL_NOT_SET"); } const response = await client.responses.create({ model, instructions: "Сожми заметку до трех коротких пунктов. Не добавляй факты, которых нет во входном тексте.", input: text, }); return response.output_text; }

new OpenAI() берёт ключ из OPENAI_API_KEY. Метод client.responses.create() отправляет запрос в Responses API. В instructions лежит постоянная инструкция функции, а в input находится пользовательская заметка. response.output_text собирает текстовые части ответа в удобную строку.

Код намеренно не фиксирует конкретную модель. Приложение получит её идентификатор из окружения, а вы выберете его по текущим требованиям к качеству, задержке и расходам. Для production этого недостаточно: нужно также ограничить длину text, а не проверять только пустое значение.

Мы не запускали этот фрагмент в вашем проекте и не называем его проверенным сервером. Он опирается на текущий интерфейс официального SDK, но требует адаптации к версии Node.js, модульной системе и фреймворку вашего приложения.

4. Оберните вызов маршрутом продукта

HTTP-маршрут должен сделать четыре вещи до возврата ответа:

1. Проверить, что пользователь имеет право вызвать функцию.

2. Принять только ожидаемое поле text и ограничить его размер.

3. Вызвать summarizeNote() на сервере.

4. Вернуть клиенту понятный статус и поле с резюме, не раскрывая ключ и внутренний текст ошибки.

Не отправляйте в браузер полный объект ответа «на всякий случай». Сформируйте собственный контракт, например { summary: "..." }. Тогда интерфейс зависит от функции продукта, а не от всех полей внешнего API.

Ответ модели также нужно считать внешним вводом. Проверьте, что output_text существует и укладывается в формат, который способен показать интерфейс. Инструкция про три пункта задаёт желаемое поведение, но не заменяет проверку результата. Если продукту нужен строгий объект с обязательными полями, для него потребуется отдельный контракт структурированного вывода, а не разбор текста по переносам строк.

Минимальная приёмка включает три ожидаемых поведения: пустой текст отклоняется до внешнего запроса, обычный текст возвращает строку резюме, сбой API превращается в контролируемую ошибку интерфейса. Это план проверки для вашей реализации, а не заявленные результаты нашего запуска.

Что добавить перед публикацией

Один успешный вызов доказывает только связь с API. Готовая функция продукта должна отдельно решить состояние, доступ к инструментам, расходы, работу с данными и диагностику. Эти задачи не появляются автоматически после установки SDK.

Состояние разговора

Обычный запрос генерации сам по себе не хранит всю историю вашего интерфейса. Для многошагового диалога состояние нужно передавать и хранить осознанно. OpenAI API позволяет управлять историей вручную, связывать ответы через идентификатор предыдущего ответа или использовать отдельные объекты разговора.

Для функции резюмирования память вообще не нужна: каждый текст можно обрабатывать независимо. Не превращайте однократное действие в бесконечный чат. Если история всё же нужна, определите срок хранения, владельца разговора, способ удаления и максимальный объём контекста. Иначе расходы и задержка будут расти вместе с накопленным текстом.

Инструменты и действия

Модель не получает доступ к базе, интернету, почте или календарю просто потому, что вы описали это в инструкции. Такие возможности подключаются как отдельные инструменты. Сервер определяет доступные действия, проверяет аргументы и решает, выполнять ли вызов.

Чем опаснее действие, тем меньше автономии должно быть у модели. Черновик письма можно показать человеку. Списание денег, удаление данных или изменение прав требует обычной серверной авторизации и явного подтверждения. Текст модели не должен обходить правила продукта.

Данные и модерация

До отправки пользовательского текста определите, содержит ли он персональные, медицинские, финансовые или иные чувствительные данные и есть ли у продукта основание передавать их внешнему провайдеру. Не записывайте полный ввод и вывод в каждый лог только потому, что это удобно при отладке.

Согласно текущей документации OpenAI, данные API не используются для обучения моделей, если клиент явно не согласился делиться ими. Это не означает отсутствия хранения: по умолчанию для API действуют журналы abuse monitoring, которые могут включать содержимое запросов и ответов и храниться до 30 дней. У отдельных функций и одобренных режимов хранения свои условия, поэтому проверяйте таблицу Data controls применительно к используемому endpoint.

Если продукт принимает открытый пользовательский ввод или показывает сгенерированный контент другим людям, задайте собственную политику допустимого содержания. OpenAI предоставляет moderation-модели для проверки текста и изображений, но результат модерации нужно связать с действиями вашего приложения: отклонить запрос, отправить на проверку или ограничить аккаунт. Наличие endpoint не заменяет продуктовую политику.

Ошибки, лимиты и расходы

Интерфейс должен различать хотя бы неверный ввод, отсутствие доступа, превышение лимита, временный сбой API и внутреннюю ошибку вашего сервера. Пользователю не нужен сырой stack trace. Команде нужны категория ошибки, время, версия функции и технический идентификатор запроса.

OpenAI возвращает x-request-id для диагностики и заголовки x-ratelimit-* с информацией о лимитах. Официальная документация рекомендует журналировать request ID в production. Не добавляйте туда API-ключ или полный чувствительный ввод. Для тайм-аутов и сетевых сбоев задайте ограниченное число повторов и не допускайте бесконечного цикла запросов.

Расходы зависят от выбранной модели, объёма входа и выхода, инструментов и числа вызовов. Поэтому вместо числа из статьи установите свой предел: максимальная длина ввода, число запросов на пользователя, бюджет проекта и сигнал при необычном росте. Перед запуском сверяйте актуальные цены и лимиты в OpenAI Platform.

Где учиться собирать функцию целиком

API-вызов редко живёт отдельно: нужны интерфейс, сервер, Git, логи, база, деплой и защита. В программе курса «Вайбкодинг на максималках» эти части идут последовательно, а отдельный модуль посвящён проекту с нейросетью и устройству ИИ. Такой маршрут подходит, если задача не просто получить ответ в терминале, а встроить функцию в работающий продукт и понимать, где проверять ошибку.

Чек-лист первой версии

Функцию можно готовить к ограниченному запуску, когда:

• ключ хранится только на сервере и может быть заменён;

• вход проверяется до внешнего запроса;

• модель и инструкция относятся к одной понятной задаче;

• ответ проверяется перед показом или действием;

• ошибки не раскрывают секреты и имеют диагностический ID;

• определены лимиты пользователя и бюджета;

• правила хранения и удаления данных записаны;

• опасные действия требуют серверной проверки и подтверждения;

• есть набор входов для повторной проверки после смены модели или инструкции.

Начните с одного текста и одного результата. Когда этот путь устойчив, добавляйте память, файлы или инструменты по одному, каждый раз обновляя критерии проверки. Ценность интеграции видна не по сложности промпта, а по тому, может ли пользователь получить нужный результат, а команда может объяснить ошибку, ограничить расход и безопасно изменить функцию.