前言¶
智能体要对比两份内容时,常见路径是起一个 bash 进程去调系统 diff,或者自己写一段比较逻辑。配置片段、API 响应、表格、文档修订都经常碰到这件事。系统 diff 只看整段文本:JSON 里改了 $.user.name,输出往往是大块加减行,看不出路径;CSV 引号里的逗号、Markdown 标题改名,手写比较又容易漏。Windows 上每次起进程的开销也更明显。
DeepSeek Harness(dsh)把模型、工具、会话和界面都做成插件,官方仓库的说法是 Everything is a Plugin(一切皆插件)。社区因此补了一批给模型调用的确定性工具。dsh-tool-diff 做的事情很具体:在进程内对文本、JSON、CSV、Markdown 做结构化比较,输出 unified diff 或带路径的变更列表,不读盘、不写盘、不联网。
需要先分清来源。DeepSeek Harness 本体在 deepseek-ai/deepseek-harness。deepseek-harness-plugin.com 是独立的社区插件目录,About 页写明与 DeepSeek / 幻方没有官方从属关系,不能当成官方应用商店。本文按目录详情页、GitHub 仓库 README / package.json / LICENSE,以及官方 Harness 仓库交叉核对,核实日期为 2026-08-18。
这是什么¶
dsh-tool-diff 是一款「工具与能力」插件,由 GitHub 组织 omdsh-dev 维护,源码在 omdsh-dev/dsh-tool-diff,许可证 MIT,主要语言 TypeScript。查阅时目录页与 GitHub 均显示 4 星;package.json 里的包名是 @deepseek-ai/dsh-tool-diff,版本 0.0.1,并标了 "private": true,安装走 GitHub 源,不是公开 npm 包。engines 要求 Node.js ^22.19.0 || >=24.0.0。
它向模型注册名为 diff 的工具,profile 里的 row id 是 tool-diff。输入是两段字符串 before / after,按 action 走不同比较器,统一吐出一段 JSON 文本信封。仓库 README 把定位写成:零依赖、纯函数、只读。
它要解决的是这三类麻烦:
- 不要为一次比较再起系统进程
- 让 JSON / CSV / Markdown 的变更落到路径或行列上,而不只是整段文本 diff
- 比较逻辑可复现、有边界:输入超限直接报错,输出超限截断并置
truncated
README 写明已在 @deepseek-ai/dsh@0.1.0-rc.6 的隔离 consumer 里做过全链路验证:配置 dump 能看到该插件 row,工具能注册并执行。这是仓库自己的验证记录,不是第三方评测。
核心功能¶
安装后只有一个工具:diff。用 action 区分五种比较,所有 action 的信封都带 { equal, truncated, beforeBytes, afterBytes, changes }。
| action | 作用 | 输出要点 |
|---|---|---|
text |
行级 Myers diff | 默认 unified diff(--- before / +++ after / @@ hunk,无时间戳)加统计;format=structured 则给带行号的操作列表 |
json |
递归比较两个 JSON 值 | $ 路径化变更,如 $.user.name、$.items[0]、$['a.b'],并汇总 add / remove / replace |
csv |
按 RFC 4180 解析后再比 | addedRows / removedRows / changedRows(列级)/ duplicateKeys / 列集合变化 |
markdown |
轻量块级 tokenizer | headingChanges(含 rename)/ blockChanges(如 h2[1]/p[0])/ codeBlockChanges,外加全文 diff |
patch |
生成 unified diff 并在内存中校验 | patch 文本 + valid / hunks / targetMatchesAfter / hunk 级错误 |
常用参数如下,均来自仓库 README:
before/after:两侧内容,任意 action 都要给format:unified(text / patch 默认)、structured(json / csv / markdown 默认)、bothcontext:unified 上下文行数,默认 3,范围 0..20key:CSV 主键列名或从 1 起的列号;不给就按行号位置比较delimiter:CSV 分隔符,默认,,也可写tabignoreWhitespace/ignoreCase:比较时忽略空白或大小写;patch会拒绝这两个选项,因为补丁必须是精确文本协议sortKeys:JSON 键排序,默认true,让变更列表稳定maxChanges:最多报告多少条变更,默认 1000,硬顶 10000
安全模型是这条插件的重点,README 写得很死:
- 零依赖:Myers 行级 diff、RFC 4180 解析、JSON 递归比较都是手写实现,不拉第三方比较库
- 只读:不读文件、不写文件、不联网、不调 git;
patch只在内存里生成并校验补丁,绝不落盘 - 预算:单侧输入 ≤ 256 KiB(超限直接报错);输出 ≤ 64 KiB(超限按
maxChanges和字节预算截断,并置truncated);行数 ≤ 50K;JSON 嵌套 ≤ 64 层;CSV ≤ 50K 行 / 512 列;timeoutMs: 2000 - Myers 还有 diagonal 预算 2000、蛇步总预算 2000 万、公共前后缀修剪和 4000 行规模上限,避免恶意重复或全异文本把进程拖死
- 工具参数会记入会话日志,不要把密钥、token 这类敏感数据当作
before/after传进去
设计上还有几条边界,用的时候会对上输出:
- CSV 给了
key且有表头,就按主键比,行顺序无关;否则按数据行号。两侧重复 key 都进duplicateKeys,且equal=false,这些行不参与匹配 - JSON 在
JSON.parse前先做非递归括号扫描,超过 64 层直接报错;重复键由状态机扫出来,写进duplicateKeys.before/after,不会静默丢掉 - Markdown 按块类型做 Myers:同型块内容变化是
replace,结构增删是add/remove;同路径同级别标题文本变化记为rename patch里equal只表示两侧在精确行和末尾换行语义下相等,和valid无关;valid只表示生成的 patch 能从before应用到after。补丁被截断时是valid:false且patchComplete:false- 入口会拒绝孤立 surrogate,报
invalid Unicode - unified diff 不带时间戳,方便复现
仓库 README 写明测试用 vitest,当前有 124 个用例。peer 依赖是 @deepseek-ai/cordis ^4.0.1、@deepseek-ai/dsh-tools 与 @deepseek-ai/dsh-invariants(>=0.0.1-rc.1 <0.2.0),由 profile 的 profiles/node_modules 回退安装提供,插件自身不再依赖未加 scope 的 cordis。
安装与启用¶
目录页给出的安装命令如下,在 DeepSeek Harness 终端里运行即可:
dsh plugin add github:omdsh-dev/dsh-tool-diff
目录页同时写了:插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前请检查源代码仓库和许可证;需要可复现安装时,固定 commit 哈希。写法是把 #commit 换成仓库里的完整哈希。查阅时 main 最新提交是 73c142e262275c5a278dc31e80bac7966fba168e(2026-08-14):
dsh plugin add github:omdsh-dev/dsh-tool-diff#73c142e262275c5a278dc31e80bac7966fba168e
仓库 README 推荐按 profile 安装。web 是交互式界面,headless 给 dsh run 用,两者互不覆盖:
# 交互式(web)profile
dsh plugin --profile web add github:omdsh-dev/dsh-tool-diff
# 一次性任务(headless)profile —— dsh run 默认使用 headless
dsh plugin --profile headless add github:omdsh-dev/dsh-tool-diff
也可以先 npm pack 再装本地 tarball:
git clone https://github.com/omdsh-dev/dsh-tool-diff
cd dsh-tool-diff
npm install && npm pack
dsh plugin --profile web add ./deepseek-ai-dsh-tool-diff-*.tgz
dsh plugin --profile headless add ./deepseek-ai-dsh-tool-diff-*.tgz
包内 dsh.bundle.patch(对应仓库里的 cordis.patch.yml)会在安装后把插件插入 profile 的 layer stack,id 为 tool-diff。Windows 路径要用正斜杠,例如 C:/...。
验证安装:
dsh --profile web --dump-config | grep tool-diff
README 给的运行验证句是:
dsh run "使用 diff 工具对比两段文本"
注意:dsh run 默认走 headless。只装了 web、没装 headless 时,这条命令看不到工具。README 还提示启动用 npx -p @deepseek-ai/dsh@0.1.0-rc.6 dsh web,不要 npm install -g 全局安装。手动改 profile 层、本地 junction / symlink 只适用于源码贡献或旧 snapshot,日常安装用上面的 bundle 即可。
典型用法¶
装好之后,模型调用 diff,把 action、before、after 传进去。仓库没有再给一套逐步点击的界面教程,下面的输出和验证句都直接来自 README。
1. JSON 路径级变更¶
action=json 时,默认 format=structured。README 的示例信封如下:
{"kind":"json","equal":false,"beforeBytes":42,"afterBytes":58,"changes":[
{"op":"replace","path":"$.tags[1]","before":"b","after":"c"},
{"op":"add","path":"$.user.email","after":"b@x.com"},
{"op":"replace","path":"$.user.name","before":"Alice","after":"Bob"}],
"summary":{"added":1,"removed":0,"replaced":2,"moved":0}}
对照这份输出可以读出三件事:$.tags 数组第 1 项从 b 换成 c;$.user 下新增 email;name 从 Alice 换成 Bob。系统 diff 通常只会给你前后两段 JSON 的行级加减,不会给出这些路径。
sortKeys 默认打开,同一组变更的列表顺序稳定,方便写断言或把结果再交给后续步骤。
2. 文本 unified diff¶
action=text 默认 format=unified。输出是标准 unified diff,文件头固定写成 --- before / +++ after,hunk 带 @@,没有时间戳。需要给模型看「第几行发生了什么」时,把 format 改成 structured。上下文行数用 context 控制,默认 3 行。
只关心逻辑是否相同、空格和大小写可以忽略时,打开 ignoreWhitespace 或 ignoreCase。这两个开关对 text / csv / markdown 有效;patch 会拒绝,不要混用。
3. CSV、Markdown 和内存补丁¶
表格对齐用 action=csv。有稳定主键(例如 id 列)时把 key 设成列名,行被打乱也能对上;没有主键就按行号比。分隔符不是逗号时改 delimiter,制表符写 tab。
文档修订用 action=markdown。它先按标题、代码块、列表、引用、表格切成块,再做块级 Myers:标题改名会进 headingChanges 的 rename,代码块的语言、行数或内容变化进 codeBlockChanges。
需要一张能从 before 应用到 after 的补丁、但又不想改磁盘文件时,用 action=patch。返回值里看 valid 和 hunks;被输出预算截断时不要拿这份 patch 当真补丁。README 明确写了:补丁只在内存中生成和校验,不会落盘,也不会调用 git。
日常冒烟可以用仓库给的这一句,确认工具已注册:
dsh run "使用 diff 工具对比两段文本"
适用场景与注意事项¶
适合这些情况:
- 智能体要对比配置片段、API 响应、CSV 导出或 Markdown 文档,需要路径 / 行列级变更,而不是整段文本 diff
- 希望比较发生在 dsh 进程内,不额外起
diff/git子进程 - 需要 unified diff 或内存中的 patch 校验,但不允许插件改工作区文件
使用时注意下面几条,都来自目录页或仓库 README,不是额外发挥:
- 先看源码和许可证再装。 目录页写明:插件以当前
dsh进程的权限运行,安装时可能执行代码。本插件自称只读,仍应按第三方代码对待。 - 社区目录不等于官方商店。 deepseek-harness-plugin.com 是独立站点,与 DeepSeek / 幻方无从属关系。
- web 和 headless 要分别装。 只给 web 装,
dsh run默认的 headless profile 里没有这个工具。 - 输入输出都有硬顶。 单侧超过 256 KiB 会直接失败;输出超过 64 KiB 会截断。大文件应先自己切片,不要指望一次塞进工具。
- 不要传入敏感数据。 参数会进会话日志。
patch不是落盘补丁工具。 它不写文件、不调 git;ignoreWhitespace/ignoreCase也不能用在patch上。- 运行时版本。 README 验证线是
@deepseek-ai/dsh@0.1.0-rc.6;package.json要求 Node.js 22.19+ 或 24+。更旧的 snapshot 可能要走仓库说的手动安装路径。 - 包名带
@deepseek-ai/,并不表示官方插件。 这是社区仓库omdsh-dev/dsh-tool-diff的 npm 包名,且private: true。
小结¶
dsh-tool-diff 给 DeepSeek Harness 注册了一个只读的 diff 工具:文本走 Myers 行级比较,JSON 给出 $ 路径,CSV 按主键或位置对齐,Markdown 按块对齐,需要时再在内存里生成并校验 unified patch。比较逻辑零依赖、有输入输出预算,不碰磁盘和网络。对经常让智能体核对配置、接口返回和文档修订的人来说,它补的是「系统 diff 看不懂结构、手写比较又难验证」这一截。
目录页与源码:
- 插件目录:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-tool-diff/
- GitHub 仓库:https://github.com/omdsh-dev/dsh-tool-diff
- DeepSeek Harness 官方仓库:https://github.com/deepseek-ai/deepseek-harness