Pular para o conteúdo principal

Documentação oficial desta página · v0.20.6

Pools de Credenciais

Pools de credenciais deixam você registrar várias chaves de API ou tokens OAuth do mesmo provedor. Quando uma chave bate num limite de taxa ou numa cota de cobrança, o Hermes gira automaticamente para a próxima chave saudável — mantendo a sua sessão viva sem trocar de provedor.

Isso é diferente dos provedores de reserva, que trocam por um provedor totalmente diferente. Pools de credenciais são rotação dentro do mesmo provedor; provedores de reserva são failover entre provedores. Os pools são tentados primeiro — se todas as chaves do pool se esgotarem, aí sim o provedor de reserva entra em ação.

A rotação de chave zera o cache de prompt

Os caches de prompt do lado do provedor (Anthropic, OpenAI, OpenRouter) valem por conta/chave de API que fez a requisição. Quando o pool gira para outra chave no meio da sessão, a chave nova não tem prefixo em cache da sua conversa — a requisição seguinte relê o histórico inteiro pelo preço cheio de entrada, e voltar para a chave anterior mais tarde é outra releitura completa, a menos que o TTL do cache da chave antiga ainda esteja válido. A rotação mantém a sua sessão de pé, que é o objetivo, mas em conversas longas cada rotação custa uma passagem de preço cheio sobre o contexto.

dica

Pools de credenciais servem principalmente para provedores com chave de API (OpenRouter, Anthropic). Um único OAuth do Nous Portal cobre mais de 300 modelos, então a maioria dos usuários não precisa de pool quando está no Portal.

Como funciona​

Sua requisição
→ Escolhe uma chave do pool (round_robin / least_used / fill_first / random)
→ Envia ao provedor
→ 429 de limite de taxa?
→ Limite do plano/uso atingido (ex.: "usage limit reached" do ChatGPT/Codex)?
→ Gira já para a próxima chave do pool (sem retentativa — o teto não some ao repetir)
→ 429 genérico / transitório?
→ Repete uma vez com a mesma chave (falha passageira)
→ Segundo 429 → gira para a próxima chave do pool
→ Todas as chaves esgotadas → fallback_model (outro provedor)
→ 402 de erro de cobrança?
→ Gira imediatamente para a próxima chave do pool (1h de espera)
→ 401 de autenticação expirada?
→ Tenta renovar o token (OAuth)
→ Renovação falhou → gira para a próxima chave do pool
→ Sucesso → segue normalmente

Início rápido​

Se você já tem uma chave de API definida no .env, o Hermes a descobre sozinho como um pool de 1 chave. Para tirar proveito do pool, acrescente mais chaves:

# Acrescenta uma segunda chave do OpenRouter
hermes auth add openrouter --api-key sk-or-v1-sua-segunda-chave

# Acrescenta uma segunda chave da Anthropic
hermes auth add anthropic --type api-key --api-key sk-ant-api03-sua-segunda-chave

# Acrescenta uma credencial OAuth da Anthropic (exige plano Claude Max + créditos extras de uso)
hermes auth add anthropic --type oauth
# Abre o navegador para o login OAuth

Confira os seus pools:

hermes auth list

Saída:

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

O ← marca a credencial selecionada no momento.

Gerenciamento interativo​

Rode hermes auth sem subcomando para abrir um assistente interativo:

hermes auth

Ele mostra o estado completo dos seus pools e oferece um menu:

What would you like to do?
1. Add a credential
2. Remove a credential
3. Reset cooldowns for a provider
4. Set rotation strategy for a provider
5. Exit

Para provedores que aceitam tanto chave de API quanto OAuth (Anthropic, Nous, Codex), o fluxo de adição pergunta qual dos dois:

anthropic supports both API keys and OAuth login.
1. API key (paste a key from the provider dashboard)
2. OAuth login (authenticate via browser)
Type [1/2]:

Comandos da CLI​

ComandoDescrição
hermes authAssistente interativo de gerenciamento de pools
hermes auth listMostra todos os pools e credenciais
hermes auth list <provider>Mostra o pool de um provedor específico
hermes auth add <provider>Acrescenta uma credencial (pergunta o tipo e a chave)
hermes auth add <provider> --type api-key --api-key <key>Acrescenta uma chave de API sem interação
hermes auth add <provider> --type oauthAcrescenta uma credencial OAuth pelo login no navegador
hermes auth remove <provider> <index>Remove a credencial pelo índice (começa em 1)
hermes auth reset <provider>Limpa todos os tempos de espera e o estado de esgotamento

Estratégias de rotação​

Configure em hermes auth → "Set rotation strategy", ou no config.yaml:

credential_pool_strategies:
openrouter: round_robin
anthropic: least_used
EstratégiaComportamento
fill_first (padrão)Usa a primeira chave saudável até esgotá-la, depois passa para a próxima
round_robinPercorre as chaves de forma equilibrada, girando a cada seleção
least_usedEscolhe sempre a chave com a menor contagem de requisições
randomSeleção aleatória entre as chaves saudáveis

Recuperação de erros​

O pool trata cada erro de um jeito:

ErroComportamentoTempo de espera
429 limite de taxaRepete uma vez com a mesma chave (transitório). O segundo 429 seguido gira para a próxima chave1 hora
402 cobrança/cotaGira imediatamente para a próxima chave1 hora
401 autenticação expiradaTenta primeiro renovar o token OAuth. Só gira se a renovação falhar5 minutos
Todas as chaves esgotadasCai para o fallback_model, se estiver configurado—

Carimbos de reset_at fornecidos pelo provedor sobrescrevem esses tempos de espera padrão.

A flag has_retried_429 é zerada a cada chamada de API bem-sucedida, então um 429 transitório isolado não dispara rotação.

Pools de endpoints personalizados​

Endpoints personalizados compatíveis com a OpenAI (Together.ai, RunPod, servidores locais) ganham pools próprios, indexados pelo nome do endpoint no dicionário providers: do config.yaml (ou pela lista legada custom_providers, que é migrada automaticamente).

Quando você configura um endpoint personalizado com hermes model, ele gera sozinho um nome como "Together.ai" ou "Local (localhost:8080)". Esse nome vira a chave do pool.

# Depois de configurar um endpoint personalizado com hermes model:
hermes auth list
# Mostra:
# Together.ai (1 credential):
# #1 config key api_key config:Together.ai ←

# Acrescente uma segunda chave para o mesmo endpoint:
hermes auth add Together.ai --api-key sk-together-segunda-chave

Os pools de endpoints personalizados ficam no auth.json, dentro de credential_pool, com o prefixo custom::

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

Descoberta automática​

O Hermes descobre credenciais sozinho, em várias fontes, e semeia o pool na inicialização:

FonteExemploSemeada automaticamente?
Variáveis de ambienteOPENROUTER_API_KEY, ANTHROPIC_API_KEYSim
Tokens OAuth (auth.json)Device code do Codex, device code da NousSim
Credenciais do Claude Code~/.claude/.credentials.jsonSim (Anthropic)
OAuth PKCE do Hermes~/.hermes/auth.jsonSim (Anthropic)
Configuração de endpoint personalizadomodel.api_key no config.yamlSim (endpoints personalizados)
Entradas manuaisAcrescentadas com hermes auth addPersistidas no auth.json

As entradas semeadas automaticamente são atualizadas a cada carga do pool — se você remover uma variável de ambiente, a entrada correspondente é podada sozinha. Entradas manuais (acrescentadas com hermes auth add) nunca são podadas automaticamente.

Segredos de runtime emprestados (por exemplo, variáveis de ambiente, referências a Bitwarden/Vault/keyring/systemd e valores de configuração personalizados) são apenas referências na fronteira do auth.json. O Hermes pode usar o valor resolvido em memória durante a execução atual, mas só persiste metadados: a referência de origem, o rótulo, o status, os contadores de requisição e uma impressão digital não reversível. Entradas manuais e o estado de OAuth/device code que pertence ao Hermes guardam os tokens duráveis de que precisam para renovar.

Delegação e compartilhamento com subagentes​

Quando o agente cria subagentes com delegate_task, o pool de credenciais do pai é compartilhado automaticamente com os filhos:

  • Mesmo provedor — o filho recebe o pool completo do pai, o que permite rotação de chave em limites de taxa
  • Provedor diferente — o filho carrega o pool próprio daquele provedor (se houver)
  • Nenhum pool configurado — o filho recorre à chave de API única herdada

Ou seja, os subagentes ganham a mesma resiliência a limite de taxa que o pai, sem configuração extra. O empréstimo de credencial por tarefa garante que os filhos não conflitem entre si ao girar chaves em paralelo.

Segurança entre threads​

O pool de credenciais usa um lock de threading para toda mutação de estado (select(), mark_exhausted_and_rotate(), try_refresh_current(), mark_used()). Isso garante acesso concorrente seguro quando o gateway atende várias sessões de chat ao mesmo tempo.

Arquitetura​

Para o diagrama completo do fluxo de dados, veja docs/credential-pool-flow.excalidraw no repositório.

O pool de credenciais se integra na camada de resolução de provedor:

  1. agent/credential_pool.py — gerenciador do pool: armazenamento, seleção, rotação, tempos de espera
  2. hermes_cli/auth_commands.py — comandos da CLI e assistente interativo
  3. hermes_cli/runtime_provider.py — resolução de credencial ciente do pool
  4. run_agent.py — recuperação de erros: 429/402/401 → rotação do pool → reserva

Armazenamento​

O estado do pool fica em ~/.hermes/auth.json, sob a chave credential_pool:

{
"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-..."
}
]
}
}

A entrada do OpenRouter acima foi emprestada de uma fonte externa, então a chave crua não fica guardada no auth.json. A entrada manual da Anthropic foi acrescentada de propósito ao armazenamento de credenciais do Hermes, então o token dela continua persistível.

As estratégias ficam no config.yaml (não no auth.json):

credential_pool_strategies:
openrouter: round_robin
anthropic: least_used