Startup no longer needs arguments: the config is created on first launch, a busy port is swapped for a free one, the console is open by default, and the browser lands on a setup wizard that downloads a ready-made .cmf model and wires it into routing (managed server + routing.default) when you press Finish. Download progress was reported from curl's own meter, which prints a full 0→100% bar for the -L redirect hop before the transfer starts — so every job showed 100% and then hung. Progress now comes from bytes on disk against the size from the HuggingFace tree (or a HEAD request). The UI and the gateway also disagreed about the output file name, so a finished download never marked its card as downloaded; the gateway now returns the exact stem and the UI sends it back verbatim for download, progress and delete. Featured models are read live from the infosave HF account in both the wizard and Import, and all 432 UI strings now exist in every one of the 7 languages.
19 KiB
Cortiq Gateway
English · Русский
Универсальный LLM-шлюз с интеллектуальной маршрутизацией. Один OpenAI-совместимый endpoint → автоматический выбор модели из вашего пула (локальные дешёвые + хостовые дорогие) на основе типа задачи и сложности, которые определяет allaigate / cortiq-router.
Меняете в своём агенте/SDK только
base_url— и получаете «умный» роутинг между моделями. Никакой логики выбора модели на стороне клиента.
┌─────────────┐ OpenAI / Anthropic / MCP ┌──────────────────┐
│ Агент / │ ─────────────────────────────▶│ Cortiq Gateway │
│ разработчик │ (стандартный протокол) │ (этот проект) │
└─────────────┘ ◀─────────────────────────────└──────────────────┘
ответ + метаданные │ │
│ /v1/route│ вызов LLM
▼ ▼
┌──────────────┐ ┌─────────────────────┐
│ cortiq-router│ │ Пул моделей │
│ (тип задачи, │ │ • local llama.cpp │
│ сложность) │ │ • ollama / vLLM │
└──────────────┘ │ • OpenAI / Claude │
└─────────────────────┘
✨ Ключевое
- Запуск без конфигурации.
cortiq-gatewayбез флагов: конфиг создаётся сам, занятый порт меняется на свободный, браузер открывается на мастере, который скачивает готовую локальную модель и заводит её в роутинг — без TOML, без токена, без отдельно запущенного сервера модели. - Быстрый. Rust/Tokio: overhead шлюза с субмиллисекундным p99 — ~10× к throughput Portkey и ~47× к LiteLLM в сопоставимом бенчмарке (детали).
- Drop-in OpenAI API + стриминг. Направьте любой OpenAI-клиент на шлюз и шлите
model: "cortiq-auto";stream: trueподдержан (SSE). - Интеллектуальный роутинг.
complexity.tier→ упорядоченный пул моделей (low → локально,high → облако), с fallback и мягкой деградацией, если роутер недоступен. - Встроенная многоязычная панель управления. Модели, роутинг, протоколы, ключи и секреты — из веб-интерфейса, без ручного TOML и без рестарта (горячая перезагрузка). 7 языков (en, ru, de, fr, es, zh, tr), тёмная/светлая тема.
- Живая аналитика. Статистика по запросам (токены, стоимость, латентность, доля успеха, failover), графики, разбивка по моделям/полосам/задачам и Prometheus
GET /metrics. - Playground. Прогон промпта через живой пайплайн с разбором решения роутинга.
- Один самодостаточный бинарь. SPA встроена в Rust-бинарь — ничего лишнего разворачивать не нужно.
- Секреты не покидают шлюз. Агенты держат только виртуальный ключ шлюза; ключи провайдеров живут в шлюзе и наружу не уходят.
📦 Установка
# Docker (GitHub Container Registry)
docker run -p 9000:9000 -e CORTIQ_ADMIN_TOKEN=secret \
-v "$PWD/config:/app/config" ghcr.io/infosave2007/cortiq-gateway:latest
# → панель на http://localhost:9000/admin
# с crates.io
cargo install cortiq-gateway
cortiq-gateway # без флагов, без конфига, без токена — см. Быстрый старт
# или сборка из исходников
git clone https://github.com/infosave2007/cortiq-gateway
cd cortiq-gateway
cargo build --release # ./target/release/cortiq-gateway
Образ идёт с дефолтным конфигом и работает из коробки; смонтируйте /app/config
(с gateway.toml), чтобы использовать свой. Теги: :latest, :X.Y.Z, :edge
(linux/amd64 + arm64).
Docker Compose — шлюз + локальная модель Ollama одной командой:
docker compose up -d
docker compose exec ollama ollama pull qwen2.5:0.5b # один раз скачать модель
# → OpenAI API на http://localhost:9000/v1 · панель на /admin (токен: change-me)
См. docker-compose.yml. Для умного роутинга задайте
CORTIQ_ROUTER_KEY и добавьте [router] (см. docs/ROUTER.ru.md).
🖥️ Панель управления
В шлюз встроена веб-панель на /admin:
Панель по умолчанию открыта — токен не нужен. Чтобы закрыть её, задайте любое из
--admin-token <ТОКЕН>, [admin].token или [admin].token_env:
cortiq-gateway --admin-token <ВАШ_ТОКЕН>
# откройте http://localhost:9000/admin?token=<ВАШ_ТОКЕН>
Когда токен задан, все эндпоинты /admin/api/* требуют его как Bearer. Значения секретов
API наружу не отдаёт (только статус наличия: store / env / missing).
🚀 Быстрый старт
cortiq-gateway
Это вся команда. При первом запуске шлюз:
- создаёт конфиг —
config/gateway.toml, если запущен из репозитория, иначе~/.cortiq-gateway/gateway.toml(переопределяется через$CORTIQ_GATEWAY_HOMEили--config); - подбирает свободный порт, если 9000 занят, и записывает выбор в конфиг;
- открывает браузер на мастере настройки
/admin#/onboarding.
Мастер доводит от нуля до работающей локальной модели:
| Шаг | Что происходит |
|---|---|
| Язык | 7 языков; потом меняется в шапке |
| Готовые модели | .cmf модели infosave, список читается с HuggingFace вживую — выбираете квантизацию и видите реальный прогресс загрузки |
| Любая модель с HF | поиск по HuggingFace и автоконвертация в .cmf |
| Завершить | каждая скачанная модель подключается как локальная, поднимается её cortiq serve, routing.default указывает на неё |
Никаких правок TOML, отдельного шага «зарегистрировать» и вручную запущенного сервера модели. Мастер не нужен? Добавляйте модели из панели (Модели, Импорт модели) или пишите конфиг руками — оба пути работают, изменения применяются на лету без перезапуска.
# явный конфиг / порт / без браузера — всё опционально
cortiq-gateway --config config/gateway.toml --no-browser --no-port-search
Для умного роутинга по пулу направьте [router] на хостовый allaigate или локальный
cortiq-router (см. docs/ROUTER.ru.md). Без роутера шлюз мягко
деградирует до модели по умолчанию, поэтому чисто локальная установка работает сразу.
Теперь любой OpenAI-клиент работает через шлюз:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:9000/v1", api_key="sk-gw-...")
resp = client.chat.completions.create(
model="cortiq-auto", # ← магическая модель = «выбери сам»
messages=[{"role": "user", "content": "Solve x^2 - 5x + 6 = 0"}],
)
print(resp.choices[0].message.content)
# заголовки ответа покажут выбор шлюза:
# X-Cortiq-Task-Label: math
# X-Cortiq-Complexity-Tier: low
# X-Cortiq-Selected-Model: local-qwen
model: "cortiq-auto" включает роутинг. Любое реальное имя модели из конфига
("gpt-4o-mini", "local-qwen") — это passthrough напрямую, без роутинга.
Используете хостовый allaigate-роутер? Укажите
url = "https://138.226.222.209",verify_tls = false,taxonomy_id = "data-assistant"и ключcortiq_…вCORTIQ_ROUTER_KEY. На сложных запросах роутер эскалирует к oracle (~10 с), поэтому ставьтеtimeout_ms = 12000+— иначе шлюз мягко деградирует на default-модель.
🧭 Роутер (allaigate)
Роутинг cortiq-auto обеспечивает семантический роутер — классификатор, который
читает промпт и возвращает тип задачи + сложность. Используйте хостовый
allaigate (~94% точности на близких типах задач,
patent-pending, privacy-first) или поднимите свой cortiq-router. Pinned-моделям роутер не нужен.
🎉 Акция: возьмите Starter-ключ за $1 по промокоду
LAUNCH1на api.allaigate.com (число активаций ограничено).
Настройка, тарифы, контракт API и как проверить точность: docs/ROUTER.ru.md.
Поток запроса
- Клиент →
POST /v1/chat/completions(или Anthropic/MCP) сmodel: "cortiq-auto". - Шлюз извлекает текст для маршрутизации (стратегия настраивается, см. docs/ROUTING.ru.md).
- Шлюз →
cortiq-router /v1/route→ получаетtask_label+complexity.tier. - Шлюз выбирает модель из пула по таблице роутинга (с порядком fallback).
- Шлюз → провайдер выбранной модели (транслируя протокол при необходимости), возвращает ответ.
- Шлюз отдаёт метаданные роутинга в заголовках/
usage, считает стоимость и статистику.
Подробно — docs/ARCHITECTURE.ru.md.
Поддерживаемые протоколы (входящие)
| Протокол | Endpoint | Статус |
|---|---|---|
| OpenAI Chat Completions | POST /v1/chat/completions |
✅ реализовано (+ стриминг) |
| OpenAI Embeddings | POST /v1/embeddings |
✅ реализовано |
| Anthropic Messages | POST /v1/messages |
✅ реализовано (+ стриминг) |
| MCP (Model Context Protocol) | POST /mcp (JSON-RPC) |
✅ реализовано |
| OpenAI Completions (legacy) | POST /v1/completions |
✅ реализовано (+ стриминг) |
| OpenAI Models | GET /v1/models |
✅ реализовано |
| Native passthrough | POST /route |
✅ реализовано |
Поддерживаемые провайдеры (исходящие)
| Провайдер | Покрывает |
|---|---|
openai (OpenAI-совместимый) |
OpenAI, OpenRouter, Together, Groq, vLLM, llama.cpp server, LM Studio, Ollama (/v1) |
anthropic |
Claude Messages API (+ стриминг) |
ollama |
нативный Ollama API |
http |
произвольный HTTP-эндпоинт (свой адаптер) |
Конфигурация
Полный пример — config/gateway.example.toml. Модель роутинга и cost-aware выбор — docs/ROUTING.ru.md. Всё из конфига также правится из панели управления в рантайме.
⚡ Производительность и точность
Латентность — overhead шлюза при проксировании одного мгновенного бэкенда, ab -k -r -c 20 -n 5000:
| Шлюз | req/s | p50 | p99 |
|---|---|---|---|
| Cortiq Gateway (Rust) | ~57 300 | 0 ms | 1 ms |
| Portkey (Node) | ~5 800 | 3 ms | 9 ms |
| LiteLLM (Python, 4 воркера) | ~1 200 | 9 ms | 59 ms |
Точность — определение типа задачи на естественных промптах (7 типов). У LiteLLM/Portkey семантического роутера нет; keyword-эвристика — это DIY-замена:
| Классификатор | Точность |
|---|---|
| семантический роутер allaigate | 100% (37/37) |
| keyword-эвристика (без классификатора) | 32% (12/37) |
Методология, оговорки и воспроизводимый harness — BENCHMARKS.md
(bash bench/run.sh, python3 bench/accuracy.py). Числа зависят от железа; важны разрывы.
Сборка и тесты
cargo build --release # один самодостаточный бинарь (SPA встроена)
cargo test # round-trip конфига, валидация роутинга
✅ Проверено
| Область | Как проверено | Статус |
|---|---|---|
| Round-trip загрузки/записи конфига, валидация роутинга | cargo test (юнит) |
✅ |
| Сборка · формат · линт | CI: cargo build / fmt --check / clippy -D warnings на Linux · macOS · Windows |
✅ |
| OpenAI Chat + SSE-стриминг | интеграционно (mock-бэкенд) | ✅ |
| Anthropic Messages — in/out, стриминг + не-стриминг | интеграционно (mock) | ✅ |
Embeddings (POST /v1/embeddings) |
интеграционно (mock) | ✅ |
| Семантический кэш — hit / miss / экономия | интеграционно (mock) | ✅ |
MCP — initialize / tools/list / tools/call |
интеграционно (mock) | ✅ |
Models · Completions · нативный POST /route |
интеграционно (mock) | ✅ |
| Роутинг — auto / pinned / failover / деградация | интеграционно (mock и живой allaigate-роутер) | ✅ |
| Горячая перезагрузка конфига (без рестарта) | интеграционно | ✅ |
| Бенчмарк latency vs LiteLLM / Portkey | bench/run.sh (Apache Bench) — см. BENCHMARKS.md |
✅ |
| Точность определения типа задачи | bench/accuracy.py — живой роутер 100% vs keyword-эвристика 32% |
✅ |
Статус
Реализовано: OpenAI Chat Completions со стримингом (SSE), провайдер и вход
Anthropic /v1/messages (стриминг), embeddings, семантический кэш,
MCP-сервер, роутинг с fallback и мягкой деградацией, учёт стоимости/токенов,
встроенная многоязычная панель управления с горячей перезагрузкой конфига,
статистика и Prometheus GET /metrics. В планах: per-account таблицы роутинга,
feedback-loop в роутер. Дорожная карта —
docs/ARCHITECTURE.ru.md. Контрибьюции приветствуются —
см. CONTRIBUTING.ru.md.
Лицензия
Apache-2.0 — см. LICENSE.



