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