dsh-auto-continue:在回合不该结束时把它重新打开

前言

在 DeepSeek Harness(DSH)里跑智能体时,常见一种挫败:模型回复在「接下来我要……」或半句话处戛然而止,界面却显示本轮已正常结束。网关静默切断时,客户端往往仍收到合法的 stopReason: "stop"——没有错误、没有重试、没有异常,DSH 主循环因此认为 turn 可以关闭,用户只能手动输入「继续」。

这类问题靠「更好的错误处理」往往解决不了,因为没有错误。维护者 VergilYe 的插件 dsh-auto-continue(当前 README 与 package.json 标注为 v2 / 2.0.0)针对「话没说完」或「只写了下一步计划就停」设计了三层防护,并在 v2 里把 v1 踩过的六个坑写进实现约束。下面介绍它是什么、怎么装、默认行为与可选配置。

这是什么

dsh-auto-continue 是 DSH 社区插件,仓库 VergilYe/dsh-auto-continue,目录页 skillhub.cn。MIT 许可,零依赖、无构建步骤;运行时不读凭据、不联网、无遥测,仅在开启诊断时向本机 $DSH_HOME/dsh-auto-continue/events.jsonl 写日志。

一句话定位:在 adapter 流与回合收尾判定上拦截「看起来像正常 stop、实则未完成」的情况,必要时在同一 turn 内推送续写或触发 guard 重试,避免轮次过早关闭。

要对付的三种形态

README 将典型现象归纳为三类,各自对应不同手段:

形态 现象 手段
A 重连变体 本 turn 有 llm/retry,之后只叙述计划 retryScope
B 静默截断 无错误、stop=stop,但正文停在冒号/半句 llm/stream guard + truncationScope
C 自述计划 语法完整,把下一步计划当结论 收尾协议 + extendedScope

三层防护(核心功能)

1. 请求层:llm/stream guard

默认开启(streamGuard: true)。adapter 流经 guardStream 逐 chunk 透传,UI 仍实时输出;在静默超时、上游未 finish 就断、或 finish=stop 但正文未收尾等情况下,以 error finish 让 loop 判本次尝试失败,插件可返回 { kind: 'retry' } 在同一步内重发。

  • 默认对所有路由生效(allowModels 为空数组);配置白名单则仅对列表内 provider/model 生效。跳过 purpose 为标题/压缩的辅助请求。
  • 截断改判每会话最多 maxGuardRetries 次(默认 1);判定前会剥离协议块,避免健康的 ```done 收尾被误判为未说完。
  • streamIdleMs 默认 90000(毫秒)。

2. 协议层:收尾声明(默认开)

通过 SystemPrompt.section() 注入要求(order 9500,不改全局提示词,卸载即撤)。模型需在消息末尾用 fenced block 声明,例如:

```done
✅ 已完成:<一句话结果摘要>

或

❓ 待确认:<需要用户拍板的具体问题>
判定是确定性的:块必须在消息最后、且摘要/问题非空才放行;缺块、正文为空、或块后仍有内容会触发一次协议推送(`completionProtocol` 为 `true` 时)。标记样式可配置:`fence-check`(默认)、`fence`、`line`、`plain`(兼容 v1 的 `[DONE: …]`,README 说明 v1 括号标记易诱发模型输出异常)。

## 3. 兜底层:三个启发式域

仅在协议关闭时使用。共同闸门包括:最后一条为纯文本 `stop`、且不是在问用户。

| 域 | 判据 |
|---|---|
| `retryScope` | 本 turn 有 `llm/retry`,且 `failure.code ∈ retryCodes`(默认 TRANSPORT/TIMEOUT/SERVER) |
| `truncationScope` | 末句未收住(如以 `:,、(` 结尾或无标点) |
| `extendedScope` | 收尾区命中计划短语(`planPatterns` 可配) |

# 安全阀与限制

推送与重试并非无限裸奔。README 强调:额度只记「连续无效推送」(推完模型确有工具调用则不计并清零);默认 `maxNudges` 为 `2`,两次推送至少间隔 `nudgeMinIntervalMs`(默认 5000 ms);放弃时会在对话里留可见提示(`giveUpNoticeText`),每个 turn 一次。`goal.phase === 'active'` 时整插件跳过;人类在首条 assistant 之后接管会清零计数(开局 prompt 不算)。

已知限制包括:真网络断连仍由 DSH 退避重试处理;不记录 `stopReason` 的路由无法按「stop」判据兜底;协议依赖宿主挂载 `systemPrompt` 服务(缺失时协议段静默缺失,仅剩 guard 与三域);依赖的 `Session.eventAt` / `snapshotEvents` 已被标 `@deprecated`。

# 安装与启用

插件要求 Node `>=22`。推荐从 GitHub 直接安装(profile bundle,无需构建):
```bash
dsh plugin add git+https://github.com/VergilYe/dsh-auto-continue.git

卸载 bundle:

plugin_manager  action: remove_bundle   target: dsh-auto-continue

DSH「市场」读取社区索引 dsh-plugin-catalog;收录后可在 设置 → 插件 → 市场 搜索 auto continue 安装。生态上的插件目录为独立社区站点,与 DeepSeek / 幻方无官方从属关系。

下载即用:allowModels 默认为空数组,表示对所有路由生效,装完无需改配置即可让 stream guard、收尾协议、兜底三域一并作用于当前 profile 的请求。

若只想对部分模型生效,在 profile 补丁层覆盖(bundle 层之后应用):

路径:~/.dsh/profiles/<profile>/cordis.patch.yml

- id: auto-continue
  name: dsh-auto-continue
  config:
    allowModels:
      - open-design/deepseek-v4.1-flash
      - zai-coding-cn/glm-5.3

行 id 为 bundle 补丁里的 auto-continue(非宿主内层 include:auto-continue)。实际路由字符串可查 $DSH_HOME/dsh-auto-continue/events.jsonl 的 route 字段(需开启相关日志时)。

常用配置项

字段 默认 含义
enabled true 关闭后不注册监听器
maxNudges 2 连续无效推送上限;0 等同未安装
completionProtocol true 收尾协议
streamGuard true 请求层防护
dryRun false 只记日志不推
logDecisions false 诊断决策日志

完整字段见仓库 README「配置」一节;非法正则项会被忽略。

适用场景与注意

适合:长回合编码、多步工具链、易受网关截断或模型「计划式收尾」的 DSH profile。不适合指望它替代 SSE 保活或修复「完全断网」——那些仍属宿主与适配器范畴。

权限与安全:插件以当前 DSH 进程权限运行,安装前请自行审阅 源码与 MIT 许可证。不想留本机诊断片段时保持 logDecisions: false(默认)。

开发者可在克隆后的插件目录运行测试(README 给出 63 tests 全通过):

cd plugins/dsh-auto-continue
npm test

结尾

dsh-auto-continue 把「合法 stop 但任务未完成」从主循环里拆出来,用流 guard、强制收尾协议和兜底启发式三层把关,并在 v2 里修正系统提示词泄漏、服务键命名、maxNudges 计数来源等问题。若你经常在 DSH 里手动敲「继续」,可以把它当作 profile 级默认插件试装。

  • 目录页:https://www.skillhub.cn/plugins/VergilYe/dsh-auto-continue
  • GitHub:https://github.com/VergilYe/dsh-auto-continue
羽毛球分组比赛记分
小程序二维码

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

Xiaoye