Чат-бот для сайта на нейросети: архитектура, код со стримингом и цена

Собираем чат-бот для сайта: ключ только на сервере, бэкенд на FastAPI со стримингом, дешёвая модель, расчёт стоимости и лимиты против злоупотреблений.

6 мин · · разработка · API-ключи

Чат-бот для сайта на нейросети собирается за вечер, но одна архитектурная ошибка — ключ API в коде страницы — может обнулить баланс за ночь. Ниже — правильная схема, рабочий бэкенд на FastAPI со стримингом и простой виджет, выбор недорогой модели, расчёт стоимости 10 000 диалогов и настройки, которые ограничат расход, если ботом начнут злоупотреблять.

Архитектура: фронт → бэкенд → API

bash
Браузер (виджет)  →  ваш бэкенд /api/chat  →  https://api.zukko.pro/v1
     без ключа          ключ fetch_..., лимиты,          модель
                        системный промпт

Ключ fetch_... — только на сервере. Всё, что попало в JavaScript страницы, может прочитать любой посетитель через инструменты разработчика. С вашим ключом он сможет отправлять запросы к любым моделям за ваш счёт. Поэтому браузер общается только с вашим бэкендом, а тот — с API.

Что делает бэкенд:

  • хранит ключ в переменной окружения;
  • добавляет системный промпт — пользователь его не видит и не может заменить;
  • обрезает историю диалога и длину сообщений;
  • ограничивает частоту запросов с одного IP;
  • скрывает от посетителя детали ошибок API.

Выбор модели

Для бота на сайте обычно хватает недорогой модели: вопросы короткие, ответы — по базе знаний из системного промпта. Цены на 7 октября 2026, $ за 1M токенов:

МодельidВход / выходИндекс силыКонтекст
DeepSeek V4.1 Flashdeepseek-v4.1-flash0.013 / 0.038391M
Qwen 3.8 Flashqwen3.8-flash0.038 / 0.075401M
GLM 5.3 Flashglm-5.3-flash0.04 / 0.0442128K
GPT-6 Lunagpt-6-luna0.04 / 0.21381M
Gemini 3.8 Flashgemini-3.8-flash0.063 / 0.288411M
GPT-6.1 Solgpt-6.1-sol0.27 / 1.32521M

Индекс силы — Intelligence Index от Artificial Analysis из каталога Zukko. Актуальный список и цены — GET https://api.zukko.pro/v1/models или страница «Модели» в кабинете.

Как выбрать: соберите 30–50 реальных вопросов посетителей, прогоните их через 2–3 дешёвые модели с вашим системным промптом и оцените ответы. Если ни одна не справляется, попробуйте GPT-6.1 Sol. В коде модель — одна строка, её легко поменять. Подробнее о выборе — в статье как выбрать модель для чат-бота.

Чат-бот для сайта на нейросети: код бэкенда

Python 3.10+, FastAPI и официальный OpenAI SDK. Установка: pip install fastapi uvicorn openai. Файл main.py:

bash
import os
import time
from collections import defaultdict, deque
from typing import Literal

from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import FileResponse, StreamingResponse
from openai import APIStatusError, AsyncOpenAI
from pydantic import BaseModel, Field

client = AsyncOpenAI(
    base_url="https://api.zukko.pro/v1",
    api_key=os.environ["ZUKKO_API_KEY"],  # ключ fetch_... только на сервере
)

Ключевые моменты:

  • Роль system клиент прислать не может — модель Message допускает только user и assistant.
  • Проверка if chunk.choices обязательна: последний чанк стрима приходит с usage и пустым choices.
  • max_tokens=400 ограничивает длину и стоимость одного ответа.
  • Счётчик запросов хранится в памяти — для одного процесса этого достаточно. При нескольких процессах или серверах вынесите его в Redis. Если перед приложением стоит прокси, берите IP клиента из заголовка, который выставляет ваш прокси, а не request.client.host.

Запуск: ZUKKO_API_KEY=fetch_ваш_ключ uvicorn main:app. Справка по стримингу — в статье о stream=true.

Виджет на странице

Минимальный index.html: история хранится в браузере и отправляется целиком, бэкенд берёт последние 10 сообщений.

bash
<pre id="log"></pre>
<form id="form">
  <input id="text" maxlength="1000" autocomplete="off" placeholder="Ваш вопрос">
  <button>Отправить</button>
</form>
<script>
const history = [];
const log = document.getElementById("log");
const form = document.getElementById("form");
const input = document.getElementById("text");

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  const text = input.value.trim();

Если между бэкендом и браузером стоит обратный прокси, отключите для маршрута /api/chat буферизацию ответа — иначе текст придёт целиком в конце, а не по частям.

Сколько стоят 10 000 диалогов

Допущения: системный промпт с базой знаний — 1 500 токенов; в диалоге 4 вопроса по 50 токенов и 4 ответа по 150. Модель получает всю историю заново, поэтому вход n-го запроса = 1 500 + 200 × (n − 1) + 50.

  • Вход за диалог: 1 550 + 1 750 + 1 950 + 2 150 = 7 400 токенов.
  • Выход за диалог: 4 × 150 = 600 токенов.
  • 10 000 диалогов: 74M входа и 6M выхода.

Формула: 74 × цена входа + 6 × цена выхода (цены за 1M токенов).

МодельРасчёт10 000 диалогов
deepseek-v4.1-flash74 × 0.013 + 6 × 0.038$1.19
glm-5.3-flash74 × 0.04 + 6 × 0.04$3.20
qwen3.8-flash74 × 0.038 + 6 × 0.075$3.26
gpt-6-luna74 × 0.04 + 6 × 0.21$4.22
gemini-3.8-flash74 × 0.063 + 6 × 0.288$6.39
gpt-6.1-sol74 × 0.27 + 6 × 1.32$27.90

Цены на 7 октября 2026, расчёт без учёта кэша. Системный промпт повторяется в каждом запросе, поэтому у моделей, где поставщик сообщает о чтении кэша, часть входа может обойтись дешевле — например, у Gemini 3.8 Flash чтение кэша стоит 0.013 против 0.063 за вход. Запись кэша у этих моделей не списывается. Итог — пример расчёта: подставьте свои размеры промпта и диалогов.

Защита от злоупотреблений

Открытый чат на сайте — это бесплатный доступ к модели для всех, включая ботов. Ограничения ставьте на двух уровнях.

На уровне ключа Zukko (в кабинете):

  • отдельный ключ только для бота;
  • дневной и месячный лимит в долларах — при исчерпании API вернёт 429 key_daily_limit_reached или key_monthly_limit_reached, остальные ключи аккаунта продолжат работать;
  • список разрешённых моделей — только модель бота, запрос к другой получит 403 model_not_allowed_for_key.

Лимиты мягкие: последний пропущенный запрос может немного превысить потолок. Подробнее — в документации по лимитам ключа.

На уровне бэкенда:

  • лимит сообщений на IP или на сессию;
  • ограничение длины сообщения и числа сообщений истории;
  • max_tokens для ответа;
  • проверка от ботов на форме, если начался поток автоматических запросов;
  • журнал расходов: в обычных (не потоковых) ответах шлюз присылает заголовок X-Zukko-Cost-Micros, у потоковых стоимость смотрите в GET /v1/usage или в кабинете.

Если ключ всё же утёк, сразу отзовите его в кабинете и только потом выпускайте новый. Больше о хранении ключей — в статье о безопасности API-ключей.

Чтобы собрать бота по этой схеме, создайте в кабинете отдельный ключ с небольшим дневным лимитом и подставьте его в ZUKKO_API_KEY на сервере.

Частые вопросы

Можно ли вызывать API прямо из JavaScript на странице?

Нет. Ключ из кода страницы может прочитать любой посетитель. Запросы к API должны идти только с вашего сервера.

Сколько стоит чат-бот для сайта в месяц?

Зависит от числа диалогов и модели. По нашему расчёту 10 000 диалогов по 4 вопроса стоят от $1.19 на DeepSeek V4.1 Flash до $27.90 на GPT-6.1 Sol по ценам на 7 октября 2026.

Что будет, если закончится лимит ключа?

API вернёт 429, бэкенд из примера покажет посетителю «Чат временно недоступен». Дневной лимит обнуляется в 00:00 UTC, месячный — в начале месяца по UTC.

Можно ли сделать то же на Node.js?

Да. Схема та же: бэкенд на Express или другом фреймворке, официальный OpenAI SDK для Node с baseURL: "https://api.zukko.pro/v1", ключ в переменной окружения и стриминг ответа клиенту.

zukko

Платите в 25×
меньше

за Claude Code & ChatGPT

Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.