前言¶
給 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.json、dsh.plugin.json 交叉覈對後整理:它是什麼、裝哪條命令、工具代碼怎麼寫,以及沙箱邊界和 harness 前置條件。
這是什麼¶
dsh-custom-tool 是一款面向 DeepSeek Harness 的開發與運行時插件,由 GitHub 組織 omdsh-dev 維護,倉庫地址爲 omdsh-dev/dsh-custom-tool。當前版本爲 0.1.2(package.json 與 dsh.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:按名字 upsertcustom_tools_listcustom_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、定時器、TextEncoder、URL 等 |
有 | 有 |
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.yml 裏 dsh-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:
- 新建一條工具,填寫名字、描述、參數 schema、作用域和存放位置。
- 在 Monaco 裏寫代碼。代碼字段是 一個異步函數體,契約是
async (args, env) => value,不是完整的源文件。 - 保存。啓用狀態下,工具立刻註冊進
ctx.tools,下一步會出現在模型提示詞裏。 - 不需要時可以停用或刪除;停用會立即註銷。
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 子集:type、properties、required、items、enum、const、oneOf、additionalProperties、description、title、default、examples。
沙箱全局量包括:fetch(allowNetwork: false 時被禁)、console、TextEncoder / TextDecoder、URL / URLSearchParams、atob / btoa、structuredClone、AbortController、setTimeout / 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,不是額外發揮:
- 先看源碼和許可證再裝。 目錄頁寫明:插件以當前 dsh 進程權限運行,安裝時可能執行代碼。這是社區插件,不是 DeepSeek 官方組件。
- 確認
custom-tools已進入 harness 白名單。 否則設置頁能打開,保存會靜默失敗(settings-not-exposed)。需要上游提交d6ea05b5或等價改動。 - 沙箱不是萬能隔離。
require/import/process不可用;global 作用域沒有fs;workspace 的路徑檢查不防符號鏈接。README 把 workspace 代碼按可信代碼對待。 - 網絡默認是開的。
allowNetwork默認true。不希望工具訪問外網時,要在cordis.yml裏關掉。 - 預算有上限。 單次 30 秒、堆 128 MB、結果 16000 字符、代碼 64 KiB、最多 100 條工具,都是文檔給出的默認硬限制。
- 不要把目錄頁當成官方商店。 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/