dsh-deadman:无人值守时的死手开关

前言

用 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>。

触发与放行顺序

  1. 解析属主会话:必要时 resume 后再投递,避免提示丢失。
  2. 向 agent 投递巡检询问(要求不打扰用户、不请求确认,只能报活或沉默)。
  3. 按活跃度循环:任一 agent 自上次巡检有 session.seq 推进则继续等;全部无推进则进入宽限;若有待用户回答的提问则单独计时;总时长不超过 maxHoldMinutes(到顶 fail-open 放行)。
  4. 放行则执行命令,成功后任务自动结束;被报活则重排下一周期。

报活方式

  1. 调用 deadman_hold 工具;
  2. 在工作目录创建 .deadman-hold-<name>(子代理无该工具时可用);
  3. 在插件数据目录 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,重启不丢;逾期任务会在下次巡检立刻处理。

典型用法

  1. 在无人值守场景(夜间编译、训练、批量渲染、云实例跑批)中,由 agent 调用 deadman_arm,指定例如若干分钟后首次检查、周期、以及「无人推进时」执行的命令(如关机脚本)。
  2. 任务仍在推进时,主代理或子代理定期 deadman_hold,或依赖全局 seq 推进自动顺延。
  3. 任务正常结束且不再需要看门狗时,可在布防会话用 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。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye