按供应商与模型粒度限速 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-AgentdynamicIds—— 追加每次请求随机的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
截图
设置卡片

设置配置
![]() |
![]() |
Composer Dock 实时统计

许可证
链接
同类插件
corrinehu/dsh-workbuddy-connect★ 456
将 WorkBuddy 桌面 App 包含的模型自动接入 DeepSeek Harness,在 DSH 对话窗口里零配置使用。
V1ki/dsh-plugin-subscriptions★ 447
把 ChatGPT(Codex)、Claude、Grok 订阅当作 DeepSeek Harness 的 LLM 提供方:设置页登录、模型目录、用量展示,以及 image_generate、video_generate 与 x_search 工具。
Mars-Sea/dsh-commandcode-provider★ 379
非官方 Command Code 模型接入插件:注册 `commandcode` 路由,带实时模型目录与推理强度支持。
cv-superding/dsh-deepseek-web-login★ 256
新增 deepseek-web provider,把 chat.deepseek.com 网页端模型接入 DSH:浏览器登录抓取、PoW 请求签名、SSE 流式传输与基于提示词的工具调用。
FishBottle7/opencode2dsh★ 175
将 OpenCode Zen 免费模型接入 DeepSeek Harness,无需 API Key。
WSL043/dsh-codex-subscription★ 161
通过 ChatGPT OAuth 在 DSH 中使用 Codex 模型,提供订阅联网搜索、额度与安全重置、图片工具、高速模式和模型感知上下文;无需 API Key 或 Codex CLI。


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