Поставить LLM-шлюз, попросив агента: плагин Keystone для Claude Code
- пятница, 6 ноября 2026 г. в 00:00:07

Попросите агента «поставь нам LLM-шлюз», и он уверенно придумает переменные окружения, которых не существует. Поэтому у Keystone есть плагин для Claude Code: восемь скиллов, которые знают настоящие команды, флаги и поля конфига, и MCP-сервер, через который агент видит, что запущено. Ключи при этом в чат не попадают.
Keystone. The Model Switchboard. (KTMS) — self-hosted LLM-шлюз на Go: сервисы ходят в одну точку, а он хранит ключи вендоров, выбирает модель по правилам, переключается при отказах и держит лимиты расходов. Про сам шлюз была релизная статья, здесь — как его поставить за один разговор с агентом.
claude plugin marketplace add ai-process/ktms && claude plugin install ktms@ai-process
✔ Successfully added marketplace: ai-process (declared in user settings) Installing plugin "ktms@ai-process"...✔ Successfully installed plugin: ktms@ai-process (scope: user)
Скиллы вызывают CLI ktms, его нужно положить в PATH из архива релиза или через go install. Версия плагина совпадает с версией Keystone.
Скилл | Что делает |
|---|---|
| Смотрит на систему и говорит, куда встаёт Keystone и с чего начать |
| Compose или Helm, секреты, порядок первого запуска |
| Переводит вызовы LLM одного сервиса на шлюз |
| Маршрутизация, ключи и лимиты в |
| Переезд с другого шлюза или с прямых вызовов SDK |
| Локальная GPU-нода с фолбэком в облако |
| Вопросы о расходах, отчёты и алерты |
| Проверка перед запуском и после |
Помнить названия не нужно: агент сам берёт подходящий скилл, а слеш-команда запускает его явно.
Демо-проект — три сервиса. Бот поддержки на OpenAI SDK с model="gpt-4o" в двух местах, поиск на Anthropic SDK с эмбеддингами OpenAI, ночной воркер, который зовёт Gemini около 40 000 раз за ночь. В Compose уже есть Postgres, Redis и Prometheus.
/ktms:assess ничего не меняет. Он читает код и деплой, перечисляет все вызовы LLM с файлом и строкой и отвечает: где запустить Keystone, что поменяется в каждом сервисе, что это даст и чего будет стоить, какой скилл запускать дальше. И честно говорит, если шлюз здесь не нужен: например, один сервис, одна модель, лимитов нет.
Ответ — отчёт строк на сто. Скилл нашёл все пять вызовов с файлом и строкой и заметил то, о чём его не спрашивали:
Every service loads it through
env_file, so each one gets all three vendor keys.
То есть каждый сервис получает все три ключа вендоров. И про temperature:
temperature=0.3indraft_reply:/v1ignores it, so check reply quality after the switch.
Ещё он заметил, что rerank.ts ничего не переранжирует, а только объясняет результаты, и что основные деньги и риск — в ночном воркере. Шлюз он ставит так:
Compose project "demo-shop" (one network, nothing exposed to the host) ┌─────────────────────────────────────────────────────────────────┐ │ support-bot ─┐ │ │ search-api ──┼── HTTP :8080 /v1 ──▶ ktms ──▶ OpenAI │ │ digest-worker┘ (gRPC :9090 later ├─▶ Anthropic │ │ for batch) └─▶ Gemini │ │ │ │ │ │ │ postgres:16 ◀── db "ktms" ──┘ │ └── :9091 ◀── prometheus │ │ redis:7 ◀──── limits ──────────┘ │ │ light-tokenmeter ◀── usage events (spend per action_id) │ │ ktms-admin (internal only; reach it via SSH tunnel/VPN) │ └─────────────────────────────────────────────────────────────────┘
Вердикт с условием:
Verdict: worth it. If the system were only support-bot on
gpt-4o, it wouldn't be.
Если бы был только бот поддержки на gpt-4o, шлюз был бы не нужен. План начинается с ночного воркера: один вызов, пользователи его не видят, неудачную ночь можно просто перезапустить.
/ktms:deploy сначала спрашивает: Compose на одном хосте или Kubernetes с Helm, свои или управляемые Postgres и Redis, где хранятся секреты, имена хостов, мониторинг. Потом пишет файлы, где каждый секрет — ссылка на хранилище, пробы на /readyz и порядок первого запуска.
Один шаг агент нарочно оставляет человеку: ktms init в собственном терминале. Команда спрашивает админский ключ и ключи вендоров без эха, поэтому в чат они не попадают, пишет ktms.yaml с моделями и правилами по умолчанию, показывает план и применяет.

Дальше /ktms:configure работает с этим файлом как с Terraform: правка, ktms config plan, план показан человеку, применение только после согласия. Ограничения зашиты в инструменты, а не в промпт:
MCP-сервер ktms по умолчанию только читает. Инструменты записи появляются, только если
добавить --allow-write.
config_plan возвращает plan_id, а config_apply применяет ровно этот план один раз и
откажется, если конфигурация успела измениться.
Ключ вендора в плане берётся из окружения MCP-сервера и только из переменных KTMS_VENDOR_KEY_*,
так что агент не может подсунуть в конфиг админский ключ или другой секрет.
Имена и значения, пришедшие из Keystone, помечены как данные, а не инструкции.
/ktms:integrate тоже начинает со списка вызовов и ничего не меняет. Потом собирает адрес, ключ, таймауты, ретраи и атрибуцию в один маленький клиентский модуль и меняет каждую зашитую модель на уровень сложности с обоснованием в одну строку: low для классификации и коротких ответов, medium для обычной генерации, high для рассуждений и длинных документов.
Он же выключает ретраи SDK и один раз реализует контракт ошибок (ждать Retry-After на 429, отступать на 503, не повторять ошибки конфигурации) и помечает то, что не переносится: эмбеддингам нужен точный id модели, а temperature, top_p, stop и seed OpenAI-совместимый API Keystone игнорирует.
Проверка в конце — по настоящей маршрутизации:
$ ktms route explain billing --effort low rule: default effort: low route mode: direct # MODEL VENDOR STATE 1 gpt-4o-mini openai kept 2 gemini-2.5-flash google dropped: no_vendor_key 3 gpt-4o openai dropped: effort tries: gpt-4o-mini
Это вывод Keystone 1.3.6. Цепочка, которая заканчивается моделью в статусе kept, в порядке; если в конце no_vendor_key, ключа не хватает, и это видно до выкатки сервиса.
Скилл, который называет флаг, удалённый два релиза назад, отправит агента в ошибку, а дальше агент начнёт импровизировать. Поэтому CI Keystone читает каждый SKILL.md и падает, если в нём есть команда ktms, флаг, инструмент MCP или раздел README, которых в этой версии нет.
Скиллы — обычные Agent Skills, папка с SKILL.md. Их можно скопировать в Codex, Cursor или другой агент, который их читает, и подключить два MCP-сервера. Для ассистентов без скиллов и MCP те же инструкции лежат промптами.
Keystone: https://github.com/ai-process/ktms
Подробнее, на английском: https://blog.ai-process.dev/2026/11/04/set-up-keystone-from-claude-code/