Перейти к основному содержанию

Личный AI-чат: от Telegram-бота до полноценного веб-интерфейса

Введение

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

Я прошёл путь от Telegram-бота до полноценного веб-интерфейса на собственном сервере. В этой статье расскажу, какие варианты рассматривал, с какими проблемами столкнулся и почему остановился на Open-WebUI.

Требования

Ключевые критерии выбора:

  • Доступ к OpenRouter — единый API для 200+ моделей (Claude, GPT, Gemini, DeepSeek, Qwen). Не хочу привязываться к одному провайдеру.
  • Self-hosted — данные остаются на моём сервере, нет подписок и лимитов кроме API.
  • Минимум зависимостей — чем меньше контейнеров и баз данных, тем проще эксплуатация.
  • Доступ с мобильных — Telegran, PWA или адаптивный веб-интерфейс.
  • Простой деплой — Podman Quadlet, rootless, один-два контейнера.

Какие решения рассматривал

NullClaw

Автономный AI-agent runtime на Zig1. Один статический бинарник в 678 КБ, ~1 МБ RAM, старт за 2 мс. Поддерживает 50+ AI-провайдеров (включая OpenRouter, Anthropic, OpenAI, Ollama) и 19 каналов связи: CLI, Telegram, Discord, Signal, Slack, Matrix, WhatsApp, IRC, email. Модульная архитектура на vtable-интерфейсах — провайдеры, каналы, инструменты и memory-движки подключаются как плагины. Встроенный sandbox (Landlock, Firejail) для безопасного выполнения команд.

Плюсы: минимальное потребление ресурсов, работает на $5 ARM-платах, 5300+ тестов, один бинарник без зависимостей.

Минусы: нет собственного веб-интерфейса (нужен NullHub для дашборда), ориентирован на автономных агентов — для простого чата избыточно по концепции и недостаточно по UI.

OpenClaw

Self-hosted AI-ассистент на TypeScript2 с 334K звёздами на GitHub. Gateway-архитектура: центральный WebSocket-шлюз нормализует протоколы 20+ мессенджеров (WhatsApp, Telegram, Slack, Discord, Signal, iMessage, Teams, Matrix) в единый формат и маршрутизирует к AI-агентам. Поддерживает голосовое управление, браузерную автоматизацию, работу с файлами, cron-задачи. Есть веб-UI, нативные приложения для macOS и мобильных, экосистема плагинов через ClawHub.

Плюсы: огромное сообщество, мультиплатформенность (одновременно общаешься через любой мессенджер), actionable AI (не только чат — управление почтой, календарём, автоматизация).

Минусы: требует Node.js 24+, тяжелее по ресурсам. Для задачи “простой веб-чат с OpenRouter” — overkill: Gateway-архитектура с 20+ мессенджерами не нужна, если хочешь только веб-интерфейс.

Nanobot

Telegram-бот с AI через OpenRouter. Удобен тем, что Telegram уже установлен на всех устройствах — нулевой барьер входа.

Плюсы: мгновенный доступ из Telegram, не нужен отдельный интерфейс.

Минусы: Telegram как платформа для AI-чата оказался неудобен по нескольким причинам. Во-первых, один чат — один поток: все разговоры на разные темы сливаются в единую ленту, и найти нужную информацию через неделю практически невозможно. Во-вторых, ограничения Telegram по форматированию — markdown рендерится не полностью, длинные ответы обрезаются, блоки кода отображаются плохо. В-третьих, нет удобного переключения моделей на лету. Наконец, после блокировки Telegram Bot API пришлось настраивать proxy для бота, что добавило ещё один компонент в инфраструктуру — лишний overhead ради неидеального интерфейса.

LibreChat

Мощная мультипровайдерная платформа3: 30+ LLM-провайдеров, AI Agents, MCP, Code Interpreter, OIDC/2FA. React + Node.js.

Плюсы: энтерпрайз-фичи (2FA, модерация, агенты), MCP-интеграция.

Минусы: MongoDB обязательна, MeiliSearch для поиска, Redis для масштабирования — три дополнительные зависимости. Для single-user сильный overkill. Сообщество в 3.7 раза меньше, чем у Open-WebUI (34.9K vs 126.8K звёзд).

Dify

LLMOps-платформа4 с визуальным конструктором workflow. Это не чат-интерфейс, а среда разработки AI-приложений.

Плюсы: drag-and-drop workflow, 50+ встроенных инструментов, мониторинг.

Минусы: 11 контейнеров в деплое (api, worker, web, db, redis, qdrant, sandbox, nginx…), минимум 4 CPU/16 GB RAM для production. Совершенно другая категория — для multi-step AI-пайплайнов, не для простого чата.

LobeChat

Современный AI-чат5 с агентами и маркетплейсом. Next.js, красивый UI, поддержка 13+ провайдеров.

Плюсы: отличный дизайн, система агентов с маркетплейсом, CRDT-синхронизация между устройствами.

Минусы: PostgreSQL 14+ обязателен для серверной версии, плюс Redis — итого 7 GB RAM. Без серверной версии данные хранятся только в IndexedDB браузера. Менее зрелый проект, чем Open-WebUI.

Open-WebUI

Чат-интерфейс6 для Ollama и облачных провайдеров. Python backend, Svelte frontend, SQLite.

Плюсы: один контейнер, SQLite из коробки, 126.8K звёзд на GitHub, PWA, knowledge base, memory, web search, Tools/Functions из маркетплейса.

Минусы: Python backend потребляет ~1-2 GB RAM — больше, чем у Go/Zig-альтернатив.

Почему остановился на Open-WebUI

Выбор определился пересечением требований:

КритерийNullClawOpenClawNanobotLibreChatDifyLobeChatOpen-WebUI
Веб-интерфейс-+-++++
OpenRouter+++++++
SQLite / без внешней БД+++---+
1 контейнер+-+---+
История диалогов-++++++
Переключение моделей++-++++
PWA-----++
OIDC-+-++++
Code Interpreter---++-+
Минимум ресурсов+-+---+

Open-WebUI — единственное решение, которое закрывает все требования при минимальной сложности деплоя. Один контейнер, SQLite, никаких внешних зависимостей.

Деплой в Podman Quadlet свёлся к одному .container файлу и паре переменных окружения. Сервис доступен только через Tailscale — публикации в интернет не нужно.

Установка и настройка

Quadlet-файл контейнера

Open-WebUI запускается одним контейнером через Podman Quadlet. Файл open-webui.container:

[Unit]
Description=Open-WebUI AI chat interface
After=network-online.target

[Container]
ContainerName=open-webui
Image=ghcr.io/open-webui/open-webui:main
Volume=%h/volumes/open-webui:/app/backend/data:Z
EnvironmentFile=%h/.config/containers/systemd/open-webui/open-webui.env
EnvironmentFile=%h/volumes/open-webui/.env
Network=caddy-private.network
AutoUpdate=registry
HealthCmd=curl -fsS http://127.0.0.1:8080/health
HealthInterval=30s
HealthTimeout=5s
HealthRetries=3

[Service]
Restart=always

[Install]
WantedBy=default.target

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

  • Один volume — ~/volumes/open-webui хранит SQLite-базу, uploads и кэш.
  • Два EnvironmentFile — первый с настройками (git-tracked), второй с секретами (только на сервере).
  • Network — caddy-private.network подключает контейнер к сети приватного Caddy за Tailscale.
  • AutoUpdate=registry — автоматическое обновление образа через podman auto-update.
  • HealthCmd — Podman проверяет /health каждые 30 секунд, рестартует при 3 неудачах.

Переменные окружения

Конфигурация разделена на два файла. Основной open-webui.env (не содержит секретов):

# Провайдеры
ENABLE_OPENAI_API=true
ENABLE_OLLAMA_API=true
OLLAMA_BASE_URL=https://ollama.com
OPENAI_API_BASE_URL=https://openrouter.ai/api/v1

# Регистрация (первый пользователь = admin)
ENABLE_SIGNUP=true

# Веб-поиск
ENABLE_RAG_WEB_SEARCH=true
RAG_WEB_SEARCH_ENGINE=tavily
RAG_WEB_SEARCH_RESULT_COUNT=5
BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL=true
BYPASS_WEB_SEARCH_WEB_LOADER=true
RAG_TOP_K=10

Секреты в отдельном .env файле (не в git):

OPENAI_API_KEY=sk-or-...          # OpenRouter API key
WEBUI_SECRET_KEY=...               # JWT secret (openssl rand -hex 32)
OLLAMA_API_KEY=...                 # Ollama Cloud key
RAG_WEB_SEARCH_API_KEY=...        # Tavily API key

BYPASS_WEB_SEARCH_EMBEDDING_AND_RETRIEVAL=true — важная настройка. Без неё Open-WebUI пропускает результаты поиска через embedding-модель и RAG-пайплайн, что требует отдельной embedding-модели. С bypass результаты поиска идут напрямую в контекст LLM — проще и быстрее.

Запуск

# Создать директорию для данных
mkdir -p ~/volumes/open-webui

# Создать файл секретов
cat > ~/volumes/open-webui/.env << 'EOF'
OPENAI_API_KEY=sk-or-ваш-ключ
WEBUI_SECRET_KEY=$(openssl rand -hex 32)
EOF

# Перезагрузить Quadlet и запустить
systemctl --user daemon-reload
systemctl --user start open-webui

После старта Open-WebUI доступен на порту 8080. Первый зарегистрированный пользователь автоматически получает роль admin.

Подключение провайдеров

OpenRouter — основной провайдер

OpenRouter7 предоставляет единый OpenAI-совместимый API для 200+ моделей. Подключение тривиально — переменные окружения:

OPENAI_API_BASE_URL=https://openrouter.ai/api/v1
OPENAI_API_KEY=sk-or-...

После старта контейнера все модели OpenRouter появляются в выпадающем списке. Можно переключаться между Claude, GPT, Gemini, DeepSeek в одном диалоге.

Ollama Cloud — бесплатные большие модели

Отдельно подключил Ollama Cloud8 — облачный сервис от Ollama, который позволяет запускать большие модели (DeepSeek V3.1 671B, Qwen3 235B, MiniMax) без локального GPU.

Бесплатный tier с лимитами по запросам (сброс каждые 5 часов и каждые 7 дней). Достаточно для личного использования — запустить DeepSeek V3.1 на 671B параметров бесплатно трудно переоценить.

Веб-поиск через SearXNG

Open-WebUI поддерживает интеграцию с поисковыми движками. У меня уже был развёрнут SearXNG9 — метапоисковик, агрегирующий результаты из Google, Bing, DuckDuckGo и десятков других источников.

Подключение: Admin → Settings → Web Search → SearXNG → URL.

Теперь модель может искать актуальную информацию в интернете прямо из чата. При этом используется мой собственный SearXNG-инстанс — никакие запросы не уходят в сторонние поисковые API.

Дополнительно подключил Tavily как альтернативный поисковый провайдер — он специализирован на AI-поиске и возвращает более структурированные результаты.

Создание агента

Одна из самых полезных возможностей Open-WebUI — создание кастомных агентов (моделей с предустановленными параметрами).

В разделе Workspace → Models можно создать агента с:

  • Фиксированной моделью — например, привязать к DeepSeek V3.2 для повседневных задач или Claude для кода.
  • System prompt — инструкции, определяющие поведение: язык ответов, стиль, область экспертизы.
  • Навыками (Tools) — подключить Web Search, Run Code, Adaptive Memory.
  • Knowledge base — привязать документы для RAG-поиска.

Это упрощает ежедневную работу: вместо того чтобы каждый раз выбирать модель, настраивать контекст и подключать инструменты — просто выбираешь нужного агента из списка. Один для написания кода, другой для исследований с веб-поиском, третий для анализа документов.

Масштабирование: PostgreSQL и Redis

SQLite достаточно для одного пользователя, но Open-WebUI поддерживает расширенную конфигурацию с PostgreSQL и Redis. Это имеет смысл, когда нужно:

  • Несколько воркеров — SQLite не поддерживает параллельную запись, при UVICORN_WORKERS > 1 нужна полноценная БД.
  • Векторный поиск (RAG) — pgvector позволяет хранить embeddings в PostgreSQL вместо встроенного ChromaDB.
  • WebSocket-синхронизация — Redis/Valkey как брокер для синхронизации состояния между воркерами.

Дополнительные контейнеры

PostgreSQL с расширением pgvector:

[Container]
ContainerName=open-webui-db
Image=docker.io/pgvector/pgvector:pg17
Volume=%h/volumes/open-webui-db/data:/var/lib/postgresql/data:Z
Volume=%h/.config/containers/systemd/configs/open-webui/init.sql:/docker-entrypoint-initdb.d/init.sql:ro,Z
EnvironmentFile=%h/.config/containers/systemd/open-webui/open-webui-db.env
EnvironmentFile=%h/volumes/open-webui/.env
UserNS=keep-id:uid=999,gid=999
Network=open-webui_db.network

Valkey (Redis-совместимый) для WebSocket:

[Container]
ContainerName=open-webui-redis
Image=docker.io/valkey/valkey:8-alpine
Exec=valkey-server --save 30 1 --loglevel warning
Volume=%h/volumes/open-webui-redis/data:/data:Z
UserNS=keep-id:uid=999,gid=1000
Network=open-webui_db.network

Init-скрипт для PostgreSQL (init.sql) — одна строка:

CREATE EXTENSION IF NOT EXISTS vector;

Изменения в конфигурации Open-WebUI

# Включить 3 воркера
UVICORN_WORKERS=3

# Переключить векторную БД на pgvector
VECTOR_DB=pgvector

# Connection pool
DATABASE_POOL_SIZE=5
DATABASE_POOL_MAX_OVERFLOW=5

# Redis для WebSocket
ENABLE_WEBSOCKET_SUPPORT=true
WEBSOCKET_MANAGER=redis

Строки подключения к PostgreSQL (DATABASE_URL) и Redis (WEBSOCKET_REDIS_URL) передаются через файл секретов.

Изолированная сеть

Контейнеры БД и Redis подключаются к отдельной сети open-webui_db.network, а Open-WebUI входит в обе сети — caddy-private (для HTTP-трафика) и open-webui_db (для доступа к БД). PostgreSQL и Redis не видны ни из какой другой сети.

Стоит ли усложнять?

На практике для single-user конфигурации SQLite хватает с запасом. Я пробовал миграцию на PostgreSQL + Redis + 3 воркера — работает, но прироста производительности при одном пользователе не заметно, а вот три дополнительных контейнера нужно обслуживать. В итоге вернулся на SQLite.

Миграция имеет смысл, если:

  • Подключаете нескольких пользователей и хотите параллельную обработку запросов.
  • Активно используете Knowledge Base с большими коллекциями документов (pgvector эффективнее ChromaDB).
  • Нужна надёжная репликация и бекапы БД (pg_dump vs копирование SQLite-файла).

Выводы

Путь от API-прослойки и Telegram-бота до полноценного веб-интерфейса занял несколько итераций. Главные уроки:

  1. Простота побеждает: один контейнер с SQLite надёжнее кластера из MongoDB + Redis + MeiliSearch. Для single-user нет смысла в энтерпрайз-архитектуре.

  2. OpenRouter решает проблему выбора провайдера: один API key — доступ ко всем моделям. Не нужно жонглировать ключами от OpenAI, Anthropic, Google.

  3. Ollama Cloud — неожиданно полезен: бесплатный доступ к моделям на 671B параметров. Подключается как второй OpenAI-совместимый endpoint.

  4. Кастомные агенты экономят время: настроить модель + system prompt + инструменты один раз, а потом просто выбирать из списка — это реально удобнее, чем каждый раз конфигурировать с нуля.

  5. Self-hosted AI-чат в 2026 году — это один контейнер: не нужен кластер Kubernetes или десяток Docker-контейнеров. Open-WebUI + SQLite + Podman Quadlet — и у вас полноценный AI-интерфейс за VPN.

Источники


  1. NullClaw — AI-agent runtime на Zig, 6.7K звёзд ↩︎

  2. OpenClaw — self-hosted AI-ассистент на TypeScript, 334K звёзд ↩︎

  3. LibreChat — мультипровайдерный AI-чат, 34.9K звёзд ↩︎

  4. Dify — LLMOps-платформа ↩︎

  5. LobeChat — AI-чат с агентами ↩︎

  6. Open-WebUI — AI-чат интерфейс, 126.8K звёзд ↩︎

  7. OpenRouter — единый API для 200+ LLM ↩︎

  8. Ollama Cloud — облачные модели ↩︎

  9. SearXNG — метапоисковик с открытым кодом ↩︎