前言¶
如果你在 DeepSeek Harness(DSH)裏用過 ask_user_question,可能遇到過這樣的場景:agent 提了一個問題,問題卡片通過 mux WebSocket 單次推送到瀏覽器。一旦頁面被切到後臺、筆記本休眠,或者連接進入半開狀態,這一幀就丟了——客戶端沒有心跳,感知不到問題存在,工具就一直等下去。實測觀察到過 6 小時以上的掛起,唯一的恢復手段是手動按 Stop。上游反饋見 deepseek-ai/deepseek-harness#1554(discussion)。
dsh-ask-guard 就是針對這個問題的一個插件:丟失或未回答的問題會以結構化的 ASK_TIMEOUT 結束,而不是讓回合永遠掛起。下面介紹它的原理、安裝和配置。
這是什麼¶
dsh-ask-guard 是 DSH 中 ask_user_question 的超時守衛插件,由 Q1hangL 維護,當前版本 0.1.0,許可證爲 MIT(README 與 package.json 均有標明)。它體現的是 DSH「一切皆插件」的思路:不改 harness 本體,通過一個工具執行包裝器補上官方 dsh-tool-call-timeout-policy 覆蓋不到的空檔——後者只強制執行工具插件聲明的預算(budget),而 ask_user_question 沒有聲明任何預算,所以此前始終無人兜底。
工作機制¶
插件做的事可以拆成三步:
1、註冊一個 tools/execute 包裝器,爲每次 ask_user_question 調度設置協作式截止時間(deadline)。
2、截止時間觸發時,等待中的 provider 中止處理器被觸發:web provider 會廣播 question/resolved cancelled,把卡住的輸入框(composer)清理掉。
3、包裝器把歸一化後的中止替換爲結構化錯誤結果(code: ASK_TIMEOUT,name: AskTimeoutError),並附帶一條面向模型的消息,agent 因此可以優雅地結束回合,而不是阻塞在那裏。
這裏有兩個值得注意的設計:
- 超時是協作式的。由
@deepseek-ai/dsh-timeout通過exec.signal發出通知,web user-questions provider 響應這個信號並真正終止,而不是隻在工具層假超時。 - 其他工具原樣通過。包裝器只針對
ask_user_question,不影響其餘工具的執行路徑。
安裝與啓用¶
官方安裝命令:
dsh plugin --profile web add dsh-ask-guard
裝完後重啓 dsh web。插件是一個 dsh.bundle 包,reconcile 時補丁行會自動加入 profile 組合,不需要手動改組合文件。
如果想從 git checkout 安裝:
dsh plugin --profile web add github:Q1hangL/dsh-ask-guard
依賴方面,插件的 peerDependencies 爲 @deepseek-ai/dsh-timeout ^0.1.0-rc.6、@deepseek-ai/dsh-tools ^0.1.0-rc.6、@deepseek-ai/schemastery ^3.18.1,安裝前可以確認一下環境版本。
配置超時時間¶
只有一個配置項 timeoutMs,即單次 ask_user_question 調用的截止時間,默認 300000 ms(5 分鐘)。
要調整的話,在 profile 的 cordis.patch.yml 里加一段,例如改成 10 分鐘:
- id: ask-guard
config:
timeoutMs: 600000
數值按你的實際交互節奏定:問題通常幾分鐘內會被回答,默認值就夠;如果提問後經常要離開一段時間再回來,可以適當調大。
關於恢復¶
先說明一下現狀:頁面刷新(F5)本來就能重新同步待回答問題——主機向重連的客戶端重放未回答的問題。裝了這個插件之後,即使不刷新頁面,回合也不會永遠掛起,超時後會以 ASK_TIMEOUT 收場。兩者解決的是同一個問題的不同層面:刷新恢復的是「問題還在等回答」的場景,插件兜住的是「問題根本沒送達」的場景。
運行測試¶
如果你要改源碼或驗證行爲,倉庫裏帶了測試,跑法是標準兩步:
npm install
node --test
適用場景與注意¶
適合誰:在 web 界面使用 DSH、並且依賴 ask_user_question 做人機交互的開發者。只要你有過「agent 卡在等回答上、只能按 Stop」的經歷,這個插件就是對症的。
兩點提醒:
1、插件以當前 dsh 進程的權限運行,安裝前建議先看一遍源碼和許可證。代碼在 GitHub 上可以完整審閱,許可證爲 MIT。
2、超時值不要設得過短,否則正常節奏下還沒來得及回答的問題會被誤判爲超時結束。
結尾¶
dsh-ask-guard 解決的是一個很具體的問題:讓丟失或未回答的提問以結構化的 ASK_TIMEOUT 收場,agent 能優雅結束回合,而不是無限等待。實現不復雜,機制也剋制——只包 ask_user_question,其餘工具不碰。如果你的工作流裏有類似的掛起問題,值得一試。