dsh-run-guard:拦截推理死循环、防止想完就停的 DSH 运行节奏守护插件

前言

DSH(DeepSeek Harness)的理念是「一切皆插件」,但在做智能体开发时,多数扩展都在给 Agent 加能力,很少有人在管运行节奏。DeepSeek V4 Flash 配合 reasoningEffort: max 跑长任务时,会出现两种典型异常:

  1. 想完就停:模型输出完整思考后直接正常结束 turn,没有正文、没有工具调用,任务还挂着——表现为「不干活」。
  2. 推理死循环:推理进入重复空转,持续数分钟不停,实测单 step 全量落盘可达 132 万字符——表现为「停不下来」。

常见的应对方式是人工盯守:发现空转就手动停止,发现停摆就手动催促,对长任务来说既耗时也不稳定。dsh-run-guard 在插件层把这两端补齐。下面介绍它的定位、工作方式、安装配置和注意事项。

这是什么

dsh-run-guard 是一个 DeepSeek Harness 插件,定位为 Agent 运行节奏守护,由 Dis2017 维护,MIT 许可证(© 2026 Dis2017)。一句话概括:guard(刹车)拦截推理死循环,continue(油门)防止想完就停不干活。

刹车和油门共用一套状态感知,互不干扰:guard 中断的 turn 以 error 结束,continue 只在 completed 时触发,不会误推;反过来,continue 推进的新 turn 若再次死循环,guard 会立刻拦截。

核心功能

guard(刹车):拦截推理死循环

  • 监听 llm/stream 流,做滑动窗口重复率检测,另设硬性上限双保险。
  • 死循环在 1~2 秒内被中断,而不是空转数分钟。
  • 中断后自动重试,默认每 turn 2 次(可配);仍失败才停止,并给出中文原因提示。

recovery(恢复):上游瞬时失败自动重试

PI_AI_ERROR 等瞬时上游失败,即使不在 llm-retry 默认重试集合里,也会被自动重试;错误码白名单可扩展,与 guard 共用每 turn 重试上限。

continue(油门):防止提前停摆

turn 正常结束后自动续跑,分两种情况:

  • 有未完成 todo:注入当前状态引导续跑,连续无产出续跑有计数上限(continue.maxAutoFollowups,默认 3)。
  • 无 todo 但模型想完就停(最后只有推理、无正文无工具调用):注入简洁提示续跑,无上限。

pause_work:随时人工暂停

模型可随时调用 pause_work 工具主动暂停;一旦标记,guard 和 continue 两路都不会再自动继续。

扩展点与设置页

插件通过四个扩展点接入宿主:llm/stream(waterfall)、session/eventsystemPrompt.context、`tools.register。同时提供设置页(设置 → Run guard),可编辑全部配置项,保存后落盘、重启生效。

安装与启用

安装使用 GitHub 发布版:

dsh plugin --profile web add "github:Dis2017/dsh-run-guard#v0.1.16"

命令中的 #v0.1.16 对应仓库的发布 tag,升级时替换为新 tag 即可。执行后先做验证,再做日常使用:

  1. 重启 GUI。
  2. 打开 设置 → 插件 → Plugin list,确认 dsh-run-guard 为 Mounted / Enabled。
  3. 打开 设置 → Run guard,检查或修改配置。

经过上面的步骤,插件即进入工作状态:死循环会在 1~2 秒内被中断并自动重试;「想完就停」后会自动收到续跑提示。

典型用法

开发模式

调试时不必反复打包发布,在 ~/.dsh/profiles/web/cordis.patch.yml 以绝对路径挂载 lib/index.js,改代码即时生效:

# ~/.dsh/profiles/web/cordis.patch.yml
- insert:
    - id: run-guard
      name: /绝对/路径/dsh-run-guard/lib/index.js?v=1

测试与升级

pnpm install
pnpm test

测试共 54 个单元/集成测试。仓库打新 tag 后,重新执行 dsh plugin --profile web add ...,或先 remove 再 add,即可完成升级。

主要配置项

配置项 默认值 说明
enabled true 总开关
guard.enabled true 死循环拦截开关
guard.windowChars 2000 滑动窗口大小(字符)
guard.substrLen 32 重复检测子串长度
guard.repeatRatio 0.7 窗口重复率阈值
guard.checkEvery 50 每 N 块检测一次(降频)
guard.maxBlocks 10000 硬闸:单次调用推理块数上限
guard.maxChars 500000 硬闸:单次调用推理字符数上限
guard.maxGuardRetries 2 中断后每 turn 自动重试次数上限
guard.autoRetryErrors ["PI_AI_ERROR"] 额外自动重试的错误码白名单
continue.enabled true 自动继续开关
continue.maxAutoFollowups 3 有 todo 场景连续无产出续跑上限

以上配置项均可在设置页编辑,保存后落盘、重启生效。

适用场景与注意

适合用 DeepSeek V4 Flash 配 reasoningEffort: max 跑长任务、遇到过想完就停或推理死循环的 DSH 用户;如果希望这类异常在插件层自动兜底,而不是靠人工盯守,这个插件值得试。

使用前有几点需要注意:

  1. 权限与审查:插件以当前 dsh 进程的权限运行,安装前应检查源码与许可证(MIT)。
  2. 依赖约定:插件的 @deepseek-ai/* 依赖必须放 peerDependencies(由宿主提供单例);放 dependencies 会在 profile 顶层产生第二份副本,运行时报 Cannot read properties of undefined (reading 'prepare')。遇到该错误,把依赖移回 peerDependencies、清理 profile 顶层副本后重启。
  3. 历史会话:已落盘过死循环推理的历史会话(单 step 可达 132 万字符)打开可能卡死,需清理数据或归档;插件只保证之后不再产生新的。
  4. 续跑边界:有 todo 场景的连续无产出续跑默认上限 3 次;无 todo 的想完就停续跑无上限;模型调用过 pause_work 后两路都不续跑。

结尾

dsh-run-guard 用一套状态感知同时管住刹车和油门:guard 保证 Agent 不会无限干活,continue 保证它不会不干活,对长任务来说是一个小而实用的兜底件。

  • 社区插件目录页:https://www.skillhub.cn/plugins/Dis2017/dsh-run-guard (独立站点,与 DeepSeek / 幻方无官方从属关系)
  • GitHub 仓库:https://github.com/Dis2017/dsh-run-guard
羽毛球分组比赛记分
小程序二维码

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

小夜