dsh-ask-guard:給 ask_user_question 加一道超時守衛,回合不再永久掛起

前言

如果你在 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_TIMEOUTname: 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,其餘工具不碰。如果你的工作流裏有類似的掛起問題,值得一試。

羽毛球分组比赛记分
小程序二维码

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

小夜