前言¶
DSH 的子代理(subagent)能讓一個會話把任務丟給另一個 agent 並行處理,但執行仍然落在本機。當你的 agent 需要在另一臺機器上跑、用那臺機器的模型配置、工具和沙箱時,本地子代理幫不上忙。通常的做法是開一個公網端口、配 token、再寫一套 WebSocket 協議——這意味着額外的暴露面和一套獨立於 DSH 的基礎設施。
dsh-remote-subagent 走的是更簡單的一條路:複用 DSH 自帶的 headless 入口,通過 SSH 的 exec 通道把遠端 dsh headless --json 的 JSON 事件流直接讀回本地。下面介紹這個插件是什麼、怎麼裝、怎麼用,以及它明確的邊界。
這是什麼¶
這是 DSH(DeepSeek Harness)的一個插件,作者 deepseekv41flash,分類屬於工作流,目前在 SkillHub 目錄頁與 GitHub 上顯示 1 個星標,版本 0.1.0,許可證 MIT。
它解決一個問題:本地會話需要讓另一臺機器上的 DSH 替自己幹活,並且能看到那個 agent 的思考、工具調用和工具結果,還能在它跑完之後接着追問。
核心機制是 remote_agent 工具。本地會話通過它把任務派給遠端 DSH,遠端 agent 用自己的模型配置、工具、沙箱和 session 存儲執行,過程中的 JSON 事件通過 SSH 實時流回本地。
本地會話 ── remote_agent 工具 ──SSH──> 遠端 dsh headless --json <task>
▲ │
└──── 事件流(thinking / tool_call / tool_result / final)◄──┘
選擇 dsh headless --json 而不是自建服務,是因爲它有三點好處:
- 遠端不需要開公網端口,也不需要 token 或 WebSocket 協議;
- 遠端 agent 用它自己的 profile,session 落在遠端
$DSH_HOME/sessions,在遠端 DSH Web UI 裏同樣可見; - 事件流本身就是「工作過程」,不需要額外埋點。
安裝與啓用¶
README 給出的安裝命令是:
# 從 npm 安裝到當前 profile(bundle 形式)
dsh plugin --profile <profile> add dsh-remote-subagent
# 或在 DSH 插件市場/plugin_manager 裏安裝 dsh-remote-subagent
依賴會自動安裝(ssh2,版本要求 ^1.17.0)。啓用後,左側欄出現「遠端代理」圖標,模型側多出 remote_agent 工具。
插件的運行要求寫在 package.json 裏:Node.js >=20,DSH 引擎 >=0.1.0-rc.6 <0.3.0。遠端同樣需要 dsh 在 SSH 登錄 PATH 上,且 headless profile 可用。
機器從哪來¶
插件不要求你重複配置一份 SSH 清單。它優先讀取 dsh-remote 的註冊表:
$DSH_HOME/remote-workspaces/machines.json
默認機器的解析順序是:插件配置 config.machineId → 註冊表 currentId → 第一個已保存機器 → config.machine(沒有 dsh-remote 的獨立部署用這個)。認證支持密碼、私鑰(含 passphrase)和 SSH agent。
主機密鑰採用 TOFU 策略:首次連接把指紋記錄到 $DSH_HOME/dsh-remote-subagent/known_hosts.json,之後每次連接必須匹配,不匹配就拒絕。
remote_agent 工具¶
插件暴露一個 remote_agent 工具,支持以下幾個 action:
| action | 作用 | 關鍵參數 |
|---|---|---|
spawn |
起一次新的遠端 run(獨立遠端會話) | task、machine?、cwd? |
wait |
阻塞等 run 結束或超時(默認 30s,上限 120s;超時不影響遠端繼續跑) | runId、waitSeconds? |
get |
狀態 + 最近 N 條過程事件 + 結果 | runId、eventLimit? |
send |
給同一遠端會話追加消息(新 run,--session-id 續跑,turn+1) |
runId、task |
list |
最近的 run 列表 | limit? |
cancel |
終止遠端進程(按 pid 文件 kill -TERM) |
runId |
machines |
列出可用的遠端機器 | — |
兩個動作的複用語義需要區分清楚:
spawn永遠創建新的遠端會話,等於內置 subagent 的 spawn;send複用該 run 所屬的同一個遠端會話,等於 subagent 的 send_message;- 多次
spawn併發 = 多個互不共享上下文的遠端會話;同一會話同一時刻只能跑一個 turn。
run 歷史和 sessionId 持久化在本地,DSH 重啓後依然可以對同一個 session 繼續 send。
面板¶
左側欄「遠端代理」打開主面板:
- 左列:新建任務(選機器 + 任務文本 + 派活)、run 列表(狀態點 / 任務摘要 / 機器 / 用時);
- 右列:run 詳情(狀態、遠端 session id、cwd、輪次、事件數、token)、實時事件時間線(1.5s 輪詢增量、自動滾底)、結果框、終止 / 刷新、追加消息輸入框。
面板背後的數據接口(GitHub 倉庫爲 client 半,Desktop 走 /api 前綴,Web 走裸路徑):
GET /dsh-remote-subagent/runs
GET /dsh-remote-subagent/run?id=<run>&from=<seq>&limit=<n>
POST /dsh-remote-subagent/action {action: spawn|send|cancel, ...}
可選配置¶
插件配置寫在所在 profile 的 cordis.patch.yml 的 config: 下,全部可省略:
| 字段 | 默認 | 說明 |
|---|---|---|
machineId |
'' |
默認機器(id/名稱/host) |
machinesFile |
'' |
自定義機器註冊表路徑 |
headlessCommand |
dsh headless |
遠端命令前綴 |
cwd |
'' |
遠端工作目錄(空 = 機器 home) |
maxConcurrent |
4 |
並行 run 上限 |
timeoutSeconds |
900 |
單 run 上限,超時自動終止遠端進程 |
maxEvents |
4000 |
每個 run 保留的事件上限 |
connectTimeoutMs |
20000 |
SSH 連接超時 |
典型用法¶
下面是 README 提供的一個完整調用序列,讀一次遠端健康檢查,再追加一條追問:
remote_agent({action:"spawn", task:"在 /opt/app 跑一次只讀健康檢查:磁盤、內存、監聽端口,最後總結"})
→ runId
remote_agent({action:"wait", runId, waitSeconds:120})
remote_agent({action:"get", runId, eventLimit:30})
remote_agent({action:"send", runId, task:"把監聽端口按大小排序再列一次"})
先 spawn 拿到 runId,再 wait 等它結束或超時,接着用 get 拉最近若干條過程事件和結果;send 是在上一步的同一個遠端會話裏追加消息,turn 加一,模型能看到前面的上下文。
數據與回滾¶
插件在本地寫入兩類數據:
$DSH_HOME/dsh-remote-subagent/runs/<runId>.json:每個 run 的元數據 + 事件 transcript。重啓後歷史仍在;重啓瞬間還在跑的 run 會標記爲 failed/interrupted,但 session id 保留,仍可send續跑。$DSH_HOME/dsh-remote-subagent/known_hosts.json:TOFU 主機指紋。
卸載時從 profile 移除 dsh-remote-subagent bundle;需要清數據就刪除 $DSH_HOME/dsh-remote-subagent/。插件對遠端沒有持久改動,只會在 /tmp/dsh-remote-subagent-*.pid 落臨時 pid 文件(正常結束自動清理)並佔用遠端 session 目錄。
實測狀態¶
README 記載了 v0.1.0(2026-11-04)在一臺 Linux 遠端(DSH 0.2.0-rc.2,SSH 密碼登錄)上的實測結果:
spawn用時 11s,產生 23 條事件,turn 1,包含tool_call與tool_result;send續跑同一session-*,turn 2 正確引用上一輪上下文,回答中的數值與 turn 1 一致;- DSH 重啓 + 插件熱重載後,
send仍能續上同一遠端會話(turn 3); cancel之後遠端沒有殘留的dsh headless進程,pid 文件被清理。
README 還說明有離線單測覆蓋:機器解析順序與報錯、事件流解析/分頁/續跑/取消/持久化、面板路由、SSH 引用與 TOFU 指紋、Client 槽位註冊。
已知邊界¶
這些限制來自 README,實際使用前需要對照自己的環境確認:
- 遠端需要
dsh在 SSH 登錄 PATH 上,且 headless profile 可用;遠端版本過老、沒有--json/--session-id時不可用; - 只支持 POSIX 遠端(命令用
sh -c包裝),Windows 遠端未實現; - 不支持 dsh-remote 的
useSshConfig別名機器與 ProxyJump 跳板,需要用直連條目; - 遠端 run 的模型 / 工具 / 沙箱完全由遠端 profile 決定,本地不能改;
wait超時不會終止遠端 run;運行中不支持插話,需要wait或cancel之後再send;- 事件流只覆蓋 headless 單 turn;遠端 agent 如果把活丟進後臺 job,後續輸出不會出現在這個 run 的流裏。
適用場景與注意¶
適合的場景是:你有一臺專門跑了 DSH 的機器(比如帶特定模型配置、特定工具或隔離沙箱的服務器),想讓本地會話把任務派過去執行,並且希望在本地面板裏看到完整的執行過程。它把執行環境和交互環境拆開,遠端不需要暴露任何端口。
需要注意的點:
- 插件安裝在當前 DSH profile 裏以後,是以當前 dsh 進程的權限運行的。安裝第三方插件之前,建議先讀一遍源碼(GitHub 倉庫)並確認許可證——本插件聲明爲 MIT;
- 它依賴 dsh-remote 的
machines.json作爲機器來源,如果已經用 dsh-remote 管理機器,不需要重複配置;沒有 dsh-remote 時要改用config.machine; - 「遠端會話可追加消息」意味着 session 內容會留在遠端,注意遠端的存儲和清理策略。
小結¶
dsh-remote-subagent 做的事情不復雜:把 dsh headless --json 的 SSH 調用封裝成一個 remote_agent 工具,配上事件流回讀、run 持久化和麪板。它的價值在於讓「換一個執行環境」這件事不需要新開服務、不需要改協議,代價是隻支持 POSIX 遠端,且遠端行爲完全由遠端 profile 決定。
插件目錄頁:https://www.skillhub.cn/plugins/deepseekv41flash/dsh-remote-subagent
倉庫:https://github.com/deepseekv41flash/dsh-remote-subagent