Однопроцессное серверное приложение на Python (stdlib, ThreadingHTTPServer): REST API + админка + чат-виджет. Хранилище — JSON-файлы (без СУБД), документы — SQLite с полнотекстовым индексом FTS5. Опционально подключается модель (PyTorch) файлом — без пересборки. Разворачивается в Docker одной командой.
┌────────────────────── САЙТ КЛИЕНТА ──────────────────────┐
│ [виджет widget.js] [лендинг / landing.html] │
└──────────┬───────────────────────────┬───────────────────┘
│ POST /api/chat │ POST /api/lead
▼ ▼
┌────────────────────────── app.py (один процесс) ──────────────────────────┐
│ HTTP (ThreadingHTTPServer) │
│ ├─ RAG: kb.json (словесный поиск) + kb.db (SQLite FTS5, документы) │
│ ├─ очередь генерации (батч до 8 / 50мс) → inference.py → модель (.pt) │
│ ├─ сценарий заявок (4 шага) → leads.json │
│ ├─ безопасность: фильтры, rate-limit, маскировка, security.log │
│ └─ бэкапы: auto_backup (1/сутки, ротация 7) │
└──────────┬──────────────────────────────────────────────────────────────┘
▼
data/ (JSON + kb.db) · models/ (model_300.pt + vocab.json)
Docker · volumes снаружи · HTTPS (nginx + Let's Encrypt)
app.py — сервер: API, RAG, заявки, безопасность, бэкапы inference.py — модель: ленивая загрузка, генерация, generate_batch vercel.html — админка (SPA, fetch к API, пароль, разделы) chat.html — публичный чат widget.js — виджет для сайта клиента (одна строка вставки) landing.html — лендинг (публичный) Dockerfile — python:3.11-slim + torch + pypdf docker-compose.yml — volumes data/ и models/ (снаружи контейнера) install.sh — автоустановка одной командой verify_client.sh — автотест пакета перед передачей клиенту reset_pw.py — сброс пароля админки
| Метод | Путь | Доступ | Назначение |
|---|---|---|---|
| POST | /api/chat | публичный | чат (rate-limit 10/мин/IP) |
| POST | /api/lead | публичный | заявка с лендинга |
| GET | /api/botinfo | публичный | имя и тон бота |
| GET | /api/auth/status|login|setup | публичный | пароль/токены |
| GET/POST | /api/kb, /api/dialogs, /api/leads, /api/fixes | токен | данные админки |
| GET/POST | /api/settings, /api/stats, /api/status | токен | настройки/статистика |
| GET/POST | /api/export, /api/import | токен | перенос базы одним файлом |
| POST | /api/upload | токен | файлы (txt/md/csv/json/pdf/docx), ≤100 МБ |
| GET | /widget.js, /chat, /landing | публичный | фронт |
Аутентификация: X-Auth-Token, пароль sha256(salt+pw), сравнение secrets.compare_digest.
kb.json — база знаний: [{id, q, a, date}]
dialogs.json — диалоги: [{id, q, bot, status, source, date, session}]
fixes.json — пары «вопрос → правильный ответ» (для дообучения)
leads.json — заявки: [{id, name, service, when, phone, status, date}]
settings.json — настройки (имя, правила, version)
auth.json — пароль (хеш+соль), токен
kb.db — документы: SQLite + FTS5 (чанки 3000, поиск bm25)
security.log — подозрительные попытки (IP, время, текст)
backups/ — авто-бэкап раз в сутки, ротация 7 дней
Записи атомарны (tmp + os.replace), права 600, threading.Lock.
esc())Сценарий из 4 шагов (имя → услуга → когда → телефон, валидация телефона). Сохранение в leads.json. Статусы: новая/в работе/закрыта. Отображаются в админке (раздел «Заявки»).
Вся статистика — в админке (раздел «Статистика»): диалоги за неделю, закрытые/неотвеченные, топ вопросов, заявки. Никаких внешних отправок.
./install.sh # Docker: образ + volumes + автозапуск MODEL_PATH=models/model_300.pt # подключение модели файлом (lazy-load) # железо: N305 (CPU ~15 ток/с) / NAG6 RTX 3060 / VPS с GPU # HTTPS: nginx reverse-proxy + Let's Encrypt (пример в nginx_neural.conf)
Одна модель (300M, GPU-инференс) — рекомендуемая конфигурация сервера клиента:
| CPU | RAM | GPU (VRAM) | Диск |
|---|---|---|---|
| 8 ядер (4 ядра минимум) | 16 ГБ (8 ГБ минимум) | 8 ГБ VRAM — RTX 3060 (минимум 6 ГБ — RTX 2060) | 40 ГБ NVMe |
Расчёт: модель ~1.2 ГБ (fp32) + PyTorch/батчинг 8 (~2-3 ГБ) + запас = 8 ГБ VRAM. CPU 8 ядер — поиск по базе (FTS5), HTTP/API, препроцессинг. RAM 16 ГБ — сервер + модель при загрузке + документы SQLite. Диск 40 ГБ NVMe — ОС + пакет + модель + данные (NVMe — быстрая загрузка чекпоинта 4 ГБ).
Нагрузка: 300M на GPU с батчингом — 30-50+ одновременных диалогов; 1000+ посетителей/день (пик 50-100) — RTX 3060 8GB достаточно, для пиков 4070+.
Модель обучалась на окнах 256 токенов и при генерации видит последние 256 токенов промпта. Память устроена НЕ внутри окна, а снаружи — на сервере:
Сколько можно общаться по символам (1 токен ≈ 2-4 символа русского текста, в среднем ~3):
| Что | Токенов | Символов (примерно) |
|---|---|---|
| Окно генерации (весь промпт) | 256 | ~750 |
| Промпт целиком: правила + пары + вопрос | 150-250 | ~500-750 |
| Вопрос клиента (комфортно) | до 100 | до ~300 символов |
| Ответ модели (max_new 120) | до 120 | ~350-400 (5-8 предложений) |
| Пара из базы знаний | ~50-100 | ~150-300 |
Практические рекомендации: вопрос клиента до ~300 символов отвечается грамотно (больше — RAG-поиск всё равно находит суть по ключевым словам, а сам вопрос не теряется); ответ — до ~400 символов. История диалога: 1-2 короткие реплики помещаются в окно; длинная память и большой контекст (16K+) — на моделях следующего поколения.
© Нейронка · техническое описание · пакет v0.5.0