前言¶
DeepSeek Harness(命令名 dsh)是 DeepSeek AI 开源的智能体运行时,目前仍是开发者预览。官方仓库 deepseek-ai/deepseek-harness 写明核心理念是「一切皆插件」:模型、工具、技能、会话、沙箱和界面都可以在配置层替换,不必改核心源码。社区里还有一份独立的插件目录站点 deepseek-harness-plugin.com,它和 DeepSeek / 幻方没有官方从属关系,不能当成官方应用商店。
智能体处理 JSON 是高频操作。API 返回值、配置文件、其他工具的输出,几乎都是 JSON。常见做法是起一个 bash 进程去跑 node -e 或 jq,每次都有进程开销,还要把对象先序列化成字符串。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.json 的 name 都是 @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() 统一校验:
- 对象直传:模型直接生成 JSON 参数,少一层转义。
- 字符串透传:bash、
read等拿到的原文可以原样送进来,内部先JSON.parse。
两种路径都会做 JSON 兼容性检查。只接受 null、布尔、有限数字、字符串、数组和纯对象;undefined、BigInt、函数、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_PROPERTY、TYPE_MISMATCH、INDEX_OUT_OF_BOUNDS、INVALID_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 的对象也会跳过;值为 null 的 name 会保留:
query: items[*].name
特殊键名用方括号:
query: ['complex-key']
字符串输入同样可以:
input: "{\"a\":1}"
query: a → 1
插件是只读的,不能改 JSON 字段。README 写明:原地修改继续用 str_replace_editor / write;仓库把 set 模式列为以后可能考虑的方向,当前版本没有。
适用场景与注意事项¶
比较适合这些情况:
- 智能体拿到 API、配置或上游工具的 JSON 后,只需要按路径取出某个字段或一组字段
- 希望查询走结构化路径,而不是用
grep在整段文本里碰同名键 - 不想为一次取值再拉起
jq或node -e
不适合、或需要自己兜底的情况:
- 要按条件过滤(
[?...])、管道或 JMESPath 函数 - 指望多级通配符自动扁平化
- 需要改写 JSON
- 输入可能超过 1 MB、嵌套超过 100 层,或单次数组投影超过 10 万元素
安装前还有几条需要自己核对:
- 插件以当前 dsh 进程的权限运行,安装时可能执行代码。目录页和 GitHub 源码、MIT 许可证都要先看过再装。
- 包名带
@deepseek-ai/前缀,只说明它按官方工具包的命名习惯接入 Cordis,不代表官方维护。 - web 装上不会自动出现在 headless 里;
dsh run默认用 headless。两边都要用,就两边都装。 - DeepSeek Harness 仍是开发者预览,官方 README 写明会有破坏兼容性的变更。本插件明确对齐的是 npm 线上的 0.1.0-rc.6。
小结¶
dsh-tool-json 给 DSH 补的是一件很具体的能力:在进程内按路径读 JSON,语法小、依赖为零,并且把长度、深度、原型链和输入形态都收在明确上限里。它不是通用 JMESPath 引擎,也不改数据。若日常只是让智能体从工具输出里取出 items[0].name 或 items[*].id,这个插件的范围和目录页上的安装命令是对齐的。
目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-tool-json/
GitHub:https://github.com/omdsh-dev/dsh-tool-json