用 dsh-tool-json 在 DeepSeek Harness 裏按路徑查詢 JSON

前言

DeepSeek Harness(命令名 dsh)是 DeepSeek AI 開源的智能體運行時,目前仍是開發者預覽。官方倉庫 deepseek-ai/deepseek-harness 寫明核心理念是「一切皆插件」:模型、工具、技能、會話、沙箱和界面都可以在配置層替換,不必改核心源碼。社區裏還有一份獨立的插件目錄站點 deepseek-harness-plugin.com,它和 DeepSeek / 幻方沒有官方從屬關係,不能當成官方應用商店。

智能體處理 JSON 是高頻操作。API 返回值、配置文件、其他工具的輸出,幾乎都是 JSON。常見做法是起一個 bash 進程去跑 node -ejq,每次都有進程開銷,還要把對象先序列化成字符串。DSH 內置的 grep 可以做正則匹配,但不理解 JSON 結構。對 {"items":[{"id":1}]} 這種數據,字符串搜索很容易把值、鍵名,以及嵌套對象裏的同名鍵混在一起。

社區插件 dsh-tool-json 做的事情比較剋制:給當前 profile 註冊一個名爲 json 的工具,用 JMESPath 風格的路徑子集做結構化查詢。解析器是手寫的遞歸下降實現,不依賴第三方查詢庫。本文按插件目錄頁、GitHub 倉庫 README / package.json / 源碼,以及 DeepSeek Harness 官方倉庫交叉覈對後整理。

這是什麼

dsh-tool-json 是一款面向 DeepSeek Harness 的「工具與能力」插件,由 GitHub 組織 omdsh-dev 維護,倉庫地址是 omdsh-dev/dsh-tool-json。社區目錄於 2026-08-14 收錄,許可證爲 MIT(LICENSE 版權聲明爲 2026 whiteicey),主要語言是 TypeScript。截至 2026-08-18,目錄頁和 GitHub 倉庫都顯示 3 顆星。倉庫 package.json 裏的版本號是 0.0.1,要求 Node.js ^22.19.0 || >=24.0.0,README 寫明適配 DSH 0.1.0-rc.6(npm 線)。

一句話定位:安裝後,模型可以調用 json 工具,對 JSON 對象或 JSON 字符串執行路徑查詢,返回匹配到的值。

需要先分清包名和來源。Cordis 插件名和 package.jsonname 都是 @deepseek-ai/dsh-tool-json,但這是社區倉庫自己用的包名,private 字段爲 true,並不表示它由 DeepSeek 官方發佈到 npm。第三方清單裏偶見 dsh plugin add @deepseek-ai/dsh-tool-json 這種按包名安裝的寫法;目錄頁和倉庫 README 均使用 GitHub 源,本文以這兩處爲準。

同一維護組織還有合集倉庫 omdsh-dev/dsh-toolkit,會把包括 json 在內的多個工具做成 vendored 快照。合集裏的測試數量和獨立倉庫不一定同步。只需要 JSON 查詢時,按本文安裝獨立倉庫即可。

核心功能

插件入口在 src/index.ts,通過 ctx.tools.register() 註冊工具;查詢邏輯在 src/query.ts,分成解析、執行和輸入歸一化三塊。面向模型的工具名是 json,兩個必填參數是:

  • input:要查詢的 JSON 值,或一段 JSON 字符串
  • query:路徑表達式,例如 data.items[0].name

輸出按 JSON 返回,渲染時用 JSON.stringify 變成文本。工具聲明裏的 timeoutMs 是 1000 毫秒。

雙形態輸入

input 有兩種形態,由 normalizeInput() 統一校驗:

  1. 對象直傳:模型直接生成 JSON 參數,少一層轉義。
  2. 字符串透傳:bash、read 等拿到的原文可以原樣送進來,內部先 JSON.parse

兩種路徑都會做 JSON 兼容性檢查。只接受 null、布爾、有限數字、字符串、數組和純對象;undefinedBigInt、函數、Date、非有限數、帶 accessor 或不可以枚舉的自有屬性會被拒絕。循環引用也會報錯。

查詢語法

語法是 JMESPath 啓發下的自定義子集,不是完整 JMESPath。倉庫 README 給出的表達式如下:

表達式 示例 說明
點號訪問 foo.bar 嵌套對象屬性;標識符允許 [A-Za-z0-9_$ 以及 BMP 非 ASCII]
方括號索引 items[0] 數組索引,必須是安全整數
方括號屬性 items['key'] / items["key"] 含特殊字符的屬性名
通配符投影 items[*].name 僅作用於數組,提取元素上的屬性
組合嵌套 a.b[0].c.d 以上寫法可以組合

測試裏還能看到:空查詢返回整個輸入;中文鍵名如 數據.名稱 可以走點號訪問;items[*] 沒有後續路徑時,返回數組裏的全體元素。

有意和標準 JMESPath 不一致、並且已經鎖定的語義包括:

  • 多級通配符 items[*].tags[*] 返回嵌套數組,例如 [['a','b'],['c']],不做標準投影扁平化。
  • 通配符只作用於數組,不支持按對象字段枚舉。
  • 投影時,非對象元素會跳過;屬性缺失(MISSING_PROPERTY)也會跳過;合法的 null 結果會保留。
  • 類型錯誤、越界、非法查詢會拋出,不會在投影裏被吞掉。
  • 引號屬性支持 \\\'\" 三種轉義;非法轉義報錯。

過濾器 [?downloads > 1000]、管道 | 和函數調用都不支持。README 的建議是:這類低頻場景繼續用 bash 加 node 兜底。

安全邊界

解析器是手寫遞歸下降,源碼註釋寫明不用 eval / new Function;讀取屬性時用 Object.hasOwn,訪問 constructor / __proto__ 不會順着原型鏈走。測試裏對這兩類鍵名都按「屬性不存在」處理。

資源上限在對象輸入和字符串輸入兩條路徑上統一執行,倉庫 README 與 src/query.ts 一致:

  • 查詢表達式長度不超過 200 字符,解析深度不超過 20 層
  • 字符串輸入不超過 1,000,000 字節(UTF-8);輸入嵌套深度不超過 100
  • 單次通配符投影不超過 100,000 個元素
  • 輸出還有 4 MB 的保險絲(JSON.stringify 後的 UTF-8 字節數)

每次查詢前會對輸入做全量校驗(類型、深度、字節、循環、枚舉性)。這是有意的安全成本:即使只取一個小字段,也會先完整掃描輸入。README 特別寫明:timeoutMs 中斷不了這段同步校驗。

錯誤類型是 JsonQueryError,帶統一的 json: 前綴,分類爲 MISSING_PROPERTYTYPE_MISMATCHINDEX_OUT_OF_BOUNDSINVALID_QUERY

安裝與啓用

目錄頁給出的安裝命令如下,在 DeepSeek Harness 終端裏運行即可:

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

dsh CLI 會從 GitHub 解析插件並裝進當前配置。如需可復現安裝,目錄頁要求固定 commit 哈希,寫法是:

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

截至 2026-08-18,倉庫 main 最新提交是 902bdf60da4d85bc014e46d32070970a62bb5532(2026-08-14)。固定到這一次可以寫成:

dsh plugin add github:omdsh-dev/dsh-tool-json#902bdf60da4d85bc014e46d32070970a62bb5532

倉庫 README 推薦按 profile 安裝。DSH 0.1.0-rc.6 下,web 和 headless 是兩套不同的配置:

# 交互式(web)profile
dsh plugin --profile web add github:omdsh-dev/dsh-tool-json

# 一次性任務(headless)profile;dsh run 默認走 headless
dsh plugin --profile headless add github:omdsh-dev/dsh-tool-json

包內的 dsh.bundle.patch 指向 cordis.patch.yml,安裝後會往 profile 的 layer stack 插入 tool-json 條目。patch 必須用 - insert: 列表包裹;寫成裸的 - id: 會報 entry not found

驗證 web profile 是否裝上:

dsh --profile web --dump-config | grep tool-json

README 還提供了本地 npm pack 再按 tarball 安裝的路徑,以及把源碼拷進 DSH monorepo 的舊快照調試步驟。日常使用按上面的 GitHub 源即可。啓動 DSH 時,官方倉庫建議用 npx -p @deepseek-ai/dsh@0.1.0-rc.6 dsh web 這類指定版本的方式,不要 install -g 全局安裝。

典型用法

倉庫 README 給出的調用形態是:

json { input: <JSON>, query: "items[0].name" }        → "hello"
json { input: <JSON>, query: "items[*].name" }         → ["a", "b"](合法 null 保留)
json { input: <JSON>, query: "items['complex-key']" }  → "ok"

裝到 headless profile 之後,可以用一次任務做冒煙:

dsh run "使用 json 工具查詢 {"a":{"b":1}} 的 a.b"

下面幾個例子來自倉庫測試,便於對照語義,而不是額外編出來的業務故事。

點號和數組下標:

input:  {"foo":{"bar":42},"items":[{"name":"a"},{"name":"b"}]}
query:  foo.bar              → 42
query:  items[0].name        → "a"
query:  items[1].meta.version  (若該元素帶 meta.version)

數組投影。items 裏如果混有數字或 null,這些非對象元素會被跳過;缺 name 的對象也會跳過;值爲 nullname 會保留:

query:  items[*].name

特殊鍵名用方括號:

query:  ['complex-key']

字符串輸入同樣可以:

input:  "{\"a\":1}"
query:  a                    → 1

插件是隻讀的,不能改 JSON 字段。README 寫明:原地修改繼續用 str_replace_editor / write;倉庫把 set 模式列爲以後可能考慮的方向,當前版本沒有。

適用場景與注意事項

比較適合這些情況:

  • 智能體拿到 API、配置或上游工具的 JSON 後,只需要按路徑取出某個字段或一組字段
  • 希望查詢走結構化路徑,而不是用 grep 在整段文本里碰同名鍵
  • 不想爲一次取值再拉起 jqnode -e

不適合、或需要自己兜底的情況:

  • 要按條件過濾([?...])、管道或 JMESPath 函數
  • 指望多級通配符自動扁平化
  • 需要改寫 JSON
  • 輸入可能超過 1 MB、嵌套超過 100 層,或單次數組投影超過 10 萬元素

安裝前還有幾條需要自己覈對:

  1. 插件以當前 dsh 進程的權限運行,安裝時可能執行代碼。目錄頁和 GitHub 源碼、MIT 許可證都要先看過再裝。
  2. 包名帶 @deepseek-ai/ 前綴,只說明它按官方工具包的命名習慣接入 Cordis,不代表官方維護。
  3. web 裝上不會自動出現在 headless 裏;dsh run 默認用 headless。兩邊都要用,就兩邊都裝。
  4. DeepSeek Harness 仍是開發者預覽,官方 README 寫明會有破壞兼容性的變更。本插件明確對齊的是 npm 線上的 0.1.0-rc.6。

小結

dsh-tool-json 給 DSH 補的是一件很具體的能力:在進程內按路徑讀 JSON,語法小、依賴爲零,並且把長度、深度、原型鏈和輸入形態都收在明確上限裏。它不是通用 JMESPath 引擎,也不改數據。若日常只是讓智能體從工具輸出裏取出 items[0].nameitems[*].id,這個插件的範圍和目錄頁上的安裝命令是對齊的。

目錄頁:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-tool-json/

GitHub:https://github.com/omdsh-dev/dsh-tool-json

羽毛球分组比赛记分
小程序二维码

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

小夜