跳到主要内容

凭据池

凭据池允许你为同一提供商注册多个 API 密钥或 OAuth 令牌。当某个密钥达到速率限制或账单配额时,Hermes 会自动切换到下一个健康的密钥——在不切换提供商的情况下保持会话持续运行。

这与 备用提供商 不同,后者会完全切换到 另一个 提供商。凭据池是同一提供商内的轮换;而备用提供商则是跨提供商的故障转移。系统会优先尝试池中的密钥——只有当池中所有密钥都耗尽后,才会激活备用提供商。

工作原理

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 密钥,Hermes 会自动将其识别为一个单密钥池。要享受池化带来的优势,请添加更多密钥:

# 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

检查你的池状态:

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 密钥和 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 命令

命令描述
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 中配置:

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

错误恢复

池会根据不同的错误采取不同行为:

错误行为冷却时间
429 速率限制同一密钥重试一次(瞬态)。连续两次 429 则切换到下一个密钥1 小时
402 账单/配额限制立即切换到下一个密钥24 小时
401 认证过期首先尝试刷新 OAuth 令牌。仅在刷新失败时才轮换
所有密钥耗尽如果已配置,将切换到 fallback_model

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

自定义端点池

自定义 OpenAI 兼容端点(如 Together.ai、RunPod、本地服务器)拥有独立的池,其键名为 config.yamlcustom_providers 的端点名称。

当你通过 hermes model 设置自定义端点时,会自动生成一个名称,如 "Together.ai" 或 "Local (localhost:8080)"。该名称将成为池的键。

# 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

自定义端点池存储在 auth.jsoncredential_pool 下,带有 custom: 前缀:

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

自动发现

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

来源示例是否自动填充
环境变量OPENROUTER_API_KEYANTHROPIC_API_KEY
OAuth 令牌(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 添加)不会被自动清理。

委托与子代理共享

当代理通过 delegate_task 派生子代理时,父代理的凭据池会自动共享给子代理:

  • 同一提供商 —— 子代理接收父代理的完整凭据池,支持在速率限制下进行密钥轮换
  • 不同提供商 —— 子代理加载该提供商自己的凭据池(如果已配置)
  • 未配置凭据池 —— 子代理回退到继承的单个 API 密钥

这意味着子代理可以像父代理一样受益于速率限制的容错能力,无需额外配置。每任务凭据租赁机制确保子代理在并发轮换密钥时不会相互冲突。

线程安全

凭据池对所有状态变更操作(select()mark_exhausted_and_rotate()try_refresh_current()mark_used())使用线程锁,确保网关在同时处理多个聊天会话时能够安全地并发访问。

架构

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

凭据池集成在提供者解析层:

  1. agent/credential_pool.py — 池管理器:存储、选择、轮换、冷却期
  2. hermes_cli/auth_commands.py — CLI 命令和交互式向导
  3. hermes_cli/runtime_provider.py — 支持池的凭据解析
  4. 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