Пулы учётных данных
Пулы учётных данных позволяют зарегистрировать несколько API-ключей или OAuth-токенов для одного провайдера. Когда один ключ достигает лимита запросов или квот биллинга, Hermes автоматически переключается на следующий здоровый ключ — поддерживая вашу сессию активной без смены провайдера.
Это отличается от резервных провайдеров, которые полностью переключаются на другого провайдера. Пулы учётных данных — это ротация в рамках одного провайдера; резервные провайдеры — это отказоустойчивость между провайдерами. Сначала пробуждаются пулы — если все ключи пула исчерпаны, тогда активируется резервный провайдер.
Как это работает
Ваш запрос
→ Выбрать ключ из пула (round_robin / least_used / fill_first / random)
→ Отправить провайдеру
→ 429 превышение лимита?
→ Повторить с тем же ключом один раз (временный сбой)
→ Второй 429 → переключиться на следующий ключ пула
→ Все ключи исчерпаны → fallback_model (другой провайдер)
→ 402 ошибка биллинга?
→ Немедленно переключиться на следующий ключ пула (24-часовой тайм-аут)
→ 401 истекла аутентификация?
→ Попробовать обновить токен (OAuth)
→ Обновление не удалось → переключиться на следующий ключ пула
→ Успех → продолжить нормально
Быстрый старт
Если у вас уже есть API-ключ, установленный в .env, Hermes автоматически обнаружит его как пул из одного переключателя. Чтобы воспользоваться преимуществами пула, добавьте больше ключей:
# Добавить второй ключ 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
# Открывает браузер для входа через OAuth
Проверьте свои пулы:
hermes auth list
Вывод:
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 без подкоманд для интерактивного мастера:
hermes auth
Это покажет полный статус вашего пула и предложит меню:
Что вы хотите сделать?
1. Добавить учётные данные
2. Удалить учётные данные
3. Сбросить тайм-ауты для провайдера
4. Установить стратегию ротации для провайдера
5. Выйти
Для провайдеров, поддерживающих как API-ключи, так и OAuth (Anthropic, Nous, Codex), процесс добавления типа запроса:
anthropic поддерживает как API-ключи, так и вход через OAuth.
1. API-ключ (вставьте ключ из панели управления провайдера)
2. Вход через OAuth (аутентификация через браузер)
Введите [1/2]:
Команды CLI
| Команда | Описание |
|---|---|
гермес авт |
Интерактивный мастер управления пулом |
список аутентификации Гермеса |
Показать все пулы и учётные данные |
список аутентификации Гермеса <поставщик> |
Показать пул конкретного провайдера |
hermes auth add <провайдер> |
Добавить учётные данные (запрашивает тип и ключ) |
hermes auth add <провайдер> --type api-key --api-key <ключ> |
Добавить API-ключ неинтерактивно |
hermes auth add <провайдер> --type oauth |
Добавить учётные данные OAuth через вход в браузер |
hermes auth удалить <поставщик> <индекс> |
Удалить учётные данные по индексу (с 1) |
сброс аутентификации Гермеса <поставщик> |
Очистить все тайм-ауты/статус исчерпания |
Стратегии ротации
Настраиваем через hermes auth → "Установить таймер ротации" или в config.yaml:
credential_pool_strategies:
openrouter: round_robin
anthropic: least_used
| Стратегия | Поведение |
|---|---|
fill_first (по умолчанию) |
Используйте первый здоровый ключ, пока он не исчерпан, а затем перейдите к следующему |
round_robin |
Равномерно перебирать ключи, переключаясь после каждого выбора |
наименее_используемый |
Всегда выбирайте ключ с наименьшим количеством запросов |
случайный |
Случайный выбор среди здоровых ключей |
Восстановление после ошибок
Пул обрабатывает разные ошибки по-разному:
| Ошибка | Поведение | Тайм-аут |
|---|---|---|
| 429 Превышение лимита | Повторить с тем же ключом один раз (временный). Второй последовательный 429 переключает на следующую клавишу | 1 час |
| 402 Биллинг/Квота | Немедленно переключиться на следующий ключ | 24 часа |
| 401 Стекло аутентификации | Сначала попробуйте обновить OAuth-токен. Переключить только если обновление не удалось | — |
| Все ключи исчерпаны | Перейдите к fallback_model, если по настроению |
— |
Флаг has_retried_429 сбрасывается при каждом успешном вызове API, поэтому один временной код 429 не вызывает ротации.
Пользовательские пулы конечных точек
Пользовательские конечные точки, совместимые с OpenAI (Together.ai, RunPod, локальные серверы), получают свои собственные пулы, ключом которых является имя конечной точки из custom_providers в config.yaml.
Когда вы настраиваете пользовательскую конечную точку через «модель Hermes», она автоматически автоматически генерирует имя, например «Together.ai» или «Local (localhost:8080)». Это имя становится ключом пула.
# После настройки пользовательской конечной точки через hermes model:
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 под credential_pool с префиксом custom::
{
"credential_pool": {
"openrouter": [...],
"custom:together.ai": [...]
}
}
Автообнаружение
Гермес автоматически обнаруживает учётные данные из нескольких источников и заполняет пул при запуске:
| Источник | Пример | Автозаполнение? |
|---|---|---|
| Переменные окружения | OPENROUTER_API_KEY, ANTHROPIC_API_KEY |
Да |
| OAuth-токены (auth.json) | Код устройства Codex, код устройства Nous | Да |
| Учётные данные Claude Code | ~/.claude/.credentials.json |
Да (Антропный) |
| PKCE OAuth Гермес | ~/.hermes/auth.json |
Да (Антропный) |
| Конфигурация пользовательской конечной точки | model.api_key в config.yaml |
Да (пользовательские конечные точки) |
| Ручные записи | Добавлены через hermes auth add |
Сохраняются в auth.json |
Автозаполненные записи обновляются при каждом включении пула — если вы удалите переменную окружность, ее запись в пуле автоматически удаляется. Ручные записи (добавленные через hermes auth add) никогда не удаляются автоматически.
Делегирование и совместное использование с подагентами
Когда агент резервирует подагентов через delegate_task, пул учётных данных родителя автоматически передаётся дочерним агентам:
- Тот же провайдер — дочерний агент получает полный пул родителя, который позволяет ротировать ключи при превышении лимита
- Другой провайдер — дочерний агент загружает собственный пул этого провайдера (если настроение)
- Нет настроенного пула — дочерний агент возвращается к унаследованному одиночному API-ключу
Это означает, что подагенты получают ту же устойчивость к ограничениям скорости, что и родитель, без дополнительных настроек. Аренда учётных данных для каждой задачи гарантирует, что дочерние агенты не будут конфликтовать друг с другом при одновременной ротации ключей.
Потокобезопасность
Пул учётных данных использует потоки блокировки для всех нарушений состояния (select(), mark_exhausted_and_rotate(), try_refresh_current(), mark_used()). Это обеспечивает безопасный конкурентный доступ, когда шлюз обрабатывает несколько сеансов чата одновременно.
Архитектура
Полную диаграмму потока данных см. в docs/credential-pool-flow.excalidraw в репозитории.
Пул учётных данных интегрируется на уровне разрешения провайдера:
agent/credential_pool.py— Менеджер пула: хранение, выбор, ротация, тайм-аутыhermes_cli/auth_commands.py— Команды CLI и интерактивный мастерhermes_cli/runtime_provider.py— разрешение учётных данных с учётом пула.run_agent.py— Восстановление после ошибок: 429/402/401 → ротация пула → резервный провайдер
Хранение
Состояние пула хранится в ~/.hermes/auth.json под ключом credential_pool:
{
"version": 1,
"credential_pool": {
"openrouter": [
{
"id": "abc123",
"label": "OPENROUTER_API_KEY",
"auth_type": "api_key",
"priority": 0,
"source": "env:OPENROUTER_API_KEY",
"access_token": "sk-or-v1-...",
"last_status": "ok",
"request_count": 142
}
]
},
}
Стратегии хранения в config.yaml (не в auth.json):
credential_pool_strategies:
openrouter: round_robin
anthropic: least_used