前言¶
用 DeepSeek Harness(dsh)跑长任务时,常见矛盾是:到点关机会误杀仍在推进的工作,一直开着又会在任务挂掉或没人再看时白白占资源。dsh 内置的 dsh-schedule 适合把提醒投回会话、由模型决定下一步,但在模型已不可用或额度耗尽时,它帮不上「直接收资源」这一环。下面介绍社区插件 dsh-deadman:布防后定期问「还有人在推进吗」,无人报活则执行你指定的 shell 命令,不经模型决策。
这是什么¶
dsh-deadman 是 dsh 的 deadman switch(死手开关) 插件,维护者为 0gl20shk0sbt36,在 SkillHub 目录中归类为工作流。一句话:布防后按周期巡检是否仍有 agent 在推进;若没有(且满足放行条件),就执行布防时写死的命令——例如关机、停实例、发本地脚本。
与内置自动化对比如下(摘自官方 README):
dsh 内置 dsh-schedule |
dsh-deadman | |
|---|---|---|
| 到点做什么 | 消息投回收件箱,由模型决定 | 直接执行 shell 命令 |
| 阻止机制 | 无 | 报活闸门:有人推进则顺延 |
| 典型场景 | 日程提醒、叫醒会话 | 无人值守止损:活儿干完或挂掉后自动收资源 |
两者互补;死手开关针对的是「资源该收回、模型未必还能处理消息」的时刻。
核心功能¶
模型工具¶
| 工具 | 作用 |
|---|---|
deadman_arm |
布防:参数含 name、command、after_minutes、interval_minutes、description。首次巡检在 after_minutes 后;被报活则按 interval_minutes 重排;执行成功一次即收工 |
deadman_hold |
报活:「我还在干活」,跳过本轮。任何会话都能报活(fail-safe) |
deadman_disarm |
撤防。仅布防会话或其直接子代理默认可用;其他会话需 force=true,并记入日志 |
任务名在进程内全局唯一;同名布防会被拒绝并提示占用会话。
斜杠命令:/deadman(本会话)、/deadman all(全部会话)、/deadman cancel <name>。
触发与放行顺序¶
- 解析属主会话:必要时
resume后再投递,避免提示丢失。 - 向 agent 投递巡检询问(要求不打扰用户、不请求确认,只能报活或沉默)。
- 按活跃度循环:任一 agent 自上次巡检有
session.seq推进则继续等;全部无推进则进入宽限;若有待用户回答的提问则单独计时;总时长不超过maxHoldMinutes(到顶 fail-open 放行)。 - 放行则执行命令,成功后任务自动结束;被报活则重排下一周期。
报活方式¶
- 调用
deadman_hold工具; - 在工作目录创建
.deadman-hold-<name>(子代理无该工具时可用); - 在插件数据目录
hold/下以任务名建文件(外部脚本或人工)。
多会话与并发¶
- 每个任务绑定属主会话,巡检询问主要投给属主;默认
progressScope: global,整机仍有推进则所有看门狗顺延;若只看属主一伙,设progressScope: owner。 - 多个看门狗同时到期可并发执行各自命令;需串行时配置
serializeCommands。
安装与启用¶
要求 dsh 0.2.0-rc.2(peerDependencies 精确对齐;版本不匹配时 dsh 会拒绝安装)。
# 本地路径
dsh plugin --profile web add /path/to/dsh-deadman
# 或从 GitHub
dsh plugin --profile web add github:OWNER/dsh-deadman
将 OWNER 换为仓库所有者(如 0gl20shk0sbt36)。Web / 桌面端在插件页启用 dsh-deadman;CLI 卸载:dsh plugin --profile <name> remove dsh-deadman。
建议装在长期运行的 profile(如 web):调度器活在 dsh 进程内,一次性 headless 进程退出后无人巡检。从 GitHub 安装时 pnpm 会按依赖自动解析;本地路径安装需在插件目录先执行 pnpm install 生成 node_modules。
配置¶
在 profile 的 cordis.patch.yml 中覆盖 bundle 默认值,例如:
- id: deadman
config:
holdWindowSeconds: 60
| 键 | 默认 | 说明 |
|---|---|---|
holdWindowSeconds |
60 |
全部 agent 无推进后再等多久执行 |
checkIntervalSeconds |
20 |
巡检周期 |
maxHoldMinutes |
30 |
从触发起的总上限,到顶一律放行 |
questionBlockSeconds |
600 |
待用户提问卡住时的最长等待 |
onUndeliverable |
execute |
属主会话投递不到时:execute / skip |
progressScope |
global |
global 整机 / owner 仅属主及直接子代理 |
serializeCommands |
false |
多条动作命令是否串行 |
commandTimeoutSeconds |
300 |
单条命令超时 |
dataDir |
$DSH_HOME/plugins/dsh-deadman |
任务表 tasks.json 与 hold/ |
任务持久化在 tasks.json,重启不丢;逾期任务会在下次巡检立刻处理。
典型用法¶
- 在无人值守场景(夜间编译、训练、批量渲染、云实例跑批)中,由 agent 调用
deadman_arm,指定例如若干分钟后首次检查、周期、以及「无人推进时」执行的命令(如关机脚本)。 - 任务仍在推进时,主代理或子代理定期
deadman_hold,或依赖全局 seq 推进自动顺延。 - 任务正常结束且不再需要看门狗时,可在布防会话用
deadman_disarm或/deadman cancel <name>;若命令已成功执行一次,任务也会自动收工。
README 未给出固定示例命令,实际 command 应为你本机已审计、可信任的 shell 片段。
适用场景与注意¶
适合:需要「没人再推进就自动执行止损动作」的长驻 dsh 实例;与 dsh-schedule 分工明确——前者提醒模型,后者直接动 shell。
务必知晓:
- 动作命令完全由布防方指定,插件以当前 dsh 进程权限运行;安装前请阅读源码与 MIT 许可,只调度你信任的命令。
- 默认 fail-open:无人报活即执行,这是死手语义;关键动作应设合理周期与宽限。
- 单写者:
tasks.json不宜多进程同时布防;插件按单实例长期 profile 设计。 progressScope: owner不含更深层孙代理;提问阻塞依赖宿主userQuestions投影,无投影时该闸门不生效。- 插件不联网、不收集数据;数据仅写本机
dataDir。
DSH 生态强调「一切皆插件」;SkillHub 目录 为社区站点,与 DeepSeek / 幻方无官方从属关系。
结尾¶
dsh-deadman 把「还有人在干活吗」变成可配置的周期巡检与报活闸门,在无人值守长任务里用 shell 命令收资源,而不依赖模型在线。目录页:https://www.skillhub.cn/plugins/0gl20shk0sbt36/dsh-deadman;源码与完整说明:https://github.com/0gl20shk0sbt36/dsh-deadman。