当多个 API key 各有额度限制时,通过本地代理均匀轮询消耗,对 tchkiller 完全透明。
┌─────────────┐ ┌──────────────┐ ┌────────────┐
│ tchkiller │ providers.json │ key_proxy │ round-robin │ 上游 API │
│ │ base_url:8090 │ (本地代理) │ sk-1→sk-2→sk-3 │ │
│ 单个 key │ ─────────────────► │ │ ─────────────────► │ GLM/其他 │
│ 单个进程 │ SSE streaming │ 端口 8090 │ 透传 SSE │ │
└─────────────┘ └──────────────┘ └────────────┘
│
┌──────┴──────┐
│ 额度耗尽? │
│ 402/429 │
│ → 冷却 60s │
│ → 跳到下个 │
│ → 自动重试 │
└─────────────┘
- 上下文丢失:tchkiller 通过 subprocess 运行 agent,API key 以环境变量传入,换 key = 重启进程 = 丢失对话上下文
- Proxy 方案:对 tchkiller 完全透明,只看到一个 endpoint + 一个 key,进程不重启,上下文不丢
方式 A:命令行直接传
python3 key_proxy.py \
--keys "sk-glm-aaa,sk-glm-bbb,sk-glm-ccc" \
--upstream https://open.bigmodel.cn/api/anthropic方式 B:keys 文件
# 创建 keys.txt(每行一个 key,# 开头为注释)
cat > keys.txt << 'EOF'
# GLM API keys
sk-glm-aaa
sk-glm-bbb
sk-glm-ccc
EOF
python3 key_proxy.py --keys-file keys.txt --upstream https://open.bigmodel.cn/api/anthropic将使用 proxy 的 provider 的 base_url 指向 localhost:8090,api_key 设为 proxy token:
{
"providers": [
{
"name": "glm-proxy",
"base_url": "http://localhost:8090",
"api_key": "proxy-local-token",
"models": {
"sonnet": "glm-5.1",
"haiku": "glm-5.1",
"opus": "glm-5.1",
"judge": "glm-5.1"
}
}
]
}python3 main.py TARGET -m cve_cloud --browser无需任何代码修改。
| 参数 | 默认值 | 说明 |
|---|---|---|
--keys |
- | 逗号分隔的 API keys |
--keys-file |
- | API keys 文件路径(每行一个) |
--upstream |
(必填) | 上游 API base URL |
--port |
8090 | 监听端口 |
--host |
127.0.0.1 | 监听地址 |
--token |
proxy-local-token | Proxy 鉴权 token |
--cooldown |
60 | key 额度耗尽冷却秒数 |
[ 1] POST /v1/messages → key-1 (200) # 正常请求
[ 2] POST /v1/messages → key-2 (200) # 轮到 key-2
[ 3] POST /v1/messages → key-3 (200) # 轮到 key-3
⚠️ key-1 额度耗尽,冷却 60s(剩余 2/3 可用) # key-1 触发 429
[ 4] POST /v1/messages → key-2 (retry, 200) # 自动重试
- Atomic Round-Robin:每次请求使用下一个 key(1→2→3→1→2→3...)
- 额度耗尽自动跳过:检测到 402/429 → 该 key 冷却 N 秒 → 立即用下一个 key 重试当前请求
- 冷却自动恢复:冷却时间到后 key 自动回到轮询池
- 全部耗尽:所有 key 都在冷却 → 选等待时间最短的 key(不会阻塞)
两个机制互不冲突:
请求级(key_proxy 处理):
单次请求 429 → proxy 内部换 key 重试 → tchkiller 无感知
轮次级(ProviderManager 处理):
proxy 全部 key 耗尽 → 返回 429 给 tchkiller → failover 到其他 provider(如 minimax)
- 关闭 proxy 进程
providers.json中base_url改回上游直连地址- 完事
- 仅监听
127.0.0.1,外部无法访问 - 使用 token 鉴权,防止本机其他进程滥用
- keys 通过命令行或文件传入,不写入代码
- keys.txt 已在 .gitignore 中,不会被提交