我为 DeepSeek Harness 写了个断连自动续跑插件:起因是 DeepSeek 涨价

4 阅读4分钟

我为 DeepSeek Harness 写了个断连自动续跑插件:起因是 DeepSeek 涨价

DeepSeek 这轮涨价涨得太狠了。我平时跑 agent 任务量不小,官方 API 的价格撑不住,就把模型切到了阿里云百炼——学生认证送 300 元额度,国内主流模型基本都能用,够我这种个人用户跑很久。

但免费额度有代价:百炼的 API 有 RPM(每分钟请求数)和 TPM(每分钟 token 数)限制。DeepSeek Harness(DSH)这种 agent 工具跑长任务时,回合动不动就被限流打断。最气人的是,模型经常已经跑完大半内容,只差最后一点,你一打断就得重新盯着屏幕、手动补一句「继续」、再等它接着跑。

一次两次还行,天天这样真的烦。于是我写了个客户端插件:检测到回合中断后自动发送「继续」续跑,不用人管。已经发布到 npm,也被 awesome-deepseek-harness 收录了。

插件干了什么

DSH 的会话事件流会持续推送回合状态。插件监听这个流,发现回合以「中断 / 报错 / 超长」结束时,等一个宽限期,自动向该会话发送「继续」。

api.events.mux 事件流 → turn/end 检测 → 宽限期 → sessions.prompt 发送「继续」

具体的判断在 turn/end 事件的 reason.kind 字段,命中 error / interrupted / max-tokens 三种才动手。宽限期默认 5 秒,给 host 留出重连恢复的时间。发送用 queue 模式,消息原样进会话日志,模型看到就接着干。

另外做了几个护栏:冷却期(默认 20 秒,同一会话两次自动继续的最小间隔)、连续次数上限(默认 5 次,到了停手等人工)、启动时扫描最近 15 分钟内被中断的会话自动恢复。这些值都能在设置卡片里调。

GitHub: github.com/Frog755/dsh… npm: www.npmjs.com/package/@fr…

三个关键设计

只发「继续」,不切模型、不切 provider

断连重试和故障转移是两码事。自动重试只管把被打断的活续上,「这个 provider 挂了换一个」应该由 DSH 的模型路由配置去管。插件越权切 provider,轻则浪费 token,重则把用户配置搞乱。这条我写代码时特别坚持。

冷却期加连续次数上限,防止自动重试烧钱

如果 provider 持续报错,无脑自动重试只会反复烧 token。两个护栏——冷却期和连续次数上限——就是为了兜住这种情况。自动化省心是真的,但没这两个参数兜底,它就是个烧钱机器。

启动时扫描,重启后也能捞回断掉的会话

页面加载后扫一遍最近 15 分钟内被中断的会话并自动恢复。窗口可配置,不会误触很久以前的老会话。

技术实现

DSH 的事件流是 RPC 信封格式:帧是 { rpcId, payload },真正的内容在 payload 里。

// 帧 → { rpcId, payload },payload 才是 session/event
const payload = (frame && frame.payload) || frame;
if (payload.type !== "session/event") return;

turn/end 事件的 reason.kind 枚举有六种:completed / aborted / blocked / error / max-tokens / interrupted。我只对后三种自动重试。前三种是正常结束或用户主动取消,插件不该碰。

发送「继续」的代码:

await api.sessions.prompt({
  sessionId,
    mode: "queue",
      content: [{ type: "text", text: "继续" }]
      });

设置卡片用 @deepseek-ai/dsh-settings 注册 schema(applies: "live" 实时生效),再通过 ctx.slots.inject("settings.general.item") 注入,中英文案都有。

发布踩的坑

npm scoped 包要带 --access public 包名用了 @frog755/dsh-client-auto-retry,第一次 npm publish 直接 402——npm 默认把 scoped 包当私有包。加上 --access public 就好。

granular token 只能发自己的 scope。 我的 npm token 只授权 @frog755/*,发非 scoped 包名直接 403。最后统一用 @frog755/ 前缀,和之前发的 @frog755/dsh-wallpaper 保持一致。

不同版本的 DSH 接口可能不一样。 插件按 DSH 0.1.0-rc.7 写的(web 端,desktop runtime 同版)。DSH 版本很杂——桌面 App、各种 rc、社区构建,客户端 API 可能有差异,比如 events.mux 的帧信封、turn/end 的 reason 枚举、sessions.prompt 的请求结构、window.__ModuleLoader__ 加载格式、settings/slots 注册方式。所以仓库里放了一份 9 项 API 对照表加排查清单(docs/COMPATIBILITY.md),其他版本的用户照着核对基本能适配。

效果

已发布 npm,已被 awesome-deepseek-harness 收录(fendouai/awesome-deepseek-harness #24),也提交了 awesome-dsh-plugin 收录(1400+ 插件的大榜,进榜即进 dsh-market 应用市场)。

如果你也被 DSH 回合断连烦过,试试:github.com/Frog755/dsh…

有想法或者踩到别的坑,欢迎提 issue,也可以直接 fork 改。