使用dsh-sentinel在DeepSeek Harness中实现条件驱动唤醒

前言

DeepSeek Harness(dsh)是 DeepSeek 开源的智能体运行时,核心理念是「一切皆插件」:模型、工具、会话、调度和界面都可以用插件增删。智能体实际干活时,经常要等一件事发生——构建产物落盘、HTTP 接口恢复、某个进程起来或挂掉、CI 推一条结果过来。如果让模型自己轮询,既耗 token,关了会话就断了;如果人肉盯着,又失去了把循环交给运行时的意义。

社区插件目录 DeepSeek Harness 插件库 收录了面向这类等待场景的插件 dsh-sentinel。该目录是独立的社区站点,与 DeepSeek / 幻方没有官方从属关系,条目指向维护者仓库,安装前需要自己核对源码。本文按目录页、GitHub 仓库 README 与源码交叉核实后,介绍它是什么、怎么装、怎么用。

本文核实日期为 2026-08-18。仓库当前发布版本为 v0.11.0(2026-08-17)。

这是什么

dsh-sentinel 是一款由 fuhefei 维护的 DeepSeek Harness 插件。社区目录把它分在「界面增强」,因为它在 Web UI 上提供 dock 卡片、侧边栏分支和全局 dashboard;能力本身是条件驱动唤醒:智能体注册一条持久监视(watch),之后可以休眠甚至关掉会话,条件成立时由哨兵通过官方 followup 通道把它叫醒,必要时先复活休眠会话里的 agent。

许可证为 BSD-3-Clause,主要语言是 TypeScript。截至本文核实,GitHub 仓库 fuhefei/dsh-sentinel 的 star 数为 11;目录页当时显示为 6,星标以仓库页面为准。npm 上的包名是 dsh-sentinel,运行时无第三方依赖。

它要解决的问题很具体:把「等到某件事发生再继续」从对话循环里拿出去,交给与 server 同生命周期的值守进程,并且每一次订阅、每一次触发都写成用户可见的会话事件。

核心能力

仓库 README 把传感器分成六种。目录页简介写的是文件 / 命令 / HTTP / 进程 / Webhook,仓库还多了一种 port(TCP 可达性),下面以仓库为准。

1、file:对路径做快照,并用 inotify 推送加速,快照变化时触发,延迟可以到亚秒级。
2、command:按间隔执行一条只读 shell,输出或退出码变化时触发。
3、http:按间隔探测 URL,状态码或响应体变化时触发。
4、process:用 pgrep -f 按模式探测,匹配集合变化时触发。
5、port:对 [host:]port 做 TCP 连接,可达性在 open / closed / timeout 之间变化时触发。
6、webhook:纯推送。注册后会得到一条 hook URL,对它发任意 POST 即可唤醒。

pattern 时,探测类传感器在该正则的「不匹配 → 匹配」边沿触发,webhook 只接受匹配的载荷;不带 pattern 时,探测类传感器对基线之后的任何变化触发,webhook 对任意 POST 触发。首次探测的语义也写在仓库里:不带 pattern 的 watch 把第一次观测当成基线(不触发);带 pattern 且目标已经匹配时,第一次探测就会触发。

值守不在单次对话里。Node 侧把插件自己的 sidecar 日志($DSH_HOME/sentinel.jsonl)折叠成活跃订阅,按共享心跳(默认 5 秒)探测;命中后走官方 followup 投递。订阅能扛住进程重启;server 停机期间变真的条件,会在下一次探测时补触发。投递是 at-least-once:崩溃前已记录但没送出的触发,重启后从 delivered 水位线重新入队。

值守是常驻进程的事,通常是 dsh web。一次性 headless 运行也能加载插件、创建 / 列出 / 取消 watch,但进程退出后没人探测;等下一个常驻进程起来,这些 watch 会自动恢复。每个 $DSH_HOME 只有一个值守 owner,靠租约文件 sentinel.lease 协调:第一个进程负责探测和投递,同一 home 上的第二个 dsh 进程保持被动,owner 死后在一个租约 TTL 内接管。

浏览器侧有三块界面:
- composer 上方的 dock 卡片(conversation.input.dock),列出本会话的活跃 watch:传感器、目标、实时探测状态、触发预算、下次探测倒计时;展开可以看到最近触发历史。没有 watch 时不渲染。
- 全局 dashboard:跨所有会话的 watch 表,路径是 GET /plugins/dsh-sentinel/dashboard
- 侧边栏会话行下的分支(折叠时是计数,展开后列出该会话的 watch)。dock 和 dashboard 在原版 host 上就能用;侧边栏分支依赖官方树尚未声明的扩展洞,需要给 DSH 源码打上仓库附带的 patches/session-row-holes.patch 并重建 ui-workspace。这个补丁和 dsh-subagent-tree 对同名洞的补丁语义不同,不要同时打。

同一 profile 里如果装了 dsh-better-sidebar,sentinel 会把全局 watch 表注册成侧边栏 tab(dsh-sentinel:watches);没装则静默跳过。和 dsh-notification 一起用时,仓库说明是零集成代码:哨兵叫醒 agent,agent 干完这一轮,回合结束触发桌面通知。

面向模型的工具只有三个:sentinel_watch 注册,sentinel_list 列出本会话活跃 watch 及实时探测状态,sentinel_cancel 按 id 取消。

安装与启用

社区目录页给出的安装命令如下,在 DeepSeek Harness 终端中运行即可:

dsh plugin add github:fuhefei/dsh-sentinel

如需可复现安装,目录页建议固定 commit 哈希:

dsh plugin add github:fuhefei/dsh-sentinel#commit

把上面的 commit 换成实际哈希。仓库 README 还提供了两条写法,一条走 npm 包名,一条把 git 源钉在当前发布标签 v0.11.0(构建产物直接提交在仓库里,git 源安装不需要再跑构建):

dsh plugin --profile web add dsh-sentinel
dsh plugin --profile web add "github:fuhefei/dsh-sentinel#v0.11.0"

v0.11.0 的发行说明写明:包名已从 @dsh-external/dsh-sentinel 改为无 scope 的 dsh-sentinel。如果以前按旧名字装过,需要把 profile 里的旧行换成 dsh-sentinel;watch 本身写在 sidecar 日志里,不跟安装包走,切换后订阅还在。

部署相关的旋钮在插件 config schema 里,可在 profile 的 cordis.patch.yml 里对 bundle 行覆盖。仓库给出的默认值如下:

- id: dsh-sentinel
  name: dsh-sentinel
  config:
    heartbeatMs: 5000
    probeConcurrency: 8
    maxSubscriptionsPerSession: 16
    maxPendingWakeups: 8
    defaultIntervalSeconds: 30
    defaultCooldownSeconds: 60
    dutyLeaseTtlMs: 30000
    notifyWebhookUrl: ''

非法值会在插件加载时按 schema 报错,而不是运行时 silently 乱来。notifyWebhookUrl 非空时,每次触发会额外 JSON POST 到该地址(字段包括 plugineventsessionIdidkindtargetnotefireNumbermaxFiressummaryafter),可以接到飞书 / 企微 / Slack 或任意接收端。这条外发是 at-most-once:POST 失败只在日志里 warn,不阻塞 harness 内的唤醒。

典型用法

安装完成后,在会话里直接告诉智能体要监视什么即可,不必自己写轮询循环。sentinel_watch 的参数以仓库源码里的工具定义为准:kindtargetnote 必填;可选 patterninterval_secondsmax_firescooldown_secondsexpires_in_seconds

kindtarget 的对应关系如下:

  • file:绝对路径
  • command:只读 shell 单行
  • http:URL
  • process:交给 pgrep -f 的模式
  • port[host:]port,端口范围 1–65535
  • webhook:给预期调用方起的短标签,真正用来推送的是返回的 hook URL

note 会随每次唤醒原样送达,相当于留给「被叫醒之后的自己」的便签,不能为空。max_fires 默认 1,也就是一次性;需要反复触发时再显式加大。cooldown_seconds 默认 60。探测间隔默认 30 秒;webhook 忽略间隔,file 会由文件系统事件加速。源码会把间隔夹到 5–86400 秒(README 工具一节曾写 1–3600 秒,以源码为准)。pattern 使用 JavaScript 正则(m 标志);占位状态(文件不存在、URL 不可达、没有匹配进程)不会被 pattern 命中,避免「文件还没出现就用尽触发额度」。

注册之后可以用 sentinel_list 查看本会话的活跃 watch 和最近探测状态,用 sentinel_cancel 按 id 取消,id 形如 watch-3。Web UI 的 dock、dashboard 表和各行上的 ✕ 也会走手动取消接口 POST /plugins/dsh-sentinel/cancel?sessionId=…&id=watch-N。host 没有 session-deleted 事件,会话删掉后孤儿 watch 会继续探测,直到人手取消,所以这个开关是最后的兜底。

webhook 场景下,工具会返回完整的推送地址:

POST /plugins/dsh-sentinel/hook?id=watch-N&s=

s 是会话限定符,避免两个会话都叫 watch-1 时 hook 撞车。不带 s 的旧 URL 仍可用,会解析到第一条匹配的 webhook watch。仓库建议把这条 curl 塞进 CI 任务、git hook 或另一台机器的脚本。完整 URL 按密钥对待:拿到它的人就可以叫醒对应会话里的 agent。

只读状态接口是 GET /plugins/dsh-sentinel/state?sessionId=…,省略 sessionId 返回所有会话,供 dock 和侧边栏轮询。

适用场景与注意事项

更适合已经在跑 dsh web、需要把「等到条件成立再继续」交给运行时的人。典型方向包括:等某个文件或构建产物出现、等 HTTP 健康检查从失败变为成功、等本机进程或端口状态翻转、以及让 CI / git hook 从外部推一把把 agent 叫醒。它不是通用定时任务框架,也不替代通知插件本身。

使用前有几条边界需要看清楚。

1、插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前应检查源代码仓库和许可证。
2、探测和投递依赖长期运行的 dsh 进程。只跑一次 headless 就把进程退出,watch 会写进 sidecar,但当时不会有人探测。
3、command 传感器会在每次探测时执行配置的 shell 行,信任边界和 host 自带的 shell 工具相同,不要把不可信命令写进去。
4、webhook URL 视为密钥;浏览器标记的跨站请求和 DNS rebinding 尝试会被四条路由以 403 拒绝,curl 和 CI 这类无头客户端不受影响。
5、每会话活跃订阅上限默认 16,每会话排队唤醒上限默认 8,超出丢最旧的。dashboard 会显示被丢掉的排队唤醒。
6、侧边栏分支不是开箱即用,需要给 DSH 源码打补丁;dock 和 dashboard 不依赖这块。
7、社区目录不是官方应用商店。本插件是社区开源项目,不代表 DeepSeek 官方背书。

小结

dsh-sentinel 把条件监视做成可持久、可看见、可取消的值守:智能体注册完就可以去睡觉,文件、命令、HTTP、进程、端口或 Webhook 条件成立时再被叫醒。界面上的 dock 和 dashboard 让订阅不再是后台黑盒。安装、源码和许可证以目录页与仓库为准,装之前自己看过再决定。

目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-sentinel/

GitHub:https://github.com/fuhefei/dsh-sentinel

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

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

小夜