9Router — локальный LLM-роутер с автофолбэком и экономией токенов
📂 Исходный код на GitHubЛокальный LLM-роутер: единый OpenAI-совместимый эндпоинт для Claude Code, Codex, Cursor, Cline и других CLI, трёхуровневый автофолбэк, сжатие вывода инструментов на 20-40% токенов и учёт квот.
Если вы гоняете 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