Docs/Credential Pools

Credential Pools

Назначение

Пулы учётных данных позволяют зарегистрировать несколько API-ключей или OAuth-токенов для одного провайдера. Когда один ключ исчерпывает лимит запросов или квоту, Hermes автоматически переключается на следующий доступный ключ, поддерживая сессию без смены провайдера.

Это принципиально отличается от механизма fallback-провайдеров. Пулы работают в пределах одного провайдера (ротация ключей), тогда как fallback-провайдеры переключаются на другой провайдер целиком. Пулы проверяются первыми, и только после исчерпания всех ключей активируется fallback.

Принцип работы

terminal
Copy
Запрос пользователя -> Выбор ключа из пула (round_robin / least_used / fill_first / random) -> Отправка запроса провайдеру -> 429 Rate Limit? -> Лимит плана/использования (например, ChatGPT/Codex)? -> Немедленная ротация на следующий ключ (без повтора) -> Транзиентный 429? -> Повторный запрос тем же ключом один раз -> Второй 429 -> ротация на следующий ключ -> Все ключи исчерпаны -> fallback_model (другой провайдер) -> 402 Billing Error? -> Немедленная ротация на следующий ключ (кулдаун 24ч) -> 401 Auth Expired? -> Попытка обновления OAuth-токена -> Обновление не удалось -> ротация на следующий ключ -> Успех -> продолжение работы

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

Если в .env уже настроен API-ключ, Hermes автоматически создаёт пул из одного ключа. Чтобы получить преимущества пулинга, добавьте дополнительные ключи:

bash
# Второй ключ OpenRouter hermes auth add openrouter --api-key sk-or-v1-your-second-key # Второй ключ Anthropic hermes auth add anthropic --type api-key --api-key sk-ant-api03-your-second-key # OAuth-учётные данные Anthropic (требуется Claude Max + кредиты) hermes auth add anthropic --type oauth

Просмотр текущих пулов:

bash
hermes auth list

Пример вывода:

terminal
Copy
openrouter (2 credentials): #1 OPENROUTER_API_KEY api_key env:OPENROUTER_API_KEY <- #2 backup-key api_key manual anthropic (3 credentials): #1 hermes_pkce oauth hermes_pkce <- #2 claude_code oauth claude_code #3 ANTHROPIC_API_KEY api_key env:ANTHROPIC_API_KEY

Стрелка <- обозначает текущий активный учётный объект.

Интерактивное управление

Запуск hermes auth без подкоманды открывает интерактивный мастер:

bash
hermes auth

Мастер отображает текущее состояние пулов и предлагает меню:

terminal
Copy
Что вы хотите сделать? 1. Добавить учётные данные 2. Удалить учётные данные 3. Сбросить кулдауны для провайдера 4. Установить стратегию ротации для провайдера 5. Выход

Для провайдеров с поддержкой и API-ключей, и OAuth (Anthropic, Nous, Codex) при добавлении выбирается тип:

terminal
Copy
anthropic поддерживает API-ключи и OAuth-вход. 1. API-ключ (вставьте ключ из панели провайдера) 2. OAuth-вход (аутентификация через браузер) Тип [1/2]:

CLI-команды

КомандаОписание
hermes authИнтерактивный мастер управления пулами
hermes auth listОтображение всех пулов и учётных данных
hermes auth list <provider>Пул конкретного провайдера
hermes auth add <provider>Добавление учётных данных (с выбором типа)
hermes auth add <provider> --type api-key --api-key <key>Добавление API-ключа без интерактива
hermes auth add <provider> --type oauthДобавление OAuth через браузер
hermes auth remove <provider> <index>Удаление по индексу (нумерация с 1)
hermes auth reset <provider>Сброс всех кулдаунов и статусов исчерпания

Стратегии ротации

Настройка через hermes auth -> "Установить стратегию ротации" или в config.yaml:

yaml
credential_pool_strategies: openrouter: round_robin anthropic: least_used
СтратегияПоведение
fill_first (по умолчанию)Использует первый доступный ключ до исчерпания, затем переход к следующему
round_robinЦиклическое чередование ключей после каждого выбора
least_usedВыбор ключа с наименьшим количеством запросов
randomСлучайный выбор среди доступных ключей

Обработка ошибок

ОшибкаДействиеКулдаун
429 Rate LimitПовторный запрос тем же ключом (транзиентный сбой). Второй 429 подряд -> ротация1 час
402 Billing/QuotaНемедленная ротация на следующий ключ24 часа
401 Auth ExpiredПопытка обновления OAuth-токена. Ротация только при неудаче обновления--
Все ключи исчерпаныПереход к fallback_model (если настроен)--

Флаг has_retried_429 сбрасывается при каждом успешном запросе, поэтому единичный транзиентный 429 не вызывает ротацию.

Пулы пользовательских эндпоинтов

Кастомные OpenAI-совместимые эндпоинты (Together.ai, RunPod, локальные серверы) получают собственные пулы. Ключ пула формируется из имени эндпоинта в секции custom_providers конфигурации.

При настройке кастомного эндпоинта через hermes model автоматически генерируется имя (например, "Together.ai" или "Local (localhost:8080)"). Это имя используется как ключ пула:

bash
# После настройки кастомного эндпоинта: hermes auth list # Вывод: # Together.ai (1 credential): # #1 config key api_key config:Together.ai <- # Добавление второго ключа: hermes auth add Together.ai --api-key sk-together-second-key

Кастомные пулы хранятся в auth.json с префиксом custom::

json
{ "credential_pool": { "openrouter": [...], "custom:together.ai": [...] } }

Автообнаружение учётных данных

Hermes автоматически обнаруживает учётные данные из различных источников и заполняет пул при запуске:

ИсточникПримерАвтозаполнение
Переменные окруженияOPENROUTER_API_KEY, ANTHROPIC_API_KEYДа
OAuth-токены (auth.json)Codex device code, Nous device codeДа
Учётные данные Claude Code~/.claude/.credentials.jsonДа (Anthropic)
Hermes PKCE OAuth~/.hermes/auth.jsonДа (Anthropic)
Конфигурация кастомных эндпоинтовmodel.api_key в config.yamlДа (кастомные эндпоинты)
Ручные записиДобавленные через hermes auth addСохраняются в auth.json

Автозаполняемые записи обновляются при каждой загрузке пула. Если переменная окружения удалена, соответствующая запись автоматически удаляется. Ручные записи (добавленные через hermes auth add) никогда не удаляются автоматически.

Секреты из внешних источников (переменные окружения, Bitwarden/Vault/keyring/systemd, пользовательские конфигурации) хранятся как ссылки. Hermes использует раскрытое значение в памяти текущего запуска, но в auth.json сохраняются только метаданные: источник, метка, статус, счётчики запросов и необратимый отпечаток. Ручные записи и OAuth/device-code состояние хранят полные токены для обновления.

Делегация и шаринг субагентами

При создании субагентов через delegate_task пул родителя автоматически доступен дочерним агентам:

  • Тот же провайдер -- дочерний агент получает полный пул родителя с поддержкой ротации
  • Другой провайдер -- дочерний агент загружает пул этого провайдера (если настроен)
  • Пул не настроен -- наследуется единственный API-ключ

Субагенты получают те же преимущества по обходу лимитов, что и родительский агент, без дополнительной настройки. Механизм заимствования учётных данных по задачам предотвращает конфликты при параллельной ротации ключей.

Потокобезопасность

Пул учётных данных использует блокировку потоков для всех операций изменения состояния: select(), mark_exhausted_and_rotate(), try_refresh_current(), mark_used(). Это обеспечивает безопасный параллельный доступ при обработке нескольких сессий шлюзом одновременно.

Хранение

Состояние пула хранится в ~/.hermes/auth.json в ключе credential_pool:

json
{ "version": 1, "credential_pool": { "openrouter": [ { "id": "abc123", "label": "OPENROUTER_API_KEY", "auth_type": "api_key", "priority": 0, "source": "env:OPENROUTER_API_KEY", "secret_source": "bitwarden", "secret_fingerprint": "sha256:12ab34cd56ef7890", "last_status": "ok", "request_count": 142 } ], "anthropic": [ { "id": "manual1", "label": "personal-api-key", "auth_type": "api_key", "priority": 0, "source": "manual", "access_token": "sk-ant-api03-..." } ] } }

Запись OpenRouter получена из внешнего источника, поэтому сырой ключ не хранится в auth.json. Запись Anthropic добавлена вручную, поэтому токен сохраняется полностью.

Стратегии ротации хранятся в config.yaml (отдельно от auth.json):

yaml
credential_pool_strategies: openrouter: round_robin anthropic: least_used

Архитектура

Интеграция пула учётных данных реализована на уровне разрешения провайдеров:

  1. agent/credential_pool.py -- Управление пулом: хранилище, выбор, ротация, кулдауны
  2. hermes_cli/auth_commands.py -- CLI-команды и интерактивный мастер
  3. hermes_cli/runtime_provider.py -- Разрешение учётных данных с учётом пула
  4. run_agent.py -- Обработка ошибок: 429/402/401 -> ротация пула -> fallback

Полная схема потока данных доступна в файле docs/credential-pool-flow.excalidraw репозитория.

Источники