Навигация: ← Теория | README | Установка →
ПОЛЬЗОВАТЕЛЬ
│
│ браузер / мобильный
▼
┌─────────────────┐
│ OPEN WEBUI │ ← Интерфейс (порт 3000)
│ (React + API) │ как ChatGPT, локально
└────────┬────────┘
│ HTTP POST /chat
▼
┌─────────────────┐
│ AI ROUTER │ ← Мозг оркестрации (порт 8000)
│ (FastAPI) │ выбирает модель, добавляет
│ │ системный промпт, память
└──┬──────────┬───┘
│ │
┌───────┘ └──────────┐
▼ ▼
┌────────────────┐ ┌─────────────────┐
│ OLLAMA │ │ CHROMADB │
│ (порт 11434) │ │ (порт 8001) │
│ │ │ │
│ Движок LLM │ │ Векторная БД │
│ llama.cpp │ │ Долгая память │
│ внутри │ │ RAG │
└───────┬────────┘ └─────────────────┘
│
│ загружает
▼
┌────────────────┐
│ МОДЕЛИ QWEN │
│ │
│ qwen2.5:14b │ ← основная
│ qwen2.5-coder │ ← для кода
│ nomic-embed │ ← для RAG
└────────────────┘
│
│ умножение на матрицы
▼
┌────────────────┐
│ ЖЕЛЕЗО (CPU) │
│ │
│ RAM: веса │ ← 7-40GB для модели
│ RAM: KV-cache │ ← 1-32GB для контекста
└────────────────┘
Что делает:
- Отображает чат (React)
- Управляет историей разговоров
- Позволяет загружать файлы (RAG)
- Управляет системными промптами
- Переключает модели
Что НЕ делает:
- Не генерирует ответы (это Ollama)
- Не хранит долгую память (это ChromaDB)
- Не выбирает модель умно (это Router)
Связь: HTTP → Ollama API (напрямую или через Router)
Что делает:
- Принимает запрос от WebUI
- Определяет тип запроса (код/текст/анализ)
- Выбирает нужную модель
- Добавляет системный промпт
- Загружает долгую память из ChromaDB
- Отправляет в Ollama
- Возвращает ответ
Это главный "мозг" — здесь живёт логика поведения
Что делает:
- Загружает модели в RAM
- Управляет KV-cache
- Запускает llama.cpp (C++ движок)
- Отдаёт OpenAI-совместимый API
- Выгружает/загружает модели по запросу
API:
POST /api/chat ← диалог
POST /api/generate ← одиночный промпт
POST /api/embed ← получить embedding вектор
GET /api/tags ← список загруженных моделей
Что делает:
- Хранит векторные представления текстов
- Ищет похожие тексты по смыслу (не по ключевым словам)
- Обеспечивает RAG (Retrieval Augmented Generation)
Как используется:
1. Важное из разговора → embed → сохранить в ChromaDB
2. При новом вопросе → embed вопрос → найти похожее
3. Найденное → добавить в контекст → ответ с памятью
Пример:
Ты рассказал что работаешь с Drupal.
Через неделю: "добавь блок на сайт" →
ChromaDB находит "работает с Drupal" →
Router добавляет в контекст →
Модель отвечает про Drupal, не спрашивает CMS
qwen2.5:14b — основная умная модель
qwen2.5-coder:7b — специализирована на коде
qwen2.5:72b — для сложных задач (нужно 40GB+ RAM)
nomic-embed-text — только для embeddings, не для чата
маленькая (274MB), быстрая
Все модели:
- Скачиваются через Ollama
- Хранятся в ~/.ollama/models/
- Загружаются в RAM при первом запросе
- Выгружаются если нет обращений (настраивается)
1. Пользователь: "напиши функцию на python"
↓
2. Open WebUI отправляет:
POST http://router:8000/chat
{
"prompt": "напиши функцию на python",
"history": [...]
}
↓
3. Router.pick_model():
"python" → code keyword → qwen2.5-coder:7b
↓
4. Router.build_messages():
[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": "напиши функцию на python"}
]
↓
5. Router → Ollama:
POST http://ollama:11434/api/chat
{"model": "qwen2.5-coder:7b", "messages": [...]}
↓
6. Ollama загружает модель в RAM (если не загружена)
Прогоняет через 28 слоёв трансформера
Генерирует токены один за другим
Стримит ответ
↓
7. Router возвращает в WebUI:
{"response": "def sort_list...", "model_used": "qwen2.5-coder:7b"}
↓
8. Open WebUI отображает ответ
1. Пользователь: "как у нас называется главная таблица?"
↓
2. Router получает запрос
↓
3. Router.embed("как у нас называется главная таблица")
→ [0.234, -0.891, 0.445, ...] (вектор 768 чисел)
↓
4. ChromaDB.search(vector, top_k=3):
Ищет ближайшие по косинусному расстоянию
Находит: "главная таблица называется orders, создана 2026-01-15"
↓
5. Router добавляет в промпт:
"Из памяти: главная таблица называется orders"
+ исходный вопрос
↓
6. Qwen отвечает: "Главная таблица у вас называется orders"
(без поиска в интернете, из локальной памяти)
ИНТЕРФЕЙС
(Open WebUI)
│
│ Слой 1: HTTP/WebSocket
│ Протокол: REST API (OpenAI-совместимый)
│ Данные: JSON {messages, model, stream}
│
▼
РОУТЕР
(FastAPI)
│
│ Слой 2: Логика выбора модели
│ Что происходит:
│ - Анализ ключевых слов → pick_model()
│ - Загрузка системного промпта
│ - Добавление истории разговора
│
│ Слой 3: Работа с памятью
│ Что происходит:
│ - Embed запроса → nomic-embed-text
│ - Поиск в ChromaDB
│ - Инжекция в контекст
│
│ Слой 4: Формирование промпта
│ Что происходит:
│ - system prompt + memory + history + question
│ - Форматирование в messages[]
│
▼
OLLAMA
(HTTP сервер)
│
│ Слой 5: Управление моделями
│ Что происходит:
│ - Выбор файла модели (.gguf)
│ - Загрузка в RAM
│ - Управление KV-cache
│
│ Слой 6: llama.cpp runtime
│ Что происходит:
│ - Токенизация текста
│ - Загрузка весов из RAM
│ - Вычисления на CPU (AVX2/AVX512)
│ - KV-cache update
│ - Sampling следующего токена
│
▼
ЖЕЛЕЗО
(CPU + RAM)
│
│ Слой 7: Физика
│ Что происходит:
│ - RAM → CPU cache → регистры
│ - SIMD инструкции (AVX2)
│ - Матричное умножение FP16/INT4
│ - Результат обратно в RAM
│
▼
МАТРИЦА
(веса модели в RAM)
7GB для Qwen2.5-14B Q4
Сервис Порт Кто обращается
─────────────────────────────────────────────────────
Open WebUI 3000 Браузер пользователя
AI Router 8000 Open WebUI, прямые клиенты
Ollama 11434 Router, Open WebUI напрямую
ChromaDB 8001 Router
Внутренняя сеть Docker: ai-network
Все контейнеры видят друг друга по имени сервиса:
http://ollama:11434
http://chromadb:8001
http://router:8000
Хост:
http://host.docker.internal:11434 ← если Ollama на хосте
Ollama + Open WebUI
Время установки: 5 минут
Что получаем: чат с локальной моделью
Чего нет: умный роутер, долгая память, RAG с файлами
Когда достаточно:
- Личный ассистент для разовых задач
- Тестирование моделей
- Прототипирование
Ollama + Open WebUI + Router + ChromaDB
Время установки: 30 минут
Что получаем: полноценная система
Когда нужна:
- Постоянный ассистент
- Работа с документами (RAG)
- Нужна долгая память
- Разные модели для разных задач
+ Агент с инструментами (поиск, код, файлы)
+ Fine-tuning на своих данных
+ Несколько пользователей
+ Логирование и аналитика
Когда нужна:
- Команда > 1 человека
- Специализированные задачи
- Хочешь автоматизацию
Следующий документ: 03_INSTALL.md