前言¶
用 DeepSeek 跑长时间任务时,账单上最大的变量不是模型,是时间段。工作日 09:00–12:00、14:00–18:00 是原价,周末和法定节假日全天是谷价。人工盯着点去掐表暂停,既不现实也容易漏;写脚本定时 kill 会话,又会丢掉待处理队列。DSH 的插件机制允许在会话控制器层面做这件事,下面介绍的 dsh-offpeak-guard 就是这个方向的插件:它读 DeepSeek 的峰谷规则和当前会话的真实模型,在峰时暂停任务、在谷时自动恢复,并把「12 点再跑」这类需求排进下一个谷价窗口。
这是什么¶
dsh-offpeak-guard 由 HATO-24 维护,分类属于 DSH 社区目录里的「工作流」,许可证为 MIT,npm 上对应包名就是 dsh-offpeak-guard。它不替换 DSH 的任务系统,而是在会话层做一层价格窗口调度:识别当前是峰还是谷,决定正在跑和即将开始的任务该不该放行。
核心思路是两条正交的判断:
- 时间:按 DeepSeek 官方规则判断峰谷窗口,含法定节假日处理;
- 模型:按会话真实的
provider / model判断是不是峰谷计价模型,避免误伤不相关的模型。
两者都命中时才介入;其余情况插件不动作。
核心功能¶
时间识别¶
按 DeepSeek 官方规则,北京时间周一至周五(不含中国法定节假日)09:00–12:00、14:00–18:00 为峰值原价,其余时间(含周末、法定节假日全天)为谷价,按 5 折计费。节假日默认从公开 API 动态同步,失败时回退内置的 2026 列表。
模型识别¶
插件按会话的真实 provider / model 精确判断。默认情况下模型名(或供应商名)包含 deepseek 就纳入管理;也可以在设置面板逐模型开关,或用 peakPricedModels / exemptModels 精确控制,这两个列表非空时优先于 modelPattern。
峰时策略与会话豁免¶
- 策略可选「立即暂停」或「完成当前轮后暂停」;
- 会话有子代理在跑时先放行子代理,子代理结束后再暂停父会话,谷价开始时恢复;
- 可以豁免某个会话不参与暂停/恢复,通过设置面板或
offpeak_guard exempt/unexempt,随时可取消。
工作规划¶
- 峰时开始 → 暂停正在运行的任务,保留待处理队列,不丢消息;
- 峰时新起的任务 → 立即停住,不花峰时 token;
- 谷价开始 → 自动把被打断的任务交还给会话继续执行;
- 提供
offpeak_plan工具,把「12 点再跑」这类事排进下一个谷价窗口。
界面¶
输入框下方有一条状态条,显示当前峰/谷、距下次切换的倒计时、当前模型,以及暂停/规划数量。左侧栏底部另有一枚常驻计时,临近切换时闪色提醒:峰价快开始闪红,谷价快开始闪绿。点击左栏计时打开设置面板,可以切换峰时策略、逐模型管理、会话豁免、查看节假日同步状态。
另外支持就地豁免:鼠标移到左侧会话行,行尾出现盾牌按钮,点一下豁免或取消;输入框状态条右侧也有「豁免本会话」按钮。
安装与启用¶
插件已发布到 npm。在 DSH 的插件页搜索 dsh-offpeak-guard 安装,或用命令行:
dsh plugin --profile <profile> add dsh-offpeak-guard
安装完成后建议先看一次 offpeak_status,确认识别到的时段和模型符合预期。
环境要求(来自 package.json 的 engines):
{ "node": ">=22.5", "dsh": ">=0.2.1-rc.2 <0.3.0" }
典型用法¶
插件提供三个工具,覆盖查询、规划、手动控制。
| 工具 | 用途 |
|---|---|
offpeak_status |
当前时段、下次切换、当前模型是否适用、暂停与规划清单 |
offpeak_plan |
add / list / remove / clear 错峰规划 |
offpeak_guard |
status / pause_now / resume_now / run_plans_now 手动控制 |
典型的工作流是:
1、长任务在跑,先看 offpeak_status,确认现在是谷价、距峰时还有多久,判断要不要让它继续;
2、如果即将进入峰时,新任务先不要发,用 offpeak_plan add 排进下一个谷价窗口;
3、峰时开始后,插件按设置的策略暂停正在跑的任务,状态条和暂停数量会更新;
4、谷价开始,任务自动交还会话继续跑,offpeak_status 里可以看到恢复记录;
5、遇到必须马上跑的情况,用 offpeak_guard pause_now / resume_now 手动介入,resume_now 会给这些会话 10 分钟豁免,避免刚恢复又被停回去。
配置¶
配置可以写在 cordis.patch.yml 里 offpeak-guard 那一行的 config,也可以在 DSH 设置页的插件配置里修改(插件已声明 Config schema)。常用键如下,默认值按 package.json 声明。
config:
enabled: true
preset: auto
pauseMode: pause-now
timezone: Asia/Shanghai
modelPattern: deepseek
peakPricedModels: []
exemptModels: []
pauseRunningOnPeak: true
deferNewTurnsOnPeak: true
resumeOnOffPeak: true
pollSeconds: 15
resumeDelaySeconds: 3
bypassMinutes: 10
alertMinutes: 10
各键含义:
enabled:总开关;preset:auto按 provider 自动选,WorkBuddy/CodeBuddy 用workbuddy,其余用deepseek-official;也可固定为deepseek-official/workbuddy/custom;pauseMode:pause-now峰时立即暂停,finish-turn当前轮跑完再暂停;timezone:计价时区,默认Asia/Shanghai;peakWeekdays/peakWindows/discount:仅custom预设使用,官方调价或换供应商时改这里;holidays:追加的法定节假日,YYYY-MM-DD;holidaySource:auto动态同步,builtin只用内置/配置列表;modelPattern/peakPricedModels/exemptModels:模型匹配与豁免;pauseRunningOnPeak/deferNewTurnsOnPeak/resumeOnOffPeak:三条主策略开关;pollSeconds:检查间隔,范围 5–300;resumeDelaySeconds:谷价开始后等几秒再恢复;bypassMinutes:手动恢复后的豁免期;alertMinutes:左栏计时在距切换多少分钟内开始闪烁,0表示不闪。
环境变量¶
部署方可以用环境变量统一注入配置,优先级是环境变量 > 配置 > 默认,无效值会被忽略。命名规则统一为 DSH_OFFPEAK_ 前缀加配置键的大写下划线形式,例如:
DSH_OFFPEAK_PRESET=custom
DSH_OFFPEAK_PAUSE_MODE=finish-turn
DSH_OFFPEAK_PEAK_WINDOWS=09:00-12:00,14:00-18:00
DSH_OFFPEAK_DISCOUNT=0.5
DSH_OFFPEAK_HOLIDAYS=2026-10-01,2026-10-02
DSH_OFFPEAK_MODEL_PATTERN=deepseek
DSH_OFFPEAK_PEAK_MODELS=deepseek-flash,vendor/model
DSH_OFFPEAK_BYPASS_MINUTES=10
完整列表见 README,覆盖 enabled、timezone、peakWeekdays、holidaySource、holidayApi、pollSeconds 等全部配置项。
预设¶
deepseek-official(默认):官方工作日峰时 + 内置 2026 法定节假日,节假日全天谷价;workbuddy:WorkBuddy 积分规则,峰时窗口与官方相同,按 provider 自动选择时用于标注来源;custom:完全使用peakWeekdays/peakWindows/discount/holidays,适合其他供应商或自建计价。
数据与恢复机制¶
状态和快照都在 $DSH_HOME/offpeak-guard/:
state.json:暂停/等待中的任务、错峰规划、会话豁免、精确模型规则、峰时策略;status.json:给输入框状态条/设置面板读的只读快照,同时镜像到~/.dsh/offpeak-guard/status.json;holidays.json:动态同步的节假日缓存。
插件不写用户工作区。
暂停用的是 sessionController.cancel,只结束当前一轮、保留待处理队列;恢复用的是 sessionController.prompt,向原会话投递一条「继续上次中断处」的指令,冷会话会被自动唤醒。恢复文本会注明中断时间与被暂停的模型,方便在对话里追溯。
子代理与等待¶
- 峰时开始时若会话有正在运行的子代理,先放行父会话与子代理;
- 子代理结束后,父会话按当前策略暂停(记录为
waiting-children),谷价开始后自动恢复; finish-turn模式下当前轮允许跑完,如果随后又排入了下一轮,下一轮会在峰时被拦下并记录,谷价开始恢复;- 当前轮跑完且没有后续轮次时,记录标记为
completed,不会在谷价时无意义地再起一轮。
这点需要留意:插件只在子代理结束时停住父会话,无法在传输层拦截已经进入父会话历史的消息,子代理结果由模型在父会话恢复后继续消费。
适用场景与注意¶
适合这三类用法:
- 跑长任务、批量任务,希望把 token 成本压到谷价窗口的人;
- 需要把「某个时间再跑」这类安排交给模型表达,而不是手写 cron 的人;
- 团队部署,希望通过环境变量统一注入峰谷策略的运维方。
几点注意:
- 插件通过
sessionController干预会话,实际以当前 dsh 进程的权限运行,安装前建议先读一遍源码确认行为符合预期,许可证为 MIT; - 内置法定节假日目前覆盖 2026 年,2027 年安排公布前,动态同步补不上时要用
holidays或DSH_OFFPEAK_HOLIDAYS追加,否则节假日会被当作普通工作日; - 动态节假日来自第三方公开 API(默认 timor.tech,只发送年份),离线或接口失败时回退
holidays.json缓存与内置列表,设holidaySource: builtin可完全离线; - 只处理有工作目录、非子代理的根会话,避免打断子代理导致父会话卡住;
- 「会话豁免」只影响后续暂停/恢复,不会自动把已经暂停的任务立即恢复,需要时用
resume_now; - 插件自身重启时不会主动打断正在跑的任务,之后进入峰时或新起任务仍按规则处理。
结尾¶
dsh-offpeak-guard 的价值在于把峰谷计价这件事变成会话层的自动策略,而不是靠人记时间或写一次性脚本。它和 DSH 现有的暂停/恢复机制配合,不丢队列、可豁免、可回溯,适合作为日常跑任务时的默认的第一层成本控制。
目录页:https://www.skillhub.cn/plugins/HATO-24/dsh-offpeak-guard
GitHub:https://github.com/HATO-24/dsh-offpeak-guard