用 dsh-custom-tool 在 DeepSeek Harness 設置頁編寫沙箱自定義工具

前言

給 DeepSeek Harness(以下簡稱 DSH)加一項能力,常規路徑是寫一個 harness 包:聲明工具 schema、實現 execute、打進 profile。這套流程適合正式插件,但對「今天臨時要調一個天氣接口」「這個工作區反覆做同一類文件整理」來說,成本偏高。改完還要重啓、重新掛載,模型這一側也不能在會話中途自己補一把工具。

官方倉庫把架構寫成「一切皆插件」:模型、工具、技能、會話、沙箱、UI 都可以在配置層裝卸,不必改 Harness 源碼。社區裏有人把「寫工具」這件事收進設置頁:用 Monaco 編輯器填名字、描述、參數和 JavaScript 代碼,保存後熱註冊進 ctx.tools;同一套工具,模型也可以通過 custom_tool_create / custom_tools_list / custom_tool_remove 增刪。這個插件叫 dsh-custom-tool,收錄在獨立的社區插件目錄 deepseek-harness-plugin.com 中。該目錄與 DeepSeek / 幻方沒有官方從屬關係,不是官方應用商店。

本文按插件目錄頁、GitHub 倉庫 README / README.zh.md、package.jsondsh.plugin.json 交叉覈對後整理:它是什麼、裝哪條命令、工具代碼怎麼寫,以及沙箱邊界和 harness 前置條件。

這是什麼

dsh-custom-tool 是一款面向 DeepSeek Harness 的開發與運行時插件,由 GitHub 組織 omdsh-dev 維護,倉庫地址爲 omdsh-dev/dsh-custom-tool。當前版本爲 0.1.2package.jsondsh.plugin.json 一致;倉庫在 2026-08-16 打了 git tag v0.1.2)。許可證爲 MIT,LICENSE 版權聲明寫的是 2026 FSMargoo。主要語言是 TypeScript;倉庫已提交 lib/,按 README 用 GitHub tarball 安裝時不必本地構建。截至 2026-08-17 查詢,GitHub API 顯示 24 stars(社區目錄頁當時標註爲 23)。package.json 要求 Node.js ^22.19 || >=24

目錄頁給它的一句話是:用 Monaco 編輯器創建和管理沙箱 JavaScript 工具,模型驅動工具生命週期。倉庫 README 寫得更具體:用戶在設置界面的「Custom Tool」頁編寫工具;模型通過上述三個工具接口擴展和修剪同一套工具集。工具持久化、熱註冊,並在下一步寫入模型提示詞。

它要填的坑,README 列了三條:以前加能力要發佈 harness 包,現在一張表單保存即生效;模型可以在會話中途持久化工具,且與 UI 共用同一道校驗門;用戶寫的代碼在受限 worker 裏跑,而不是直接進當前 Node 進程。

核心功能

下面幾條都來自當前倉庫 README、README.zh.md 與 dsh.plugin.json,不額外發揮。

1. 設置頁裏的 Custom Tool

插件在 Web 設置里加了一個「Custom Tool」分區,帶專屬導航圖標。可以列表、新建、編輯、啓用 / 停用、刪除。模型創建的工具、以及工作區作用域的工具會打徽章。文案接入 harness 的中文 / English 語言體系,隨界面語言切換。

編輯器是 Monaco(VS Code 引擎)加 TypeScript 語言服務:args 按你聲明的參數 schema 生成類型,env 和沙箱全局量有聲明,補全與診斷即時出現。編輯器和 TS worker 內聯打包,客戶端是單文件 bundle。package.json 聲明瀏覽器半通過 dsh.client 提供,README 寫明路徑是 /plugins/dsh-custom-tool/client.js

2. 持久化與熱註冊

工具存在 custom-tools 設置命名空間,分層方式和 harness 其他設置一樣:schema 默認值、組合 base、用戶文檔。改動提交後立刻生效,重啓後按存儲恢復。

啓用的工具在設置寫入提交的瞬間註冊進 ctx.tools;停用或刪除會立即註銷。工具 schema 由 harness 自動匯入系統提示詞,模型下一步就能看見。

3. 模型自助:創建、列出、刪除

dsh.plugin.json 聲明貢獻的工具是:

  • custom_tool_create:按名字 upsert
  • custom_tools_list
  • custom_tool_remove

這三條與設置 UI 共用校驗門。歸屬規則 README 寫得很清楚:

  • 模型可以創建、列出、刪除 自己創建 的工具(source: model
  • 創建 global 位置 的工具需要用戶明確授權:custom_tool_create 會發起 harness 審批請求(GUI 彈窗);拒絕或審批不可用則創建失敗關閉
  • workspace 位置的工具,模型可以自主創建
  • 模型 不能 刪除用戶創建的工具(source: user):custom_tool_remove 會拒絕,提示詞會引導模型請用戶在設置界面刪除

設置界面管理全部來源、作用域、位置,以及啓停和刪除。

4. 兩套作用域、兩套存放位置

每個工具聲明一種執行作用域。這是插件的核心安全契約:

global(默認) workspace
用途 純計算、外部數據、工作流 工作區內重複性的文件任務
fetch allowNetwork 控制 allowNetwork 控制
console、定時器、TextEncoderURL
fs readFile / writeFile / list,限定在本會話 workspace 根目錄內
require / import / process 永不 永不

workspace 作用域的根目錄是發起 agent 的 cwd,調用時解析。相對路徑從根解析;絕對路徑必須落在根內;越界路徑會被顯式拒絕。沒有會話上下文時,workspace 工具直接報 no workspace root,不會在無邊界下運行。

隔離是詞法級的(resolve + 前綴檢查)。README 明確寫了:工作區內的符號鏈接仍可能指向外部——workspace 作用域按可信代碼處理,不是對抗惡意宿主的沙箱。

存放位置是另一維:

  • location: 'global':存在共享設置命名空間,所有工作區都可用,直到被刪除
  • location: 'workspace':存在按工作區根路徑哈希命名的獨立文件裏(README 寫在 workspace-tools/ 目錄下),只對該工作區的會話可見

兩維可以自由組合。README 舉的例子是:location 爲 global、scope 爲 workspace 的文件類工具(例如 PDF 讀取),在任意被調用的工作區上執行 fs

5. 沙箱執行與預算

每次調用在獨立 worker 線程裏跑,環境是全新的 node:vm 領域,配合白名單、Node Permission Model 和硬預算。worker 不繼承環境變量,也不能訪問配置範圍之外的文件或創建子進程。超時、取消或完成後,該 worker 被終止。

README 給出的可調預算(cordis.ymldsh-custom-tool 條目的 config 字段)默認值如下:

字段 默認值 含義
timeoutMs 30000 單次調用牆鐘上限(毫秒)
memoryLimitMb 128 單次調用 worker 老年代堆上限(MB)
maxResultChars 16000 結果渲染文本字符上限
maxCodeBytes 65536 單個工具代碼的 UTF-8 字節上限
maxTools 100 可存儲的工具數上限
allowNetwork true 是否允許工具代碼調用 fetch

安裝與啓用

插件目錄頁給出的安裝命令是:

dsh plugin add github:omdsh-dev/dsh-custom-tool

目錄頁同時提醒:插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。安裝前請檢查源代碼倉庫和許可證。若需要可復現安裝,固定 commit 哈希:

dsh plugin add github:omdsh-dev/dsh-custom-tool#<commit>

<commit> 換成倉庫裏實際的提交哈希,不要照抄佔位符。當前 tag v0.1.2 指向提交 7cb95649dca9b380c9a30af96bdbef87a76a2259

倉庫 README 面向 Web 界面,寫法是按 web profile 安裝固定版本的 tarball,然後重啓:

dsh plugin --profile web add https://github.com/omdsh-dev/dsh-custom-tool/archive/refs/tags/v0.1.2.tar.gz
dsh web

包聲明瞭 dsh.bundle.patch(掛載 host 插件)與 dsh.client(提供瀏覽器半)。lib/ 已提交,因此這份 tarball 安裝後無需再構建。

Harness 前置條件(README 原文):設置命名空間要通過 packages/host/apiproxy/src/api-proxy.ts 中的 WEB_SETTINGS_NAMESPACES 白名單暴露給 web 配置客戶端,名單裏必須有 'custom-tools'。上游 harness 提交 d6ea05b5 已加入該項。缺少它時界面能渲染,但保存會被靜默拒絕,錯誤爲 settings-not-exposed

典型用法

在設置頁新建工具

啓動 Web 界面並打開設置裏的 Custom Tool:

  1. 新建一條工具,填寫名字、描述、參數 schema、作用域和存放位置。
  2. 在 Monaco 裏寫代碼。代碼字段是 一個異步函數體,契約是 async (args, env) => value,不是完整的源文件。
  3. 保存。啓用狀態下,工具立刻註冊進 ctx.tools,下一步會出現在模型提示詞裏。
  4. 不需要時可以停用或刪除;停用會立即註銷。

README 給出的示例是按城市拉天氣(需要 allowNetwork 爲 true,這是默認值):

// args 按你聲明的參數 JSON Schema 生成類型。
const url = `https://api.example.com/weather?city=${encodeURIComponent(args.city)}`
const response = await fetch(url)
if (!response.ok) throw new Error(`upstream returned ${response.status}`)
return await response.json()

返回值必須是 JSON 值:string、number、boolean、null、array 或普通對象。undefined 或非 JSON 值會使調用失敗。

參數是 object 根的 JSON Schema,且只接受 harness 子集:typepropertiesrequireditemsenumconstoneOfadditionalPropertiesdescriptiontitledefaultexamples

沙箱全局量包括:fetchallowNetwork: false 時被禁)、consoleTextEncoder / TextDecoderURL / URLSearchParamsatob / btoastructuredCloneAbortControllersetTimeout / setInterval 及對應的 clear。env{ tool, scope }。workspace 作用域額外提供 fs

界面目前沒有「試運行」按鈕。README 寫明:工具通過模型調用或 headless 運行來驗證。

讓模型自己補工具

會話裏可以直接要求模型創建一條可複用的工具。模型會走 custom_tool_create。若目標是 global 位置,界面會彈出 harness 審批;拒絕則創建失敗。workspace 位置不走這道審批。

查看當前自定義工具用 custom_tools_list。自定義工具名不能遮蔽其他包已經註冊的工具;衝突會以逐工具註冊失敗的形式出現在這份列表裏。

刪除時,模型只能刪 source: model 的條目。用戶在設置頁寫的工具,需要人在 UI 裏刪。

適用場景與注意事項

比較適合這些情況:

  • 已經在用 dsh web,希望給當前環境加幾條小工具,又不想爲此發一個正式插件包
  • 需要模型在會話中途把反覆出現的步驟沉澱成可調用工具,並在下一步立刻看見
  • 工具邏輯是純計算或受控的 fetch;若要碰文件,明確使用 workspace 作用域,並接受詞法隔離的邊界
  • 希望用戶寫的工具和模型寫的工具分權:人刪人的,模型只能動自己創建的那批

使用前注意下面幾條,均來自目錄頁或倉庫 README,不是額外發揮:

  1. 先看源碼和許可證再裝。 目錄頁寫明:插件以當前 dsh 進程權限運行,安裝時可能執行代碼。這是社區插件,不是 DeepSeek 官方組件。
  2. 確認 custom-tools 已進入 harness 白名單。 否則設置頁能打開,保存會靜默失敗(settings-not-exposed)。需要上游提交 d6ea05b5 或等價改動。
  3. 沙箱不是萬能隔離。 require / import / process 不可用;global 作用域沒有 fs;workspace 的路徑檢查不防符號鏈接。README 把 workspace 代碼按可信代碼對待。
  4. 網絡默認是開的。 allowNetwork 默認 true。不希望工具訪問外網時,要在 cordis.yml 裏關掉。
  5. 預算有上限。 單次 30 秒、堆 128 MB、結果 16000 字符、代碼 64 KiB、最多 100 條工具,都是文檔給出的默認硬限制。
  6. 不要把目錄頁當成官方商店。 deepseek-harness-plugin.com 是社區目錄;DSH 本體以 deepseek-ai/deepseek-harness 爲準。安裝命令以目錄頁原文爲準;Web 固定版本安裝以倉庫 README 的 tarball 寫法爲準,不要憑插件名自行拼接路徑。

小結

dsh-custom-tool 做的事情很集中:把「寫一個 JavaScript 工具」放進 DSH 設置頁,用 Monaco 編輯、熱註冊、持久化;同時把同一套生命週期交給模型,但用審批和歸屬規則把用戶工具保護起來。執行側是帶白名單和預算的 worker,不是把任意腳本直接跑進當前進程。

目錄頁與倉庫:

  • 插件目錄:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-custom-tool/
  • GitHub:https://github.com/omdsh-dev/dsh-custom-tool
  • DeepSeek Harness:https://github.com/deepseek-ai/deepseek-harness
  • 官方介紹:https://www.deepseek.com/harness/
羽毛球分组比赛记分
小程序二维码

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

小夜