前言¶
在 DeepSeek Harness(DSH)裏跑 Agent 時,常見情況是:模型調用了 browser_tab_new、把 bash 或 subagent 丟到後臺、或在 run_code 裏起了臨時進程和端口,會話結束或任務被打斷後,這些資源仍留在宿主機上。靠提示詞提醒「記得關掉」並不穩定,也不適合作爲唯一治理手段。
dsh-resource-lease(維護者 r-ayin)把「打開即登記、到期或會話結束即回收」做成插件機制:資源在打開時自動或手動寫入租約表,歸屬當前會話並帶 TTL;回收由會話銷燬、定時掃描和啓動補償等多條路徑觸發,不依賴模型是否記得收尾。插件在 SkillHub 分類爲 admin-security(安全管理),當前版本 v0.0.1,許可證 MIT。
這是什麼¶
一句話:資源租約治理——把瀏覽器標籤頁、後臺 job、進程與端口等待回收對象登記爲「會話擁有的租約」,用 TTL 與清掃邏輯自動收回;需要長期保留的條目可升級爲 pinned。
- 倉庫:github.com/r-ayin/dsh-resource-lease
- 目錄頁:skillhub.cn/plugins/r-ayin/dsh-resource-lease
- 運行環境:
package.json要求 Node >= 20,依賴 DSH 生態中的cordis、@deepseek-ai/dsh-llm、@deepseek-ai/dsh-tools等 peer 包。
DSH 社區插件由獨立目錄站點收錄,與 DeepSeek / 幻方無官方從屬關係;安裝前請自行審閱源碼與許可證。插件在當前 dsh 進程權限下執行回收(關 tab、殺 job、對進程發 SIGTERM),權限範圍與宿主一致。
三層防線¶
下面按 README 中的設計,從登記、回收到策略分層說明。
1. 自動登記(零提示詞依賴)¶
通過 tools/result 觀察鉤子,在資源創建時寫入租約,無需在提示詞裏反覆強調「登記資源」:
| 來源 | 租約類型 | 默認 TTL |
|---|---|---|
browser_tab_new |
browser-tab(tabId + 會話) | 240 分鐘 |
bash / subagent / workflow 且 run_in_background |
job(jobId) | 360 分鐘 |
run_code 等其它資源 |
需 Agent 調用 lease_register |
按登記參數 |
lease_register 支持 kind=process|port|custom;process/port 需帶 pid。
2. 自動回收(多觸發點冗餘)¶
- 會話正常結束:
session/disposed時關閉該會話下全部 session 級租約。 - Daemon 週期掃:默認每 60s 處理 TTL 已過期的租約(會話掛死時的兜底)。
- 啓動補償:宿主啓動約 10s 後掃一遍過期賬;註冊表持久化在
~/.dsh/resource-lease/leases.json(重啓後仍能回收遺留項)。 - 瀏覽器空閒關實例:在
autoCloseBrowser爲 true 時,空閒 10 分鐘且實查無未登記 tab 才調用 browser 關閉;有未登記 tab 時不關,避免誤傷共享 Chrome。
回收執行路徑(README 實測說明):
- 瀏覽器 tab →
ctx.tools.execute('browser_tab_close') - job →
ctx.jobs.kill(jobId, sessionId, reason)(README 註明不宜依賴僅 Agent 作用域可見的job_kill工具) - process/port →
process.kill(pid, SIGTERM) - 資源已不存在(not found / ESRCH / already-finished)視爲成功;
'unknown tool'不算成功——連續失敗 3 次標failed並停止重試,可在面板中人工處理
3. 分類策略¶
- session(默認):隨會話結束或 TTL 自動回收。
- pinned:用戶表示「這個留着」時,通過
lease_pin升級,不參與自動回收。 - system:白名單(如 cron/watchdog、外部 Chrome 等不登記項天然豁免)。
Agent 工具面¶
| 工具 | 用途 |
|---|---|
lease_list |
列租約;默認當前會話活躍項,all=true 可看全部 |
lease_register |
手動登記 process/port/custom |
lease_pin |
pinned 升級或降級 |
lease_release |
立即關閉;force=true 時連 pinned 也關 |
lease_sweep |
立即掃一輪;可指定 sessionId 只清該會話 |
典型流程:後臺起服務後 lease_register 登記端口與 pid → 任務結束用 lease_list 覈對 → 臨時資源 lease_release,長期保留 lease_pin。
對話面板¶
插件在 conversation.view 槽位提供 「資源租約」 面板:活躍租約表、單條關閉/固定、清掃過期,約 10s 自動刷新。宿主 HTTP API 路徑爲 /resource-lease/api/{leases,release,pin,sweep}。
配置¶
默認行爲可通過包內 cordis.patch.yml 覆蓋,README 給出的項包括:
| 配置項 | 含義(README 默認值) |
|---|---|
sweepIntervalMs |
清掃間隔,60s |
tabTtlMinutes |
瀏覽器 tab TTL,240 分鐘 |
jobTtlMinutes |
後臺 job TTL,360 分鐘 |
autoCloseBrowser |
是否啓用瀏覽器空閒關閉 |
browserIdleCloseMs |
瀏覽器空閒判定,10 分鐘 |
keepClosedHours |
已關閉記錄保留,72 小時 |
修改後按你當前的 DSH 插件加載方式重載配置即可。
安裝與構建¶
已抓取資料中未給出 SkillHub 或 README 裏的單行 dsh plugin add … 安裝命令,此處不憑倉庫名拼接命令。請從 SkillHub 目錄頁 或 GitHub 倉庫 按頁面說明安裝到 DSH 環境。
若你需要從源碼構建(README 說明可離線構建、無需 npm install 依賴安裝步驟作爲主路徑):
# 宿主側
bash scripts/build.sh
# DSH_CHECKOUT 會自動探測 ~/dsh-harness
# 客戶端
bash scripts/build-client.sh
# tsc 輸出 CJS,並用手工 __ModuleLoader__ 包裝
# 開發熱重載(DSH 內置流程)
dev_build_plugin → dev_inject_plugin / dev_reload_package
package.json 中 scripts.build 同樣指向 bash scripts/build.sh。
適用場景與注意¶
適合:長時間跑 Agent、頻繁開瀏覽器調試、大量 run_in_background job 或本地臨時服務的開發與運維場景;需要一眼看到「當前會話佔用了什麼」並在 UI 或工具裏收尾時。
注意:
- 自動登記覆蓋 README 列出的鉤子路徑;其它資源務必
lease_register,否則不會進入租約表。 - 瀏覽器整實例關閉有「無未登記 tab」安全閘,不能替代你對共享環境的 tab 管理習慣。
- pinned 資源只有
lease_release(且force=true)或人工操作纔會釋放。 - 安裝前檢查源碼與 MIT 許可證;回收動作與 dsh 同權限,生產環境請評估影響面。
結尾¶
dsh-resource-lease 把 Agent 遺留的 tab、job、進程和端口收成可查詢、可 TTL、可固定的租約,用會話銷燬、定時掃和啓動補償多條路徑做回收,並暴露工具與「資源租約」面板。若你正在 DSH 裏治理半自動資源生命週期,可從目錄頁或倉庫 README 安裝並覈對 cordis.patch.yml。