前言¶
用 DSH 做智能体开发,有一类需求很常见:每天凌晨跑一遍测试、定时巡检某个项目、周期性整理任务。这些工作的共同点是周期固定、prompt 能写清楚、跑完只需要一段结论。DSH 的理念是一切皆插件,但调度这件事本身没有现成方案,靠系统 crontab 拼 shell 脚本,又会丢掉智能体会话的日志和审计能力。
下面介绍 dsh-routines,它把「定时运行一个 prompt」做成了 DSH 里的一等公民。
这是什么¶
dsh-routines(npm 包名 @dsh-routines/bundle)由 Jesse-njx 维护,MIT 许可,当前版本 0.1.0,在社区目录里归类为「工作流」类插件。
一句话定位:为 DSH 提供定时智能体(scheduled agents)——按 cron 运行一段 prompt,把摘要投递到你已经在看的地方(file 摘要、chatnode 投递),并保证无人值守安全。
一个 routine = 命名 prompt + schedule + 投递渠道,存为纯 YAML 文件:人类可 diff、可 git 提交。调度器把每次到期的运行经 headless runner 以独立 one-shot 会话启动,完整会话日志就是完整审计记录,之后还能被 dsh-replay 重放。摘要的生成规则:最后一条 assistant 消息较短时直接采用,否则对会话日志做一次性 summarizer 调用。
核心能力¶
例程文件与热重载¶
例程放在两个被监视的目录里,改动即热重载;非法文件只报告,不会让存储崩溃:
| 目录 | 作用域 |
|---|---|
<cwd>/.dsh/routines/*.yaml |
项目级例程,可按名称覆盖全局 |
~/.dsh/routines/*.yaml |
全局例程 |
主要字段与默认值:
| 字段 | 默认值 | 说明 |
|---|---|---|
name |
必填 | [a-z0-9][a-z0-9-]*,不超过 64 字符 |
schedule |
必填 | "0 2 * * *"、@daily、every 4h 等 |
timezone |
UTC |
用 IANA 时区做调度计算,不用宿主机时区 |
prompt |
必填 | headless 运行执行的任务 |
cwd |
当前目录 | 运行的工作目录,也是摘要落地处 |
profile |
headless |
运行启动的 DSH profile |
overlap |
skip |
skip / queue / cancel-previous |
timeoutMin |
45 |
硬超时(分钟) |
deliver |
[{type: file}] |
摘要投递渠道 |
调度语法¶
cron 为 5 字段,支持 *、步进(*/15)、范围(9-17)、列表(0,30)、? 以及月/日名称;当「日」和「星期」同时受限时,任一匹配即触发(Vixie cron 语义)。也接受 @daily、@hourly、@weekly、@monthly、@yearly、every 4h、every 30m 这类简写。
overlap 决定到期但上一次还没跑完时的行为,默认 skip(不在同一个仓库上叠两个智能体);timeoutMin 是硬停止,默认 45 分钟。
摘要投递¶
- file(始终开启):运行记录 + 摘要 markdown 写入
.dsh/routines/runs/<runId>.json,旁边有可读的<runId>.md。 - chatnode(可选):摘要经
ctx.chatnode服务的send(input: { text, title? })发送;没有安装会话节点时记为not-installed,运行照常完成。未来暴露该服务的@dsh-cowork/chatnode-wechat可以自动点亮这条通道。
CLI¶
在承载 profile 里使用 dsh --profile ops routines <command>:
| 命令 | 作用 |
|---|---|
list |
列出例程的 schedule、暂停状态、下次运行时间 |
run <name> |
手动立即触发,打印摘要后退出 |
pause <name> / resume <name> |
暂停 / 恢复调度 |
logs <name> [--limit n] |
最近运行记录:状态、时长、摘要、session id |
无人值守安全默认¶
定时运行的智能体没人盯着,所以每个运行子进程都会被 patch:
- 强制审批策略
never:自动拒绝任何会弹提示的请求,被拒项记入运行记录的denied并出现在摘要里;sandbox 模式沿用 profile 继承值(通常为workspace-write)。 - 禁止嵌套调度:run overlay 会在运行 profile 内部关掉调度器。
- 投递、摘要、启动失败只记入运行记录,不向外抛出。
错过的运行(比如电脑休眠):唤醒时最多补跑一次,不做积压重放。
组成结构¶
一个 bundle,三个插件加一个 run driver,均可按子路径安装:
| 模块 | 职责 |
|---|---|
@dsh-routines/bundle/store |
监视 .dsh/routines/*.yaml(项目 + 全局),校验、热重载、持有持久状态 |
@dsh-routines/bundle/scheduler |
把到期例程注册到 ctx.jobs(kind routine),负责 overlap、错过运行与超时语义 |
@dsh-routines/bundle/cli |
dsh routines ... 命令行 |
@dsh-routines/bundle/run |
子进程侧驱动,经生成的 --patch overlay 注入每个 one-shot 运行,负责写运行记录和摘要 |
安装与启用¶
npm 包 @dsh-routines/bundle 在 README 中标注为 when published(发布后可用),当前可直接从 GitHub 安装:
# 1. 创建承载调度器与 CLI 的 profile,并装入本 bundle
dsh plugin --profile ops add github:Jesse-njx/dsh-routines
# npm 发布后也可:dsh plugin --profile ops add @dsh-routines/bundle
# 2. 保持进程存活,调度才会触发(守护模式,Ctrl-C 停止)
dsh --profile ops
dsh --profile ops 不带内层参数就是预期的守护形态:CLI 保持静默,调度器接管进程生命周期。调度器在 bundle 安装进的 profile 内运行,所以也可以装入主 web profile,web 应用运行期间例程照常触发:
dsh plugin --profile web add @dsh-routines/bundle
环境要求 node >= 20;peerDependencies 依赖 @deepseek-ai/cordis、@deepseek-ai/cordis-plugin-timer、dsh-agent、dsh-cmdline、dsh-jobs、dsh-llm 等 DSH 相关包。例程运行默认启动 DSH 自带的 headless profile,无需额外设置;需要别的 profile 时在例程里设 profile: <name>,该 profile 须支持 one-shot(包含 headless bundle,或同样安装本 bundle——无论哪种,运行 overlay 都会禁用嵌套调度)。
调度簿记(暂停集合、上次运行锚点)存放在 <cwd>/.dsh/routines/state.json。
典型用法:夜间测试分诊¶
README 给出的示例例程:凌晨 2 点跑测试套件,若有失败则诊断首要失败并在分支上起草修复,最后留一份不超过 10 行的总结。
# ~/work/projectx/.dsh/routines/nightly-tests.yaml
name: nightly-tests
schedule: "0 2 * * *" # 5 字段 cron;也接受 "@daily"、"every 4h"
timezone: Asia/Shanghai # 显式声明,不静默使用宿主机时区
prompt: |
Run the test suite. If anything fails, diagnose the top failure
and draft a fix on a branch. Summarize in <10 lines.
cwd: ~/work/projectx
profile: headless # 运行使用的 profile
overlap: skip # skip | queue | cancel-previous
timeoutMin: 45
deliver:
- type: file # 始终开启:摘要写入 .dsh/routines/runs/
- type: chatnode # 可选:已安装的会话节点
把这个 YAML 放进被监视目录即可,改动会热重载。先确认例程已被识别:
$ dsh --profile ops routines list
nightly-tests active 0 2 * * * tz=Asia/Shanghai next=2026-08-15T02:00:00.000Z
第二天早上查看最近运行记录:
$ dsh --profile ops routines logs nightly-tests --limit 3
[completed] 2026-08-14T18:00:01.000Z 41213 ms session=session-2f7d…
tests: 3 failed of 412; top failure: flaky wait in auth.spec.ts — drafted fix on branch fix/auth-wait
在信任一条 schedule 之前,先用 dsh --profile ops routines run nightly-tests 手动触发一次验证。
适用场景与注意¶
适合的场景:周期固定、一段 prompt 能说清楚、结果只要一份摘要的任务——夜间测试、定时巡检、周期性整理。前提是承载进程在触发时刻存活,错过运行只补跑一次,不做积压重放。
几点注意:
- 插件以当前 dsh 进程的权限运行,安装前应检查源码与许可证。本项目 MIT 许可,源码公开在 GitHub。
- 无人值守运行强制
approval: never,任何需要确认的操作都会被自动拒绝并记入denied、出现在摘要中。写 prompt 时要把这一点考虑进去。 - chatnode 是软依赖:需要安装暴露
send(input: { text, title? })服务的会话节点;没有安装也不影响 file 投递。 - npm 渠道是否已发布无法确认,当前以 GitHub 安装方式为准。
小结¶
dsh-routines 把「定时跑 prompt、拿到摘要」收进一个 DSH bundle:例程是可 git 提交的 YAML,运行是独立 one-shot 会话、日志可审计,投递落在文件或已安装的会话节点上。如果你在 DSH 里有周期性任务的需求,可以从这个 bundle 入手。
- GitHub 仓库:https://github.com/Jesse-njx/dsh-routines
- 社区目录页:https://www.skillhub.cn/plugins/Jesse-njx/dsh-routines
目录为社区独立维护的站点,与 DeepSeek / 幻方无官方从属关系。