9Router — локальный LLM-роутер с автофолбэком и экономией токенов

· 2 мин чтения
llm model-routing ai-gateway open-source tokens
📂 Исходный код на GitHub

Локальный LLM-роутер: единый OpenAI-совместимый эндпоинт для Claude Code, Codex, Cursor, Cline и других CLI, трёхуровневый автофолбэк, сжатие вывода инструментов на 20-40% токенов и учёт квот.

9Router — локальный LLM-роутер с автофолбэком и экономией токенов

Если вы гоняете Claude Code, Codex или Cursor, то рано или поздно упираетесь в три вещи: месячная квота подписки сгорает неиспользованной, rate limit останавливает работу посреди задачи, а вывод инструментов (git diff, grep, ls) съедает треть бюджета токенов. 9Router — локальный прокси, который решает все три проблемы сразу: он принимает запросы от любого CLI-инструмента на одном адресе, переводит формат под нужного провайдера и сам переключается на следующий по счёту, когда текущий исчерпан.

Проект написан на JavaScript, распространяется под MIT- лицензией, собирается на Next.js 16 и React 19, а на GitHub у него почти 30 000 звёзд. Официальный сайт — 9router.com, есть русская версия README в репозитории.

Как устроена маршрутизация

Схема работы простая: ваш CLI-инструмент отправляет запрос на http://localhost:20128/v1, роутер применяет оптимизации, конвертирует формат и уходит к провайдеру. Дальше срабатывает трёхуровневый каскад:

Tier 1: SUBSCRIPTION   Claude Code, Codex, GitHub Copilot
        ↓ квота исчерпана
Tier 2: CHEAP          GLM ($0.6/1M), MiniMax ($0.2/1M)
        ↓ лимит бюджета
Tier 3: FREE           Kiro, OpenCode Free, Vertex AI

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

Combo: "always-on"
  1. cc/claude-opus-4-7
  2. cx/gpt-5.5
  3. glm/glm-5.1
  4. minimax/MiniMax-M2.7
  5. kr/claude-sonnet-4.5

Префикс модели задаёт провайдера: cc/ — подписка Claude Code, cx/ — Codex, gh/ — GitHub Copilot, cu/ — Cursor, kr/ — бесплатный Kiro, oc/ — OpenCode Free, vertex/ — Vertex AI.

Экономия токенов

Главная техническая особенность 9Router — встроенный RTK Token Saver, порт RTK с Rust на JavaScript. Он перехватывает результаты инструментов и сжимает их до отправки в LLM. Заявленная экономия — 20-40% входных токенов на каждом запросе.

Фильтры покрывают git-diff, git-status, grep, find, ls, tree, дедупликацию логов, умное усечение и чтение с нумерацией строк. Никакой настройки не нужно: RTK заглядывает в первые 1 КБ каждого tool_result и сам подбирает фильтр. Если фильтр падает или увеличивает объём — молча остаётся исходный текст, запрос никогда не ломается. Сжатие работает до конвертации форматов, поэтому одинаково применимо ко всем провайдерам.

Заявленный в README пример:

Без RTK: 47K токенов отправлено в LLM
С RTK:   28K токенов отправлено в LLM   (40% экономии)

Отключается сжатие заголовком X-9Router-Token-Saver: off — либо тумблером в дашборде.

Сверху натягиваются ещё два необязательных режима. Caveman (JuliusBrussee/caveman) подмешивает в промпт сокращённый стиль общения и экономит до 65% выходных токенов. Ponytail (DietrichGebert/ponytail) вставляет системный промпт «ленивого сеньора» и подталкивает модель к минимальному YAGNI-коду; есть режимы Lite, Full и Ultra. Отдельно поддерживается внешний прокси Headroom (chopratejas/headroom) с эндпоинтом /v1/compress — если он лежит, запрос уходит без изменений.

Быстрый старт

npm install -g 9router
9router

Дашборд открывается на http://localhost:20128. Дальше в разделе Providers подключаете бесплатный провайдер — например Kiro AI или OpenCode Free (последний вообще не требует авторизации), — копируете API-ключ и прописываете его в настройках CLI-инструмента:

Endpoint: http://localhost:20128/v1
API Key:  [скопировать из дашборда]
Model:    kr/claude-sonnet-4.5

Ноутбук с 8 ГБ RAM для сборки из исходников не подойдёт — README прямо говорит, что ожидаемый путь локальной разработки это Docker, и приводит команды с временным swap-файлом. Готовые образы опубликованы на Docker Hub и GHCR, запуск сводится к одной строке:

docker run -d --name 9router -p 20128:20128 \
  -v "$HOME/.9router:/app/data" -e DATA_DIR=/app/data \
  decolua/9router:latest

Состояние лежит в SQLite по пути $HOME/.9router/db/data.sqlite на хосте и /app/data/db/data.sqlite внутри контейнера.

Провайдеры

Уровень Провайдеры Стоимость
Подписка Claude Code, Codex, GitHub Copilot, Cursor $10-200/мес
OAuth Claude Code, Antigravity, Codex, GitHub, Cursor, Kimchi по подписке
Дёшево GLM-5.1 / 4.7, MiniMax M2.7, Kimi K2.5 $0.2-0.6 за 1M
Бесплатно Kiro AI, OpenCode Free, Vertex AI $0 в рамках лимитов
Свои whisper.cpp, faster-whisper, Kokoro-FastAPI, llama-server, vLLM свой сервер

Через OAuth подключаются Claude Code, Antigravity, Codex, GitHub, Cursor и Kimchi — токены обновляются автоматически, повторная авторизация не нужна. Для одного провайдера можно завести несколько аккаунтов: роутер перебирает их по кругу или по приоритету и переходит к следующему, когда один упирается в квоту.

По API-ключам доступно 40+ облачных провайдеров, включая OpenRouter, OpenAI, Anthropic, Gemini, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA и SiliconFlow.

Отдельно сделана связка со своими локальными моделями для речи и эмбеддингов. Адрес задаётся в поле providerSpecificData.baseUrl на уровне каждого подключения, поэтому один провайдер может обслуживать сразу несколько машин:

Провайдер Что указать Какой адрес получится
Self-hosted STT полный URL с /v1/audio/transcriptions как есть
Self-hosted TTS корень сервера + /v1/audio/speech
Self-hosted Embedding базу OpenAI вместе с /v1 + /embeddings

Тонкость, на которой часто спотыкаются: для эмбеддингов /v1 в адресе обязателен, потому что адаптер сам дописывает /embeddings, и llama-server на неверном пути отвечает кодом 501. При этом у Self-hosted Embedding намеренно нет облачного фолбэка — соединение без baseUrl помечается как ошибка конфигурации, а не молча уходит на сторонний сервер вместе с вашим текстом и ключом.

Поддерживаемые инструменты

Роутер работает с Claude Code, OpenClaw, Codex, OpenCode, Cursor, Antigravity, Cline, Continue, Droid, Roo, Copilot, Kilo Code, OpenDesign, jcode, Grok Build, Devin CLI, DeepSeek TUI и Qwen Code. Принцип простой: если инструмент умеет менять базовый URL OpenAI-совместимого API — он работает.

Для Claude Code правится ~/.claude/config.json:

{
  "anthropic_api_base": "http://localhost:20128/v1",
  "anthropic_api_key": "your-9router-api-key"
}

Для Codex CLI достаточно двух переменных окружения:

export OPENAI_BASE_URL="http://localhost:20128"
export OPENAI_API_KEY="your-9router-api-key"

Осторожно с цифрами в дашборде

Отдельный раздел FAQ объясняет то, что регулярно пугает новичков: сумма «$290 total cost» в аналитике — не счёт. Это оценка того, сколько вы бы заплатили при прямом обращении к платным API. Сам 9Router бесплатный, не хранит карту и не выставляет счетов; платите вы провайдерам напрямую. Дашборд работает как трекер экономии.

Форк

Стоит присмотреться и к OmniRoute — полноценному TypeScript-порту 9Router с 36+ провайдерами, четырёхуровневым фолбэком, мультимодальными API (изображения, эмбеддинги, аудио, TTS), circuit breaker, семантическим кэшем и 368+ юнит-тестами. Оригинальная JavaScript-версия, в свою очередь, портирована с CLIProxyAPI — оригинальной Go-реализации, которая её вдохновила. Лицензия MIT, текст — LICENSE.

Источник: https://github.com/decolua/9router