DeepSeek Harness 插件

jyao-SUSE-power-group/dsh-provider-rate-limit

Star 数 ★ 4 分类 模型与账号接入 收录于 2026-08-28

按供应商与模型粒度限速 LLM 请求,预约式令牌桶支持排队或拒绝两种模式,附带网关身份规则(改写 User-Agent、注入自定义请求头)。

安装

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:jyao-SUSE-power-group/dsh-provider-rate-limit

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

English | 简体中文

适用于 DeepSeek Harness 的按供应商/模型粒度 LLM 限速插件,附带网关身份规则(客户端伪装)能力,面向有身份校验的免费档网关。

功能特性

  • 令牌桶限速,按 (provider, model) 路由生效 —— 平滑补充、支持突发、空闲后自动恢复额度
  • 两种模式(桶空时):
    • wait —— 排队等待至多 maxWaitMs 后放行(对上层完全透明)
    • reject —— 立即短路,返回合成的 RATE_LIMIT 响应并携带 providerRetryAfterMs
  • 严格 FIFO —— 预约式设计保证进入顺序与到达顺序一致,全程无轮询
  • 网关身份规则 —— 对匹配 URL 改写 User-Agent / 注入静态请求头(用于校验客户端身份的网关),内置一键 OpenCode Zen 预设
  • 总开关 —— enabled 关掉即全量直通,无需反注册监听器,即时生效
  • 设置界面卡片 —— 在 Harness 设置页完成全部配置,中英双语
  • 实时统计行 —— 聊天输入框下方的精简读数,通过 SSE 实时推送(无轮询);鼠标悬停可查看各路由 provider·model 明细
  • SSE 推送接口 —— GET /api/provider-rate-limit.events 每次计数变化即推送最新快照,带 15s 心跳与自动重连
  • 统计 HTTP 接口 —— GET /api/provider-rate-limit.stats 返回聚合与分路由计数的 JSON(供统计行使用,也可对接外部工具)
  • 跨插件统计服务 —— provider-rate-limit/stats 服务供进程内消费者调用(getStats、getAllStats、getAggregateStats、resetStats)

安装

DSH 插件管理器(推荐)

dsh plugin --profile web add github:jyao-SUSE-power-group/dsh-provider-rate-limit

然后重启 DeepSeek Harness,插件会经 cordis patch 注册进 llm 服务。

手动安装

git clone https://github.com/jyao-SUSE-power-group/dsh-provider-rate-limit.git ~/.dsh/plugins/dsh-provider-rate-limit
cd ~/.dsh/plugins/dsh-provider-rate-limit && pnpm install --prod

配置说明

打开 设置 → 插件 → Provider Rate Limit。所有配置热更新,无需重启。

配置项 默认值 说明
enabled true 总开关;关闭后所有流量直通
requestsPerMinute 20 全局稳态速率(无路由规则命中时生效);0 = 不限速
burst 4 桶容量 —— 允许连续瞬时发出的请求数
mode wait wait = 排队等待;reject = 快速失败
maxWaitMs 30000 wait 模式最长排队时间,超过后回落到 reject 行为
upstream429Backoff true 上游返回 429(如配额耗尽)时,让该路由暂停,直到窗口结束
backoffMs 30000 上游 429 未带 Retry-After 时的初始冷却时长 (ms);连续 429 会指数递增至 maxBackoffMs
maxBackoffMs 60000 指数退避的冷却上限 (ms);0 = 固定冷却(同 backoffMs)
backoffJitter 0 冷却抖动比例 (0–1),防止惊群效应;0 = 确定性延迟
maxConcurrentRequests 0 每路由同时在飞的最大请求数;0 = 不限并发
models [] 路由规则:按 provider/model 子串匹配,每条可独立设 RPM/burst

路由规则

路由规则按解析出的 provider id 与模型名的子串匹配(例如 provider opencode + 模型 claude-*)。命中最具体的规则;未命中的流量走全局限额。

身份规则

部分免费网关(如 OpenCode Zen)会拒绝"看起来不像官方客户端"的请求。身份规则让选定的出站 URL 携带不同身份:

  • urlPattern —— 对请求 URL 做子串匹配
  • userAgent —— 替换后的 User-Agent
  • dynamicIds —— 追加每次请求随机的 x-opencode-client/project/session/request 头组
  • headers —— 任意静态请求头(Name: Value),最后应用,因此可以覆盖上面所有项

fetch 补丁带引用计数、干净卸载:插件停用时恰好恢复原生 fetch 一次;期间叠在我们之上的其他补丁不会被破坏。

⚠️ 请仅为你有权使用、且符合其服务条款的服务伪装身份。

实时统计

插件在 composer dock(聊天输入框下方)显示精简统计行:

限流统计 已拒绝 0 · 当前排队 0 · 累计排队 0 · 平均等待 — · 总请求 153 · 活跃路由 3

鼠标悬停可查看各路由 provider·model 明细。数据通过 SSE 实时推送 —— dock 订阅响应式统计 store,请求排队、被拒或完成时数字即时跳动,全程无轮询定时器;仅当 SSE 连接断开时才启用 30 秒兜底轮询。

SSE 推送接口

GET /api/provider-rate-limit.events

Server-Sent Events 流,每一帧都是一份完整统计快照:

data: {"aggregate":{"reserved":153,"waited":0,"totalWaitMs":0,"rejected":0,"queuedNow":0,"avgWaitMs":0,"routes":3},"routes":{...}}

连接建立时立即发送一帧,此后每次计数变化(请求预约、队列深度变化、请求被拒或完成)都会再推一帧。服务端每 15 秒发一条 : ping 注释维持代理环境下的连接存活。

HTTP 接口

GET /api/provider-rate-limit.stats

返回聚合与分路由计数的 JSON:

{
  "ok": true,
  "value": {
    "aggregate": { "reserved": 153, "waited": 0, "totalWaitMs": 0, "rejected": 0, "queuedNow": 0, "avgWaitMs": 0, "routes": 3 },
    "routes": {
      "opencode\u0000big-pickle": { "reserved": 117, "waited": 0, "queuedNow": 0, ... },
      "opencode-vision\u0000big-pickle": { "reserved": 34, ... },
      "amd-r\u0000DeepSeek-V4-Flash": { "reserved": 2, ... }
    }
  }
}

queuedNow 是当前正在排队的请求数(实时值,等待一结束立即回 0);waited 仍是累计计数。设置卡片两者同时显示。

工作原理

所有出站 LLM 流量经过唯一的 llm/stream 钩子(瀑布式收口点,同时覆盖 agent 循环、标题生成与压缩)。每次调用同步预约路由令牌桶的一个名额:

waitMs = bucket.reserve()        // 由单调地板值精确算出等待时长
if waitMs === 0                  → 立即放行
else if mode=wait && ≤ maxWaitMs → sleep(waitMs) 后放行
else                             → 产出 RATE_LIMIT 结束事件(附 Retry-After 提示)

桶的地板值为 now − (capacity − 1) × interval,呈现经典的「突发 + 自恢复」语义:空闲一段时间后桶自动回满;运行时调整容量/速率也绝不凭空发放免费突发额度。

上游 429 自动降速

当上游返回 HTTP 429(如 workspace 配额耗尽)时,插件会捕获该结束事件,并在 upstream429Backoff 开启时让该路由进入冷却窗口。窗口内新请求在 wait 模式下排队(最多 maxWaitMs)、在 reject 模式下直接拒绝,直到窗口结束 —— 避免在供应商已经拒绝我们的时候继续猛打。窗口时长优先取上游 Retry-After 头(即 providerRetryAfterMs),否则用 backoffMs 作为初始冷却。连续 429(中间无成功响应)会使冷却时间指数递增(×2),上限为 maxBackoffMs;backoffJitter 可添加随机偏移防止惊群效应。成功响应(非 429)会将退避计数器重置为初始值。429 结束事件本身仍会透传,dsh-llm-retry 也可以据此重试。

并发限制

当 maxConcurrentRequests > 0 时,插件还会限制每个路由同时在飞的请求数。通过了 RPM 检查但发现并发槽已满的请求会进入 FIFO 槽位队列,前一个请求释放的瞬间即被授予槽位 —— 全程无轮询,进入顺序严格保持到达顺序。这可以防止多个并行 agent 或子 agent 单独突破 RPM 限制但合计压垮供应商。0 = 不限并发(仅 RPM 限流)。

开发

pnpm install
npm test   # node:test 套件:桶行为、FIFO、中止/reject、身份补丁、卸载生命周期、总开关、queuedNow gauge

截图

设置卡片

设置卡片

设置配置

设置配置 1 设置配置 2

Composer Dock 实时统计

Composer Dock 统计

许可证

MIT

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。