凭据池允许你为同一个提供商注册多个 API key 或 OAuth token。当某个 key 达到速率限制或计费配额时,Hermes 会自动轮换到下一个健康的 key —— 从而在不切换提供商的情况下保持你的会话继续运行。
这不同于 备用提供商,备用提供商会切换到完全不同的提供商。凭据池是在同一提供商内部轮换;备用提供商是跨提供商故障转移。凭据池会优先尝试 —— 如果所有池中的 key 都耗尽,才会激活备用提供商。
你的请求 → 从池中选择 key(round_robin / least_used / fill_first / random) → 发送给提供商 → 429 速率限制? → 使用同一个 key 重试一次(瞬时波动) → 第二次 429 → 轮换到下一个池中的 key → 所有 key 都耗尽 → fallback_model(不同提供商) → 402 计费错误? → 立即轮换到下一个池中的 key(24 小时冷却) → 401 认证过期? → 尝试刷新 token(OAuth) → 刷新失败 → 轮换到下一个池中的 key → 成功 → 正常继续如果你已经在 .env 中设置了 API key,Hermes 会自动将其发现为一个单 key 池。要从池化中受益,请添加更多 key:
# 添加第二个 OpenRouter keyhermes auth add openrouter --api-key sk-or-v1-your-second-key
# 添加第二个 Anthropic keyhermes auth add anthropic --type api-key --api-key sk-ant-api03-your-second-key
# 添加 Anthropic OAuth 凭据(需要 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这会显示你的完整凭据池状态,并提供一个菜单:
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 的提供商(Anthropic、Nous、Codex),添加流程会询问使用哪种类型:
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]:CLI 命令
Section titled “CLI 命令”| 命令 | 描述 |
|---|---|
hermes auth | 交互式凭据池管理向导 |
hermes auth list | 显示所有凭据池和凭据 |
hermes auth list <provider> | 显示特定提供商的凭据池 |
hermes auth add <provider> | 添加凭据(提示输入类型和 key) |
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 开始的索引移除凭据 |
hermes auth reset <provider> | 清除所有冷却/耗尽状态 |
通过 hermes auth → “Set rotation strategy” 配置,或在 config.yaml 中配置:
credential_pool_strategies: openrouter: round_robin anthropic: least_used| 策略 | 行为 |
|---|---|
fill_first(默认) | 使用第一个健康 key,直到它耗尽,然后移动到下一个 |
round_robin | 在 key 之间均匀循环,每次选择后轮换 |
least_used | 始终选择请求次数最低的 key |
random | 在健康 key 中随机选择 |
凭据池会针对不同错误采取不同处理方式:
| 错误 | 行为 | 冷却时间 |
|---|---|---|
| 429 Rate Limit | 先用同一个 key 重试一次(瞬时问题)。连续第二次 429 则轮换到下一个 key | 1 小时 |
| 402 Billing/Quota | 立即轮换到下一个 key | 24 小时 |
| 401 Auth Expired | 先尝试刷新 OAuth token。只有刷新失败时才轮换 | — |
| 所有 key 都耗尽 | 如果已配置,则转入 fallback_model | — |
has_retried_429 标志会在每次成功 API 调用后重置,因此单次瞬时 429 不会触发轮换。
自定义端点池
Section titled “自定义端点池”自定义 OpenAI 兼容端点(Together.ai、RunPod、本地服务器)拥有自己的池,其 key 来自 config.yaml 中 custom_providers 的端点名称。
当你通过 hermes model 设置自定义端点时,它会自动生成一个名称,例如 "Together.ai" 或 "Local (localhost:8080)"。这个名称会成为池 key。
# 通过 hermes model 设置自定义端点后:hermes auth list# 显示:# Together.ai (1 credential):# #1 config key api_key config:Together.ai ←
# 为同一个端点添加第二个 key:hermes auth add Together.ai --api-key sk-together-second-key自定义端点池会存储在 auth.json 的 credential_pool 下,并带有 custom: 前缀:
{ "credential_pool": { "openrouter": [...], "custom:together.ai": [...] }}Hermes 会自动从多个来源发现凭据,并在启动时初始化凭据池:
| 来源 | 示例 | 是否自动初始化? |
|---|---|---|
| 环境变量 | OPENROUTER_API_KEY、ANTHROPIC_API_KEY | 是 |
OAuth token(auth.json) | Codex 设备码、Nous 设备码 | 是 |
| Claude Code 凭据 | ~/.claude/.credentials.json | 是(Anthropic) |
| Hermes PKCE OAuth | ~/.hermes/auth.json | 是(Anthropic) |
| 自定义端点配置 | config.yaml 中的 model.api_key | 是(自定义端点) |
| 手动条目 | 通过 hermes auth add 添加 | 持久化到 auth.json |
自动初始化的条目会在每次加载池时更新 —— 如果你移除了某个环境变量,其池条目会被自动清理。手动条目(通过 hermes auth add 添加)永远不会被自动清理。
委托与子 Agent 共享
Section titled “委托与子 Agent 共享”当 Agent 通过 delegate_task 启动子 Agent 时,父 Agent 的凭据池会自动共享给子 Agent:
同一提供商 —— 子 Agent 会收到父 Agent 的完整池,从而在速率限制时启用 key 轮换
不同提供商 —— 子 Agent 会加载该提供商自己的池(如果已配置)
未配置池 —— 子 Agent 会回退到继承的单个 API key
这意味着子 Agent 无需额外配置,也能受益于与父 Agent 相同的速率限制弹性。按任务进行凭据租赁可以确保多个子 Agent 并发轮换 key 时不会相互冲突。
凭据池对所有状态变更都使用线程锁(select()、mark_exhausted_and_rotate()、try_refresh_current()、mark_used())。这可以确保当 gateway 同时处理多个聊天会话时能够安全并发访问。
完整数据流图请参阅仓库中的 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 → 池轮换 → fallback
池状态存储在 ~/.hermes/auth.json 的 credential_pool key 下:
{ "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