前言¶
在 DeepSeek Harness(cordis)裏用 subagent 並設置 run_in_background: true 時,調用會立刻返回 subagentId,子代理在後臺繼續跑,收尾結果通常靠異步的 settlement 通知送達。若下一步必須依賴子代理的停止原因或收尾消息,原先沒有「阻塞等待」這一環:run_in_background: false 只在啓動時阻塞;send_message 發完即返;list_agents 明確不是用來做輪詢的。下面介紹維護者 john-walks-slow 發佈的工作流類插件 dsh-wait-subagent,它註冊 wait_subagent 工具,在事件驅動、零輪詢的前提下,阻塞直到指定後臺 continuable 子代理收尾,並在同一次調用裏返回 stop_reason 與 closing_message。
這是什麼¶
dsh-wait-subagent 是 DeepSeek Harness 插件,在每個 root agent 上註冊一個面向模型的 Agent 工具 wait_subagent。它不改動 Web 客戶端、不提供 UI、也沒有額外配置項;安裝後通過 bundled 的 cordis.patch.yml 自動掛載 loader 入口。
- 倉庫:john-walks-slow/dsh-wait-subagent
- 社區目錄:SkillHub 插件頁
- 許可證:MIT(package.json 版本 1.0.0)
- 運行要求:Node ≥ 22.5;依賴
@deepseek-ai/dsh-tools0.1.2-rc.1(與 dsh 0.1.2-rc.1 鎖定版本對齊)
DSH 生態強調「一切皆插件」;SkillHub 等社區目錄是獨立站點,與 DeepSeek / 幻方無官方從屬關係。插件在當前 dsh 進程權限下運行,安裝前建議自行查看源碼與許可證。
核心功能¶
wait_subagent 工具¶
工具簽名(來自 README):
wait_subagent(subagent_id: string, timeout_ms?: integer)
→ { status: "settled" | "timeout" | "cancelled",
subagent_id: string,
stop_reason?: "completed" | "aborted" | "error" | "max-tokens" | "refusal" | "unknown",
closing_message?: string }
行爲要點:
- 成員校驗:通過
ctx.subagents.listChildren(parent.id)(與list_agents同一投影)校驗subagent_id;未知或非本 agent 的子 id 會直接報錯,提示使用後臺 dispatch 返回的 id(可參考list_agents)。 - 事件等待:監聽
subagent/end生命週期事件(子 agent activation 被 dispose 時觸發),在插件 context 上訂閱,避免與 registry 更新的競態。 - 可選超時:傳入
timeout_ms可在超時後得到status: "timeout";省略則無限等待(文檔建議通常省略;若設超時宜給較大值,而非用多次短等待模擬輪詢)。 - 取消:尊重調用方的
AbortSignal,返回status: "cancelled"。 - 阻塞語義:等待期間佔用調用方 agent 的 tool lane,這是設計行爲;等待本身由事件驅動,阻塞時 CPU 開銷可忽略。無網絡、無外部服務、無文件寫入等副作用。
安裝與啓用¶
安裝後需重啓 DSH 實例,cordis.patch.yml 會自動註冊 loader。
從插件名安裝(web profile):
dsh plugin --profile web add dsh-wait-subagent
或從 GitHub 源碼安裝(純 ESM JavaScript,無構建步驟,無需 pnpm build-script 審批):
dsh plugin --profile web add github:john-walks-slow/dsh-wait-subagent
典型用法¶
先後臺啓動子代理,再對返回的 subagentId 調用 wait_subagent:
wait_subagent({ subagent_id: "session-9f2c47ab-83d1-4e06-b5a9-1c7f2d84e0b3" })
調用在子代理運行期間阻塞;收尾後工具返回 JSON,模型側可見的文本類似:
Subagent session-9f2c47ab-83d1-4e06-b5a9-1c7f2d84e0b3 settled: completed
Spec written to docs/plan.md; 3 files changed, ready for review.
對應結構化結果示例:
{
"status": "settled",
"subagent_id": "session-9f2c47ab-83d1-4e06-b5a9-1c7f2d84e0b3",
"stop_reason": "completed",
"closing_message": "Spec written to docs/plan.md; 3 files changed, ready for review."
}
其他常見結果:
| 情況 | 結果 |
|---|---|
| 調用前子代理已收尾 | status: "settled",stop_reason 可能爲 unknown;說明此前已收尾,closing message 可能已通過 settlement 通知單獨送達 |
timeout_ms 到期 |
status: "timeout";子代理可能仍在運行 |
| 調用方 AbortSignal 觸發 | status: "cancelled" |
| 未知或非本子 agent 的 id | 拒絕並報錯 |
適用思路:當你下一步動作依賴子代理結果時,用 wait_subagent 主動等待,而不是猜測或輪詢 list_agents。
適用場景與注意¶
適合:編排「後臺跑探索 / 寫 spec / 改文件 + 主對話等結果再決策」的工作流;需要同一步工具調用內拿到 stop_reason 與 closing_message 的場景。
注意:
- 不要在同一步並行
wait_subagent與interrupt_agent。wait_subagent雖併發安全,但interrupt_agent需要獨佔 tool lane 且排在進行中的調用之後;同一步並行時往往會先等到 wait 超時,interrupt 才生效。應先interrupt_agent,下一步再wait_subagent(已中斷的子 agent 會較快收尾)。 - 無限等待會長期佔用 tool lane,這是功能本身;需要上限時再設
timeout_ms。 - 社區目錄頁星標爲 0,不代表功能未驗證;以 README 與源碼爲準。
結尾¶
dsh-wait-subagent 補齊了 run_in_background「即發即返」與異步 settlement 通知之間的缺口:一個事件驅動的 wait_subagent,讓主 agent 在依賴子代理結果時能阻塞等待並一次性讀回收尾信息。
- 目錄頁:https://www.skillhub.cn/plugins/john-walks-slow/dsh-wait-subagent
- GitHub:https://github.com/john-walks-slow/dsh-wait-subagent