Credential Pools
Назначение
Пулы учётных данных позволяют зарегистрировать несколько API-ключей или OAuth-токенов для одного провайдера. Когда один ключ исчерпывает лимит запросов или квоту, Hermes автоматически переключается на следующий доступный ключ, поддерживая сессию без смены провайдера.
Это принципиально отличается от механизма fallback-провайдеров. Пулы работают в пределах одного провайдера (ротация ключей), тогда как fallback-провайдеры переключаются на другой провайдер целиком. Пулы проверяются первыми, и только после исчерпания всех ключей активируется fallback.
Принцип работы
Быстрый старт
Если в .env уже настроен API-ключ, Hermes автоматически создаёт пул из одного ключа. Чтобы получить преимущества пулинга, добавьте дополнительные ключи:
Просмотр текущих пулов:
Пример вывода:
Стрелка <- обозначает текущий активный учётный объект.
Интерактивное управление
Запуск hermes auth без подкоманды открывает интерактивный мастер:
Мастер отображает текущее состояние пулов и предлагает меню:
Для провайдеров с поддержкой и API-ключей, и OAuth (Anthropic, Nous, Codex) при добавлении выбирается тип:
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:
| Стратегия | Поведение |
|---|---|
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)"). Это имя используется как ключ пула:
Кастомные пулы хранятся в auth.json с префиксом custom::
Автообнаружение учётных данных
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:
Запись OpenRouter получена из внешнего источника, поэтому сырой ключ не хранится в auth.json. Запись Anthropic добавлена вручную, поэтому токен сохраняется полностью.
Стратегии ротации хранятся в config.yaml (отдельно от auth.json):
Архитектура
Интеграция пула учётных данных реализована на уровне разрешения провайдеров:
agent/credential_pool.py-- Управление пулом: хранилище, выбор, ротация, кулдауныhermes_cli/auth_commands.py-- CLI-команды и интерактивный мастерhermes_cli/runtime_provider.py-- Разрешение учётных данных с учётом пулаrun_agent.py-- Обработка ошибок: 429/402/401 -> ротация пула -> fallback
Полная схема потока данных доступна в файле docs/credential-pool-flow.excalidraw репозитория.
Источники
- Оригинальная документация
- GitHub:
NousResearch/hermes-agent