Серверная интеграция
Как подключить ChatGPT API к сайту в России через совместимый endpoint
У формы «Спросить помощника» на сайте есть две разные части. Первая — интерфейс: посетитель вводит вопрос и получает понятный статус. Вторая — серверный контур: он решает, кто может сделать запрос, что допустимо отправить модели, какой бюджет доступен и как не раскрыть ключ. Если соединить форму с внешним endpoint напрямую, красивый демо-вид быстро превращается в утечку секрета, неуправляемые расходы и непонятные ошибки. Надёжная интеграция начинается с собственного сервера.
Определите полезный сценарий сайта
Начните с конкретного действия пользователя. Для базы знаний это может быть поиск по опубликованным статьям, для SaaS — черновик ответа в поддержку, для внутреннего портала — краткое резюме уже разрешённого документа. Запишите, какие данные разрешено отправлять, какой ответ можно показывать без дополнительной проверки, сколько раз пользователь вправе повторить запрос и что считается безопасной неудачей. «Добавить чат на сайт» — слишком широкая задача; «сделать черновик в пределах 800 символов для авторизованного оператора» уже позволяет настроить контроль.
Не используйте модель как источник прав. Она может помочь сформулировать текст, но не должна сама определять роль пользователя, цену, скидку, доступ к файлу или возможность выполнить действие. Эти сведения приходят из вашей сессии и базы данных. Если чат связан с заказами или личными данными, сервер сам добавляет ограничение владельца и передаёт в модель лишь необходимый фрагмент. Так сообщение пользователя «я администратор» не становится привилегией.
Почему браузер не должен видеть API Key
Любой код, отправленный в браузер, доступен посетителю: в DevTools, исходниках, сетевых запросах, расширениях и сохранённых логах. Даже короткоживущий ключ нельзя считать безопасным, если он встроен в JavaScript или mobile-приложение. Кроме утечки вы теряете контроль: невозможно надёжно связать расход с вашей сессией, отфильтровать опасный вход, отключить злоупотребляющий сценарий или скрыть внутренние ошибки.
Правильный маршрут выглядит так: браузер отправляет авторизованный запрос вашему /api/assistant; сервер проверяет сессию, размер текста и лимит; затем сервер вызывает доступный RussiaAPI endpoint своим ключом; клиент получает только разрешённый результат. Ключ остаётся в менеджере секретов или переменной окружения процесса. Создавайте отдельные ключи по приложению и среде, чтобы ошибка тестового стенда не затрагивала production. О плановой замене секрета читайте в материале о ротации API Key.
Выберите модель только после проверки каталога
Не подставляйте в код название модели, увиденное в чужом примере. Сначала откройте актуальный каталог моделей и проверьте, что ваш ключ видит нужный вариант. Затем выполните один серверный тест и только после этого запускайте оценку на обезличенном наборе реальных запросов. У разных моделей и endpoint могут отличаться формат streaming, обработка инструментов, ограничение контекста, скорость и стоимость; знакомая структура запроса не отменяет эти различия.
Для сайта полезны простые критерии: понятен ли ответ без доработки, укладывается ли он в интерфейс, не повторяет ли секретные данные, как часто нужен ручной просмотр и сколько стоит успешно закрытый сценарий. Добавьте специальные примеры: пустой запрос, слишком длинный текст, попытка выдать инструкцию за системное правило и запрос, который требует отказа. Полная методика теста описана в статье как выбрать модель для API.
Минимальный серверный обработчик
Ниже приведён каркас Express для Node.js 18+. Он рассчитан на сервер, где RUSSIAAPI_API_KEY уже передан через защищённую переменную окружения. Замените MODEL_ID только на идентификатор из актуального каталога и сверяйтесь с документацией о параметрах endpoint. В примере нет настоящего ключа, нет клиентского доступа к секрету и есть ограничение длины входа и времени ожидания.
app.post('/api/assistant', requireSession, async (req, res) => {
const text = typeof req.body?.text === 'string' ? req.body.text.trim() : '';
if (!text || text.length > 2000) return res.status(400).json({ error: 'invalid_input' });
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 15000);
try {
const upstream = await fetch('https://russiaapi.com/v1/chat/completions', {
method: 'POST', signal: controller.signal,
headers: { 'content-type': 'application/json', Authorization: `Bearer ${process.env.RUSSIAAPI_API_KEY}` },
body: JSON.stringify({ model: process.env.MODEL_ID, messages: [{ role: 'user', content: text }] })
});
if (!upstream.ok) return res.status(502).json({ error: 'assistant_unavailable', status: upstream.status });
const data = await upstream.json();
return res.json({ answer: data.choices?.[0]?.message?.content ?? '' });
} catch { return res.status(504).json({ error: 'assistant_timeout' }); }
finally { clearTimeout(timer); }
});
Это минимальный пример, а не готовая политика production. Добавьте проверку схемы тела, лимит запросов на пользователя, ограничение бюджета, журнал с request ID и тесты для неуспешных ответов. Не возвращайте клиенту полный объект ошибки, внутренний URL или заголовки: они могут содержать служебные данные. Пользователь должен увидеть короткий честный статус, например «сервис временно недоступен», а подробности остаются в защищённой системе наблюдаемости.
Сделайте ошибки и повторы предсказуемыми
HTTP 400 говорит, что клиенту нужно исправить запрос; 401 и 403 требуют проверить конфигурацию собственного ключа, endpoint и права; 429 означает, что нужно уменьшить частоту; тайм-аут может быть временным, но не доказывает, что операция не дошла до сервиса. Поэтому не ставьте в браузере бесконечный цикл retry. Он только увеличивает расход и может показать пользователю несколько разных ответов на один клик.
Для безопасного read-only запроса сервер может выполнить ограниченный повтор с возрастающей паузой и jitter, если документация и ваш сценарий это допускают. Для действия с последствиями нужен idempotency key или другая защита от дублей. Про 429 и границы повторов см. подробное руководство, а для длительных задач, например видео, используйте task ID и честный статус вместо удержания HTTP-соединения; пример есть в статье об асинхронной генерации.
Защитите данные до отправки модели
Передача всего содержимого CRM или истории переписки «на всякий случай» повышает риск и стоимость. Определите минимальный контекст: несколько разрешённых полей, короткий фрагмент статьи, текущий язык интерфейса. Уберите пароли, API Key, токены сессии, банковские реквизиты и данные, которые не нужны для ответа. Если документ содержит персональные данные, примените правила вашей организации и применимого права до вызова модели.
Системная инструкция должна описывать задачу и формат, но не является единственной защитой. Текст пользователя, содержимое документа и даже результат инструмента — недоверенный вход. Валидируйте структуру на сервере, ограничивайте доступ к источникам данных и не позволяйте модели выбирать hostname, SQL, shell-команду или роль. Если нужны инструменты, внедряйте их через белый список и отдельные права; безопасный подход разобран в статье о function calling.
Измеряйте результат после запуска
После первого rollout отслеживайте число запросов, долю успешных ответов, p95 задержки, коды ошибок, отмены, расход и долю ответов, отправленных на ручную проверку. Не помещайте в метрики prompts, Authorization и личные данные. Для коммерческого сценария полезнее считать стоимость полезного результата, а не среднюю цену каждого вызова: повтор, длинный контекст и неудачный ответ тоже потребляют бюджет.
Запускайте новую конфигурацию небольшой долей трафика и держите простой rollback. Это означает сохранённую проверенную настройку, а не просьбу прислать другой ключ в чат. Если каталог, лимиты или требования изменятся, у вас останутся проверяемые данные о том, что именно работало и почему вы остановили rollout.
Подключите сайт через безопасный серверный маршрут
Откройте документацию RussiaAPI, создайте отдельный собственный ключ для серверного приложения и начните с малого обезличенного сценария. Каталог, лимиты и цена должны проверяться в текущей консоли перед запуском.
Открыть консоль RussiaAPIFAQ
Можно ли вызывать AI API прямо из браузера?
Не следует, если для вызова нужен секрет. Браузер раскрывает ключ посетителю и не даёт централизованно проверять сессии, ввод, лимиты и расход. Используйте свой серверный endpoint.
RussiaAPI — это официальный ChatGPT API?
Нет. Это независимый сторонний API gateway. Упоминание ChatGPT API описывает сценарий чат-интеграции и совместимый формат, но не официальный статус или одинаковые условия поставщика.
Что делать с 429 на сайте?
Не запускайте бесконечные повторы. Ограничьте частоту на сервере, покажите честный статус, используйте ограниченный backoff только для временных ошибок и проверьте лимиты в текущей консоли.