DeepSeek Harness 81 个定时任务挤在一个会话:一任务一会话的替代方案与实践
「81 个任务全落在同一个对话里,改一个要翻半天历史,执行记录和日常聊天混在一起」——这不是任务太多造成的,而是它们当初都创建在同一个会话里。 定时任务在当前的实现里绑死在创建它的 Session 上,任务记录里甚至没有「目标会话」这个字段(#10911)。所以只能倒过来用:先有专用会话,再往里建任务。下面按代价从低到高排四条路线。
DeepSeek Harness 第一优先级:一任务一会话(零改动、可立即执行)
先建专用会话,再在这个会话里创建对应任务;投递、模型、preset 都跟着会话走,主对话不受影响。
- 先想清楚任务分组:同一业务线、同一模型、同一 preset 的放一组。
- 为主对话之外的每个组新建一个会话,命名带上前缀,比如
cron-行情、cron-巡检。 - 进入该会话,在里面创建这一族定时任务。
- 确认任务的投递目标就是该会话:任务到期时 Host 会把这个冷会话恢复起来再交付。
- 主对话不再创建任何定时任务,保持干净。
- 需要几组就建几个会话,不要试图把不同模型的任务混在一个会话里。
这条路线的价值在于它不改任何代码,也不依赖插件,今天就能做。代价是会话数量会随任务族增长。
DSH插件 第二优先级:按模型与 preset 再拆一层
任务的模型与 preset 跟随来源会话,所以分组时要把这两项一起考虑。
- 列出所有任务,标注每个任务期望的模型与 preset。
- 同一模型、同一 preset 的任务合并到同一个专用会话。
- 需要不同推理档位的任务不要混在一起,否则只能全局迁就。
- 每个专用会话只放同一类任务,减少历史噪音。
- 定期清理已完成的一次性任务,避免会话被历史撑大。
DeepSeek Harness 第三优先级:社区插件(需要自己验证)
报告者列了几个方向接近的候选,但社区回复没有逐一点评,也没有在 81 条量级下验证过。
- 报告者提到的方向包括「每次执行使用独立 Session」「任务本身就是独立会话」「headless 独立进程运行」这几类实现。
- 选择前先确认三件事:是否真的每次执行新开会话、是否有可用的管理面板、升级 DSH 后是否还能装。
- 先用三到五条任务小规模试跑一周,再决定是否迁移全部任务。
- 注意插件自身的升级路径,别把 81 条任务的调度托付给一个已经停更的包。
- 任何「升级即挂」的坑,都应在试跑阶段暴露,而不是在生产任务上暴露。
这一段没有确定结论,只有验证清单——别把别人列的候选当成已验证方案。
DeepSeek Harness 第四优先级:外置调度 + headless
把调度完全移出 DSH,用系统 cron 或工作流工具触发一次 headless 运行,每次都是独立进程,天然不共享会话。
- 为每类任务写一条 headless 调用命令,参数里带上具体提示词。
- 用系统 cron 或工作流工具排期,触发一次就退出,不常驻。
- 注意凭据来源:headless 只查启动环境、调用目录的
.env与~/.dsh/.env,调度器的环境变量要显式注入。 - 日志按任务分开落盘,别再依赖会话历史当执行记录。
- 这种方式下「改一条任务」就是改一条调度项,不会牵动任何对话。
- 代价是你要自己维护调度、凭据与日志,等于把编排责任接了过来。
DeepSeek插件 为什么不能直接「指定投递目标」
任务记录里只有创建它的来源会话,没有目标会话字段;所以「任务 A 投递到会话 B」在当前实现里做不到。
- 看 README 措辞:任务被描述为「follow-up messages in their original Session」。
- 看机制:到期时 Host 恢复的是那个原始会话。
- 看数据结构:没有可以填目标会话的字段。
- 所以任何「先把任务建在临时会话里、再改投递目标」的做法都不成立。
- 真要一等公民的独立运行体,得等上游把任务与会话解耦。
DeepSeek Harness 四条路线的取舍
按「改动成本 / 隔离程度 / 维护负担」三项一起看,别只看隔离程度。
| 路线 | 改动成本 | 隔离程度 | 维护负担 |
|---|---|---|---|
| 一任务一会话 | 无 | 中 | 会话变多 |
| 按模型再拆 | 无 | 中高 | 需要分组 |
| 社区插件 | 中 | 视实现 | 依赖第三方 |
| 外置调度 + headless | 高 | 高 | 自己维护调度 |
如果只是「改任务时别翻半天历史」,第一条就够;如果要求「每次执行都是干净上下文」,只有第四条能完全满足。
已有任务怎么迁移
别一次性重建 81 条任务,先迁一小批验证语义,再批量搬。
- 选三条互不相关的任务,在专用会话里重建。
- 等它们至少各触发一次,确认投递到的是新会话而不是原对话。
- 确认无误后,把原对话里的旧任务停用,不要直接删,留作对照。
- 观察一周没有异常,再按分组批量迁移其余任务。
- 全部迁完后,清理原对话里的任务记录与历史噪音。
注意事项
- 别在主对话里建任务。一旦建了,后续投递都会回到这个会话来。
- 别把不同模型的任务混在一组。模型跟随会话,混组只能全局妥协。
- 别忽略冷会话恢复的成本。任务越多、会话越冷,恢复开销越明显。
- 别把插件当官方能力。报告者列出的候选未经社区验证,先用小规模试跑。
- 记录任务归属。哪条任务属于哪个会话,最好在任务名里写清楚。
如果你的任务已经全建在主对话里,不用重建历史——新建专用会话,把后续任务建在新会话,旧任务按需迁移即可。相关排查见 DeepSeek Harness 模型不创建提醒?schedule 工具缺失与 preset 限制。
常见问题
因为 DeepSeek Harness 的定时任务绑在创建它的 Session 上。schedule README 的原话是按「follow-up messages in their original Session」投递,到期时 Host 把那个冷会话恢复起来再交付。81 条挤在一起,是因为它们当初都创建在同一个会话。
不能,DeepSeek Harness 的任务记录里没有目标会话字段,只有创建时的来源会话,所以现在做不到跨会话投递。
倒过来用:在 DeepSeek Harness 里先新建一个专用会话,再在那个会话里创建这一族任务。投递、模型、preset 都跟着那个会话走,主对话不受影响;需要几组就建几个会话。
报告者列出了几个候选(如按「每次执行独立 Session」描述的实现),但社区回复没有针对 DeepSeek Harness 逐一点评它们,也没有在 81 条量级下验证。选之前请自己小规模试跑,并确认与当前 DSH 版本的兼容性。
可行,DeepSeek Harness 的定时任务也可以用外置调度加 headless 绕开会话绑定,代价是你要自己维护调度与凭据。用系统 cron 或工作流工具触发一次 headless 运行,每次都是独立进程,天然不共享会话;注意 headless 的凭据来源只有启动环境与 .env。
相关术语
- schedule 任务
- schedule 任务是 DeepSeek Harness 的定时任务记录,到期时以 follow-up 消息的形式投递回它被创建的那个会话。记录里不保存目标会话字段。— https://github.com/deepseek-ai/deepseek-harness/discussions/10911
- 冷会话恢复
- 冷会话恢复是任务到期时 Host 把已经不在内存里的来源会话重新加载起来、再把提示词交付进去的机制,也是任务与会话强绑定的直接体现。— https://github.com/deepseek-ai/deepseek-harness/discussions/10911
- 专用会话
- 专用会话是为了承载某一族定时任务而单独创建的会话。它的投递目标、模型与 preset 都随会话走,由此实现任务之间的软隔离。— https://github.com/deepseek-ai/deepseek-harness/discussions/10911
- headless
- DeepSeek Harness 的无界面运行模式,每次调用是独立进程,不依附任何已有会话。它常被用作外置调度的执行端。— https://github.com/deepseek-ai/deepseek-harness/discussions/10911
来源
- #10911 — 标求助:DSH 定时任务如何实现独立会话模式?81 个任务挤在一个对话里· deepseek-ai(GitHub Discussions)
- deepseek-ai/deepseek-harness(schedule README)· GitHub