pi-multikey
v1.14.0
Published
One pi provider backed by many API keys: automatic 429 rotation, per-request key leases for concurrent subagents, and a /multikey management TUI
Maintainers
Readme
pi-multikey
一个 pi 扩展:把多个 API key 组成一个"密钥池",对外只暴露一个 provider。
解决三个痛点:
- 不用为每个 key 复制一份 provider 配置 —— 模型(contextWindow / 模态 / thinkingLevelMap / compat)只配置一次,换 key、加 key 都不动模型定义。
- 429 自动换 key —— 请求失败立刻用下一个 key 重试,失败的 key 进入冷却(尊重
retry-after),无需手工切换 provider。 - 并发 subagent 自动分摊 key —— 每个进行中的请求持有一个 key lease,选择策略是"在用数最少 + 最久未用",所以主 agent 同时开多个 subagent 时,它们天然落在不同的 key 上。
安装
# 方式一:git(推荐,无需 npm 账号)
pi install git:github.com/kslamph/[email protected]
# 方式二:npm(scoped 包,发布时始终带 --access public)
pi install npm:pi-multikey
# 方式三:本地目录
pi install /path/to/multikey快速开始(B.AI preset)
/multikey → Add pool… → Preset: B.AI → 逐行粘贴 key(一行一个,留空结束)选 preset 后 endpoint、compat、3 个模型的全部设定自动就位,模型通过
bai/<model-id> 直接可用,例如 bai/hy3。
Presets
内置 preset 把"模型设定"与"密钥"解耦。数据来自 b.ai model cards、
DeepSeek / Tencent / 小米官方文档,并对每个 thinking 档位做过实测探测;
不支持的档位写为 null,UI 不显示。
| 模型 | ctx / max-out | 模态 | 生效 thinking 档位 | |---|---|---|---| | hy3 | 256K / 128K | text | off · low · high | | mimo-v2.5 | 1M / 128K | text+image | off · high(官方:low/medium/high 行为相同) | | qwen3.8-flash | 1M / 131K | text+image | off · low · medium · xhigh |
为什么必须显式写
null:pi 的getSupportedThinkingLevels把mapped === null视为不支持并隐藏该档,但省略会被当作支持并把档名原样发给 API;xhigh/max还要求显式给出非 null 值才可用。
配置
~/.pi/agent/multikey.json。首次运行时会从 ~/.pi/agent/models.json 自动发现
可合并的池(同一 baseUrl 出现 ≥2 个 provider = 你在按 key 复制 provider),
也会收录指向 api.b.ai 的 provider;什么都没发现则生成空配置。
{
"pools": [
{
"id": "bai", // pi 里的 provider id → bai/hy3
"name": "B.AI (Key Pool)",
"baseUrl": "https://api.b.ai/v1",
"api": "openai-completions",
"auth": "bearer", // 可选:"bearer"(默认)或 "api-key"(x-api-key 头)
"compat": { ... }, // provider 级默认,合并进每个模型
"cooldownMs": 20000, // 429 冷却
"invalidKeyCooldownMs": 600000, // 401/403 冷却
"keys": [
{ "key": "sk-...", "label": "key-1", "enabled": true },
{ "key": "sk-...", "label": "key-2", "enabled": true }
],
"models": [ "…preset 或手动配置的模型定义…" ]
}
]
}以后要加 nvidia 等其他 provider:/multikey → Add pool…(Custom),或直接编辑
JSON 后 Reload config from disk。
添加自定义池(不再询问 API 类型)
自定义向导只问最基本的三项:provider id、Base URL、key。随后自动探测端点:
- 用
Authorization: Bearer请求<baseUrl>/models(会自动尝试<baseUrl>/v1/models),若返回 401/403 再换x-api-key重试。 - 有些网关的
/models是公开的,因此还会发一个 1 token 的迷你 chat 请求验证 key。若两种头都被拒但假 key 能通过,说明是免鉴权的开放端点,按默认 Bearer 保存。 - 直接从服务端返回的模型列表中多选要添加的模型。元数据里的上下文长度 / 输入模态 / 最大输出会被采用,其余一律安全默认值(128k 上下文、text 输入、16k 最大输出、成本 0)。
- 可选:逐模型微调常用参数(上下文、输入模态、最大输出),或跳过以后在 Models 菜单里改。高级字段(thinking 映射、compat、cost)直接编辑
multikey.json后Reload config from disk。
探测出的认证头风格只在端点确实要求 x-api-key 时才会存为 "auth": "api-key",默认 Bearer。整池最后一次性写入,中途取消不会留下半成品 provider。
管理界面
/multikey
├─ Status 实时状态:每把 key 的 in-flight / 冷却 / 429 计数
├─ Manage pools… api 类型非法的池会标 ⚠ broken;未完成的池标 (incomplete)
│ ├─ Keys… 一行一个添加 key;删 / 改 / 禁用
│ ├─ Models… 从 /models 拉取多选添加,或手动添加;编辑 contextWindow、
│ │ maxTokens、模态、reasoning、thinkingLevelMap、compat、cost
│ ├─ Endpoint & settings… baseUrl、api 类型、认证风格、冷却时长、headers
│ └─ Delete pool
├─ Add pool…
│ ├─ Preset: B.AI 预置全部模型设定,粘贴 key(自动校验)即可用
│ ├─ Preset: OpenCode Zen 免费层模型预置(8 个模型),粘贴 key 即可用
│ └─ Custom… 只填 id + Base URL + key,随后自动探测、多选模型、安全默认值
└─ Reload config from disk改动即时生效(重新注册 provider),无需重启。
工作原理
- 扩展通过
pi.registerProvider()注册 provider,并提供自定义streamSimple。 - 每次请求从池中取一把 key(
options.apiKey覆盖),收到 HTTP 响应头后:- 429 → 该 key 冷却(默认 20s,尊重
retry-after),立即换 key 重试(不产生任何重复输出); - 401/403 → 该 key 长冷却(默认 10 分钟),换 key 重试;
- 其他错误 → 原样交给 pi 的重试机制。
- 429 → 该 key 冷却(默认 20s,尊重
- 所有 key 都耗尽时才向上抛 429,由 pi 自身的 backoff 重试兜底(此时最早的冷却多半已结束)。
安全提示
key 明文保存在 ~/.pi/agent/multikey.json,建议:
chmod 600 ~/.pi/agent/multikey.json