dsh-api-key-switch:在设置面板保存多把 API Key 并一键切换

前言

用 DSH 跑智能体,常见一类需求是同一个接口地址、多把 API Key:主力 Key 限流了切备用,或者按配额轮换。原生做法是改配置或环境变量里的凭据引用,保存后重启 DSH 才生效。切换一次成本不高,但排障时反复重启会打断正在跑的请求。

下面介绍 my-0228 维护的 Web 插件 dsh-api-key-switch。它在设置面板里新增一页,把多把 Key 存到本机凭据库,列表里点「使用」即可切换,下一次模型请求就生效,不需要重启 DSH。插件属于 admin-security 分类,无运行时依赖、无构建步骤。

这是什么

一句话定位:一个 DSH Web 插件,在设置面板保存多把 API Key 并切换当前生效的那把。

  • 维护者:my-0228(package.json 里 author 为 mayue,邮箱 1771826962@qq.com)
  • 许可证:MIT
  • 版本:1.0.0
  • 运行要求:DSH 0.2.x(Web 端)、Node.js >= 20
  • 路径:dsh-api-key-switch(包名与插件 id 同名)

它不改动 DSH 本身的模型配置界面,只在设置左侧导航挂一页,复用 DSH 已有的客户端槽位契约(settings.section)与 Connection RPC 信封。原生「设置 → 模型」页照常可用,两边读到的是同一份凭据事实。

核心功能

  1. 设置面板左侧导航新增一页「API Key 切换」。
  2. 在本机保存多把 API Key(名称 + Key),列表里点「使用」切换。
  3. 切换把选中的 Key 写进当前 LLM 路由引用的凭据(默认 DEEPSEEK_API_KEY);凭据库按请求解析,所以下一次模型请求就生效。
  4. 列表只显示掩码(如 sk-a…599c);明文只在输入那一刻存在,不会回到浏览器。

「当前生效」这一列有两种显示:显示插件内的 Key 名称,或者显示 外部设置。后者说明凭据是别处写入的(例如官方「模型」页),点「收录到列表」即可纳入管理。

安装与启用

安装命令来自 README,用 profile 方式安装并进入 web 平台:

dsh plugin --profile web add github:my-0228/dsh-api-key-switch

这条命令会在 profile 里建立依赖,并把本包追加到 dsh.profile.bundles(本包声明了 dsh.bundle.patch)。完成后刷新 DSH 页面;如果设置面板没有出现新页,重启一次 DSH。

开发时也可以从本地目录安装,便于改完即测:

dsh plugin --profile web add /path/to/dsh-api-key-switch

开发模式下两个半件都是纯源码:Host 半是普通 ESM Cordis 插件 lib/index.js,浏览器半是手写 window.__ModuleLoader__.load({id, factory}) 包裹的 CJS lib/client.js,不需要构建步骤。

典型用法

先准备一个 profile 里的凭据引用。插件默认写 DEEPSEEK_API_KEY,只要你的 LLM 路由引用了这个名称即可直接用。也可以用profile 侧覆盖层改 ref,见下一节。

  1. 打开设置,左侧导航选「API Key 切换」。
  2. 填「名称」和「API Key」,勾选「保存后立即启用」,保存。
  3. 以后在列表里点「使用」切换;生效中的那行带「使用中」标记。

三条规则需要提前知道:

  • 同一把 Key 只允许保存一次。否则会出现一条显示未生效、却删不掉的重复条目。
  • 删除「使用中」的那一行会被拒绝。
  • 改「使用中」那行的 Key 时,新 Key 会自动接替生效,不会留下”旧 Key 还在用”的状态。

配置项

本包的 Cordis patch 里有一条 Host 行:

- insert:
    - id: dsh-api-key-switch
      name: dsh-api-key-switch
      config:
        ref: DEEPSEEK_API_KEY   # 要切换的凭据引用;换成别的 apiKeyEnv 也成立
  • ref:POSIX 标识符形式的凭据引用名,默认 DEEPSEEK_API_KEY。
  • RPC 路由 /api/dsh-api-key-switch 与浏览器半硬编码在同一条约定上;要改就得同时改 lib/index.js 与 lib/client.js 的常量。
  • 改 ref 时请改 profile 侧的覆盖层(cordis.patch.yml 的 id 定向覆盖),不要直接改本包的 patch:patch 是整段替换 config,不是合并。

存储与安全边界

保存的 Key 放在 DSH 凭据库的记录区 $DSH_HOME/.credentials.yaml,形状如下:

records:
  dsh-api-key-switch/<id>:
    kind: grant
    payload:
      label: 主力
      apiKey: sk-…
      createdAt: 2026-11-03T02:41:59.797Z

这里有几个容易踩的坑,README 都写明了:

  • id 形如 k-<uuid>,必须以小写字母开头。凭据库要求记录键的每一段都匹配 [a-z][a-z0-9-]*,否则下次启动整份凭据文件解析失败,连带所有 LLM 路由。
  • 「当前生效」不额外存指针,等于 refs[ref] 的值。手改凭据文件也不会让两边说法不一致。
  • 切换走凭据服务的 set():原子写加跨进程锁。
  • 校验:名称 1–64 字符、禁止控制字符;Key 8–512 个可见 ASCII 字符、禁止空白;最多 50 把;Key 不允许重复;删除生效中的 Key 会被拒绝。
  • 凭据库只读时(describe().writable === false),本页禁用所有写操作并说明原因。
  • Windows 上凭据文件的保护取决于目录 ACL,与 DSH 自身凭据库一致。
  • 插件不联网、不做 Key 有效性校验,也不把 Key 写入日志或前端以外的位置。

卸载与清理

dsh plugin --profile web remove dsh-api-key-switch

卸载不会清掉已保存的 Key 记录。Key 记录仍在 .credentials.yaml 的 records 里,refs 保持最后一次切换的结果。清理请只删除条目,不要手写或改动记录内容:把 records 下 dsh-api-key-switch/ 开头的整段删掉即可。写错形状(例如缺少 kind: grant/payload)会让下次启动解析失败。

如果 .credentials.yaml 里已经出现非法记录键(症状是 DSH 启动后所有模型请求都报凭据错误,或日志里出现 invalid document),用附带脚本一键改名,默认只修本插件 scope、默认 dry-run:

node scripts/repair-credentials.mjs            # 预演,只打印
node scripts/repair-credentials.mjs --apply    # 真正修复(写前备份 .credentials.yaml.bak-<时间>)

脚本只改记录键的拼写(补 k- 前缀),payload、refs、注释和其它 scope 原样保留;修完重启 DSH 或等它重新加载凭据库。

适用场景与注意

适合的人:一个 LLM 路由对应多个同源 Key,需要按限流、配额或成本手动轮换,且不想为每次切换重启 DSH 的开发者。如果你的需求是切换 baseURL 或切换模型,这个插件不在范围内。

注意以下几点:

  • 插件以当前 DSH 进程权限运行,写入能力等同 DSH 进程的凭据库访问权限。安装前应检查源码与许可证(MIT),确认它存取的凭据引用名与你的配置一致。
  • 插件不做 Key 有效性校验,也不联网。Key 无效时由 DSH 原生报错。
  • 没有导出 Config(schemastery),ref 在 apply 里手写校验,插件检查器里看不到表单。
  • 浏览器半依赖 DSH 0.2.x 的客户端槽位契约与 Connection RPC 信封,DSH 大版本升级后需按新契约复核。
  • 生态背景:DSH 理念是「一切皆插件」;目录站点是社区独立站点,与 DeepSeek / 幻方无官方从属关系。

小结

dsh-api-key-switch 解决的是「同一接口多把 Key」的轮换问题:面板管理、本机存储、按请求生效、不重启。它只做这一件事,边界很清楚。目录页与源码如下:

  • 目录页:https://www.skillhub.cn/plugins/my-0228/dsh-api-key-switch
  • GitHub:https://github.com/my-0228/dsh-api-key-switch
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜