跳到主要内容

凭证池

Credential pool 允许你为同一个大模型提供商(provider)注册多个 API key 或 OAuth token。当某个 key 遇到限流或账单配额问题时,Hermes 会自动切换到下一个健康 key,而无需切换到其他 provider。

这与 fallback providers 不同。fallback 大模型提供商(provider) 是切换到另一个 provider;credential pool 是在同一个 大模型提供商(provider) 内部轮换。Hermes 会先尝试 pool;如果 pool 中所有 key 都耗尽,才会触发 fallback provider。

工作原理

Your request
→ Pick key from pool (round_robin / least_used / fill_first / random)
→ Send to provider
→ 429 rate limit?
→ Retry same key once (transient blip)
→ Second 429 → rotate to next pool key
→ All keys exhausted → fallback_model (different provider)
→ 402 billing error?
→ Immediately rotate to next pool key (24h cooldown)
→ 401 auth expired?
→ Try refreshing the token (OAuth)
→ Refresh failed → rotate to next pool key
→ Success → continue normally

快速开始

如果你已经在 .env 中设置了某个 API key,Hermes 会自动把它识别为一个只含 1 个 key 的 pool。若想真正发挥 pool 价值,请继续添加更多 key:

# Add a second OpenRouter key
hermes auth add openrouter --api-key sk-or-v1-your-second-key

# Add a second Anthropic key
hermes auth add anthropic --type api-key --api-key sk-ant-api03-your-second-key

# Add an Anthropic OAuth credential (Claude Code subscription)
hermes auth add anthropic --type oauth
# Opens browser for OAuth login

查看当前 pool:

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

它会展示完整 pool 状态并提供菜单:

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

对于同时支持 API key 和 OAuth 的大模型提供商(provider)(如 Anthropic、Nous、Codex),添加流程会进一步询问凭据类型。

CLI 命令

命令说明
hermes auth交互式 pool 管理向导
hermes auth list显示所有 pools 与凭据
hermes auth list <provider>显示某个特定 大模型提供商(provider) 的 pool
hermes auth add <provider>添加凭据
hermes auth add <provider> --type api-key --api-key <key>非交互方式添加 API key
hermes auth add <provider> --type oauth通过浏览器登录添加 OAuth 凭据
hermes auth remove <provider> <index>按 1-based 索引移除凭据
hermes auth reset <provider>清空该 大模型提供商(provider) 的 cooldown / exhaustion 状态

轮换策略

可通过 hermes auth → “Set rotation strategy” 或直接在 config.yaml 中配置:

credential_pool_strategies:
openrouter: round_robin
anthropic: least_used
策略行为
fill_first(默认)优先使用第一个健康 key,直到其耗尽,再切到下一个
round_robin均匀轮转,每次选择后切到下一个
least_used始终选择请求次数最少的 key
random在健康 key 中随机选择

错误恢复

pool 会针对不同错误采取不同策略:

错误行为Cooldown
429 Rate Limit同一 key 先重试一次;连续第二次 429 才切换到下一个 key1 小时
402 Billing/Quota立即切换到下一个 key24 小时
401 Auth Expired先尝试刷新 OAuth token;仅在刷新失败时切换
All keys exhausted若已配置 fallback_model,则回退到其他 大模型提供商(provider)

has_retried_429 标志会在每次成功 API 调用后重置,因此单次偶发 429 不会立即触发轮换。

自定义端点 pools

自定义的 OpenAI 兼容端点(如 Together.ai、RunPod、本地服务)也会拥有自己的 credential pool,其 key 取自 config.yamlcustom_providers 的端点名称。

通过 hermes model 设置自定义端点时,Hermes 会自动生成名称,例如 “Together.ai” 或 “Local (localhost:8080)”。这个名称就是 pool 的主键。

# After setting up a custom endpoint via hermes model:
hermes auth list
# Shows:
# Together.ai (1 credential):
# #1 config key api_key config:Together.ai ←

# Add a second key for the same endpoint:
hermes auth add Together.ai --api-key sk-together-second-key

这些自定义端点的 pool 会以 custom: 前缀保存在 auth.jsoncredential_pool 下:

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

自动发现

Hermes 会从多个来源自动发现凭据,并在启动时为 pool 预填充:

来源示例自动加入 pool?
环境变量OPENROUTER_API_KEY, ANTHROPIC_API_KEYYes
OAuth tokens(auth.json)Codex device code, Nous device codeYes
Claude Code 凭据~/.claude/.credentials.jsonYes(Anthropic)
Hermes PKCE OAuth~/.hermes/auth.jsonYes(Anthropic)
自定义端点配置model.api_key in config.yamlYes(自定义端点)
手工添加项通过 hermes auth add 添加持久保存在 auth.json

自动发现的条目会在每次加载 pool 时同步更新;如果你删除了某个环境变量,对应 pool 条目也会自动消失。手工添加的条目则不会被自动裁剪。

Delegation 与子智能体共享

当智能体通过 delegate_task 启动子智能体时,父智能体的 credential pool 会自动共享给子智能体:

  • 同一 provider — 子智能体继承父智能体的完整 pool,可在限流时轮换 key
  • 不同 provider — 子智能体会加载目标 大模型提供商(provider) 自己的 pool(若有配置)
  • 未配置 pool — 子智能体会回退到继承下来的单个 API key

这意味着子智能体天然拥有与父智能体相同的限流韧性,无需额外配置。每任务凭据租约机制还能避免多个子智能体并发轮换时相互冲突。

线程安全

credential pool 在所有状态变更操作上都使用线程锁,从而确保 网关 同时处理多个聊天会话时的并发安全。

架构

完整数据流图见仓库中的 docs/credential-pool-flow.excalidraw

credential pool 集成在 大模型提供商(provider) 解析层:

  1. agent/credential_pool.py — pool 管理器:存储、选择、轮换、cooldown
  2. hermes_cli/auth_commands.py — CLI 命令与交互式向导
  3. hermes_cli/runtime_provider.py — 感知 pool 的凭据解析
  4. run_agent.py — 错误恢复:429 / 402 / 401 → pool 轮换 → fallback

存储

pool 状态保存在 ~/.hermes/auth.jsoncredential_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 中:

credential_pool_strategies:
openrouter: round_robin
anthropic: least_used