前言¶
在 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