Поставить LLM-шлюз, попросив агента: плагин Keystone для Claude Code. claude code.. claude code. DevOps.. claude code. DevOps. Go.. claude code. DevOps. Go. keystone.. claude code. DevOps. Go. keystone. llm.. claude code. DevOps. Go. keystone. llm. mcp.. claude code. DevOps. Go. keystone. llm. mcp. self-hosted.. claude code. DevOps. Go. keystone. llm. mcp. self-hosted. агенты.. claude code. DevOps. Go. keystone. llm. mcp. self-hosted. агенты. искусственный интеллект.. claude code. DevOps. Go. keystone. llm. mcp. self-hosted. агенты. искусственный интеллект. Микросервисы.. claude code. DevOps. Go. keystone. llm. mcp. self-hosted. агенты. искусственный интеллект. Микросервисы. Программирование.. claude code. DevOps. Go. keystone. llm. mcp. self-hosted. агенты. искусственный интеллект. Микросервисы. Программирование. Шлюз.
Поставить LLM-шлюз, попросив агента: плагин Keystone для Claude Code - 1

Попросите агента «поставь нам 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.

Скилл

Что делает

/ktms:assess

Смотрит на систему и говорит, куда встаёт Keystone и с чего начать

/ktms:deploy

Compose или Helm, секреты, порядок первого запуска

/ktms:integrate

Переводит вызовы LLM одного сервиса на шлюз

/ktms:configure

Маршрутизация, ключи и лимиты в ktms.yaml с планом изменений

/ktms:migrate

Переезд с другого шлюза или с прямых вызовов SDK

/ktms:node

Локальная GPU-нода с фолбэком в облако

/ktms:usage-reports

Вопросы о расходах, отчёты и алерты

/ktms:production-review

Проверка перед запуском и после

Помнить названия не нужно: агент сам берёт подходящий скилл, а слеш-команда запускает его явно.

Шаг 1. Куда встаёт шлюз

Демо-проект — три сервиса. Бот поддержки на 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.3 in draft_reply: /v1 ignores 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, шлюз был бы не нужен. План начинается с ночного воркера: один вызов, пользователи его не видят, неудачную ночь можно просто перезапустить.

Шаг 2. Деплой и конфиг без ключей в чате

/ktms:deploy сначала спрашивает: Compose на одном хосте или Kubernetes с Helm, свои или управляемые Postgres и Redis, где хранятся секреты, имена хостов, мониторинг. Потом пишет файлы, где каждый секрет — ссылка на хранилище, пробы на /readyz и порядок первого запуска.

Один шаг агент нарочно оставляет человеку: ktms init в собственном терминале. Команда спрашивает админский ключ и ключи вендоров без эха, поэтому в чат они не попадают, пишет ktms.yaml с моделями и правилами по умолчанию, показывает план и применяет.

Поставить LLM-шлюз, попросив агента: плагин Keystone для Claude Code - 2

Дальше /ktms:configure работает с этим файлом как с Terraform: правка, ktms config plan, план показан человеку, применение только после согласия. Ограничения зашиты в инструменты, а не в промпт:

  • MCP-сервер ktms по умолчанию только читает. Инструменты записи появляются, только если

добавить --allow-write.

  • config_plan возвращает plan_id, а config_apply применяет ровно этот план один раз и

откажется, если конфигурация успела измениться.

  • Ключ вендора в плане берётся из окружения MCP-сервера и только из переменных KTMS_VENDOR_KEY_*,

так что агент не может подсунуть в конфиг админский ключ или другой секрет.

  • Имена и значения, пришедшие из Keystone, помечены как данные, а не инструкции.

Шаг 3. Перевести один сервис

/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, которых в этой версии нет.

Не только Claude Code

Скиллы — обычные Agent Skills, папка с SKILL.md. Их можно скопировать в Codex, Cursor или другой агент, который их читает, и подключить два MCP-сервера. Для ассистентов без скиллов и MCP те же инструкции лежат промптами.

Автор: coylOne

Источник