← 返回列表
未验证
用于 DeepSeek HarnessDSH的哈希锚定 read、edit 和 grep…
尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/8/14 · 已提供中文文档
为 DeepSeek Harness 提供的哈希锚定读取/编辑/grep 工具:每一行都带有内容哈希,过期的锚点在触碰文件之前就会被拒绝。
综合分
27.7
GitHub 分
27.7
用户评分
—
★ Stars
2
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add InklingYoshi584/dsh-tool-hashline该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
信任档位:仅索引本站尚未对其实装验证,仅收录元数据
- 是什么
- dsh 原生插件 · chat
- 装得上吗
- 本站尚未做安装检查
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 更新放缓:最近一次提交在 42 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
数据截至 2026/9/21(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-fs@deepseek-ai/dsh-fs-local@deepseek-ai/dsh-fs-observation-policy@deepseek-ai/dsh-llm@deepseek-ai/dsh-subprocess@deepseek-ai/dsh-subprocess-local@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh-tools@deepseek-ai/schemastery用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-tool-hashline
用于 DeepSeek Harness(DSH)的哈希锚定 read、edit 和 grep 工具。每一行都带有一个简短的内容哈希;编辑操作引用 LINE#HASH 锚点,这些锚点在写入任何内容之前都会根据文件的当前内容进行校验。过期的锚点会导致整个调用失败——绝不重新定位,绝不模糊匹配,绝不静默地应用到错误的行。
协议采用自 pi-hashline-edit(MIT),灵感来自 oh-my-pi。
如何安装
前置条件
- Node.js ≥ 20(用于运行 dsh 和该插件)。
- dsh。有两种获取方式:
- 无需安装:npx @deepseek-ai/dsh —— 注意裸命令始终需要一个 profile:npx @deepseek-ai/dsh web 或 npx @deepseek-ai/dsh --profile headless "task"。
- 全局安装(在 PATH 上提供裸 dsh 命令,同时一并安装 pnpm):npm i -g pnpm @deepseek-ai/dsh。
- pnpm —— dsh plugin 命令会转发给它(由上面的全局命令安装)。
- 用于实时会话的 DeepSeek API key(在 Web UI 的 Settings → Models 中配置,或导出 DEEPSEEK_API_KEY)。
第 1 步 —— 获取插件
选项 A:npm(推荐) —— 已发布到 registry,安装预构建的 lib/ 包:
dsh plugin --profile web add dsh-tool-hashline
…or without a global dsh:
npx @deepseek-ai/dsh plugin --profile web add dsh-tool-hashline
选项 B:从源码安装(开发):
git clone https://github.com/InklingYoshi584/dsh-tool-hashline.git
cd dsh-tool-hashline && npm install
这里的 @deepseek-ai/ harness 包有意作为 dev 依赖:在运行时,插件通过 profile 维护的扁平回退($DSH_HOME/profiles/node_modules 符号链接)从 dsh 安装中解析它们,因此插件永远不会附带重复的 harness 核心。npm install 只需为测试成功即可;运行插件只需要 preset 行。
第 2 步 —— 编写 hashline preset
该插件通过 preset 平面遮蔽替换原装工具:一个挂载此插件而非 tool-fs 的 preset,会为其会话提供 hashline 的 read/edit/grep,而其他一切仍从宿主组合中正常工作。通过将随附文件放入用户 preset 根目录来创建 preset(手动创建的 preset 会被实时发现):
mkdir -p "$DSH_HOME/.agent-presets/hashline"
cp preset/agent.cordis.yml "$DSH_HOME/.agent-presets/hashline/"
cp preset/preset.yml "$DSH_HOME/.agent-presets/hashline/"
…或使用 Web UI(Settings → presets → 将 standard 复制为 hashline),并用随附模板替换复制出的组合。
然后编辑 $DSH_HOME/.agent-presets/hashline/agent.cordis.yml 中的插件行,使其指向你的安装位置:
npm install:
- id: tool-hashline
name: 'dsh-tool-hashline'
from source (Windows needs the file:/// URL form):
- id: tool-hashline
name: 'file:///C:/path/to/dsh-tool-hashline/src/index.ts'
要同时启用 grep,请在该行添加 config: { grep: true }。
第 3 步 — 选择预设
设置 → 预设 → hashline,或在 $DSH_HOME/settings.yaml 中设置默认值:
agent-presets:
default: hashline
新会话现在运行在 hashline 上。已在运行的会话保持其原有组合 — 只有新会话会采用该预设。
第 4 步 — 验证其是否生效
1. 在会话中:读取任意文本文件 — 输出行带有 LINE#HASH: 标记( 1#PK:alpha)。
2. 让 agent 编辑某些内容 — 调用会携带 edits: [{op, pos: "N#HASH", …}],结果会返回一个 --- Anchors --- 块。
3. 设置 → Agent 预设应显示 “使用中:Hashline”。
替换会带来什么变化
在 hashline 预设上,read/edit(以及启用时的 grep)是 hashline 版本 — 预设的作用域层会按名称遮蔽全局的 tool-fs/tool-fs-search 工具。write、read_image、glob、bash 以及其他所有内容仍从宿主组合中正常工作,子 agent 会继承该预设。
无头 / 无名单部署
headless 配置文件不组合任何预设名单。请改用带宿主平面替换的 --patch 覆盖:
hashline.patch.yml
- id: tool-fs
disabled: true
- id: tool-fs-search
disabled: true
- insert:
- id: tool-hashline
name: 'file:///C:/…/src/index.ts'
config:
grep: true
npx @deepseek-ai/dsh --profile headless --patch ./hashline.patch.yml "your task"
为什么要使用它
AI 编程 agent 通过引用它们在屏幕上看到的内容来编辑文件。在编辑时,有两件事可能为真:文件自读取以来已发生变化(并发写入、漂移、同一轮中较早的编辑),并且引用的文本出现在不止一个位置。现成的编辑工具处理得很糟糕:
- 字面字符串替换(old_string/new_string,DSH 所提供的方式)要求引用的文本恰好匹配一次。任何漂移都意味着重试循环;歧义则意味着“让它更具体”的繁琐工作。
- 行号编辑更糟:在任何偏移之后,数字会悄无声息地指向错误的行,而且编辑会破坏模型从未查看过的代码。
- 这个问题足够真实,以至于 Cursor 专门训练了一个 70B 模型,只是为了正确地应用编辑。
证明 harness — 而非模型 — 才是杠杆的证据:Can Balioglu 的基准测试 固定了 15 个模型,只替换了编辑格式。Hashline 在 16 种配置中的 14 种上击败了 patch,而且最弱的模型获益最多。更好的锚定拯救了那些你原本会放弃的长尾模型。
Hashline 改变了什么:
| 属性 | 现成的 edit | hashline |
|---|---|---|
| 锚点 | 字面 old_string 文本 | LINE#HASH 内容哈希 |
| 文件自读取以来发生漂移 | 报错,用新文本重试 | 报错并指出过期的锚点,重新读取,重试 |
| 同一行文本出现两次 | 歧义,“请更具体” | 上下文哈希使碰撞很少见;歧义会列出候选 |
| 多个 hunk | 每个 hunk 一次调用 | 一次调用中 N 个操作,一个快照,一次原子写入 |
| 编辑之后 | 重新读取文件 | 新的 --- Anchors --- 块 → 无需重新读取即可链式编辑 |
| 搜索到编辑 | grep,然后打开,然后引用 | grep 返回相同的锚点 → 无需读取即可编辑 |
在此基础上,DSH 自身的观察策略仍然有效:写前读取和文件级版本 CAS 仍然保护整个文件,而锚点保护行。你同时获得行级正确性和文件级新鲜度。
演示
$ read e2e/probe/notes.txt
…/notes.txt
file
1#PK:alpha
2#YB:beta
3#VZ:gamma
4#WX:delta
5#XJ:epsilon
6#BK:zeta
7#XP:eta
8#KR:theta
(End of file - total 8 lines)
一次 edit 调用,四个操作,一个快照:
{
"file_path": "e2e/probe/notes.txt",
"edits": [
{ "op": "replace", "pos": "2#YB", "lines": [] },
{ "op": "append", "pos": "3#VZ", "lines": ["BETA-NEW"] },
{ "op": "replace", "pos": "4#WX", "lines": ["DELTA"] },
{ "op": "replace", "pos": "5#XJ", "end": "6#BK", "lines": ["EPSILON-ZETA"] }
]
}
The file …/notes.txt has been updated: 4 edit(s) applied.
--- Anchors 1-6 ---
1#ZP
2#XZ
3#BY
4#RJ
删除 beta,在 gamma 之后插入 BETA-NEW,重写 delta,并将两行范围 epsilon…zeta 合并为一行——全部基于编辑前的内容进行验证,并在一次写入中提交。新的锚点块无需重新读取即可驱动下一次编辑。
工具
read
带行号的 UTF-8 内容,每行一个哈希。该哈希覆盖该行的上下文三元组(prev + curr + next),因此不同上下文中的相同行会有不同的哈希,并且编辑第 N 行只会使第 N−1、N、N+1 行的锚点失效。
| 参数 | 含义 |
|---|---|
| file_path | 路径,相对于会话工作区解析 |
| offset, limit | 基于 1 的窗口(默认 2000 行,受字节数上限限制) |
| raw | 不带标签的纯内容 |
edit
| 操作 | 锚点 | 效果 |
|---|---|---|
| replace | pos(或 pos + end) | 用 lines 替换一行或包含端点的范围;lines: [] 表示删除 |
| append | pos(省略 → EOF) | 在 pos 之后插入 lines |
| prepend | pos(省略 → BOF) | 在 pos 之前插入 lines |
| replace_text | 唯一的 old_text | 字面子串替换(默认关闭:仅锚点) |
规则:每个操作都基于同一个编辑前快照进行验证;重叠操作会被拒绝(HASHLINE_INVALID_PATCH);lines 必须是字面内容——hashline 前缀或 diff 标记会被拒绝;成功的编辑会返回更改区域的新锚点;无操作会发出警告,连续三次相同的无操作会引发 HASHLINE_NOOP_LOOP。
grep(可选启用,grep: true)
使用打包的 ripgrep 二进制文件进行搜索——无需系统 rg。匹配的行以相同的 LINE#HASH 锚点返回,匹配的文件被记录为已读取,因此锚点可直接供 edit 使用,无需事先 read。参数:pattern(正则表达式,除非 literal: true)、path、glob、ignore_case、context(0–5)、limit(默认 50,最大 200)。遵循 .gitignore。
错误
失败时提供稳定的 {name, code} 元数据:
| 代码 | 触发条件 |
|---|---|
| HASHLINE_STALE_ANCHOR | 锚点哈希不再与其行匹配 |
| HASHLINE_AMBIGUOUS | 哈希匹配多行(列出候选项) |
| HASHLINE_INVALID_PATCH | 重叠操作,或非字面量 lines |
| HASHLINE_NOOP_LOOP | 连续三次相同的无操作编辑 |
| FS_NOT_OBSERVED / FS_STALE_VERSION | DSH 策略门控,与 stock 一致,附带重新读取的补救措施 |
协议如何工作
- 哈希字母表 ZPMQVRWSNKTXJBYH(16 个视觉上可区分的字符,每个 4 位),默认长度 2(可配置 2–4)。对 UTF-8 上下文三元组进行 FNV-1a,跨平台确定性。
- 上下文失效:编辑第 N 行只会改变 N−1、N、N+1 的哈希——正是每次编辑后重新锚定的区域。
- 严格性:不匹配的锚点会使整个调用失败。绝不重新定位到“足够接近”的行——该工具以便利换取正确性。
- 文件级安全网:每次变更仍然经过 DSH 的 fs/edit-intent → 版本 CAS 写入,因此验证与写入之间的并发修改会被捕获为 FS_STALE_VERSION。
配置
全部可选(位于预设行的 config 上):
| 键 | 默认值 | 含义 |
|---|---|---|
| hashLength | 2 | 每行的哈希字符数(2–4);更长 → 更少冲突,更多 token |
| replaceText | false | 允许字面量 replace_text 操作 |
| grep | false | 注册哈希锚定的 grep 工具 |
| readLimit | 2000 | 每次 read 的最大行数 |
| readMaxLineLength | 2000 | 截断前每行的字符数 |
| readMaxBytes | 51200 | 每个 read 窗口的字节上限 |
| readStreamMinSize | 10485760 | 达到/超过此大小的文件以流式处理 |
组合陷阱(已针对已发布的 dsh 验证)
- 配置文件 cordis.patch.yml 中按 id 定位的覆盖是裸顶层条目(- id: tool-fs + disabled: true,没有 name);在 insert: 列表中重新声明 name 会创建一个新行,加载器会失败并报 duplicate loader entry id。
- 补丁行中的绝对插件路径在 Windows 上必须是 file:/// URL;裸驱动器路径会失败并报 ERR_UNSUPPORTED_ESM_URL_SCHEME。
- 注册表会在同一作用域层内对同名工具抛出错误——预设平面的遮蔽才是实现替换的原因,而不是重新注册。
仓库布局
src/hash.ts 哈希核心:FNV-1a、上下文三元组、锚点格式化/解析(无依赖)
src/render.ts 读取窗口化、字节上限、带标签信封(无依赖)
src/edit-engine.ts 操作解析、严格验证、自底向上应用(无依赖)
src/grep-engine.ts rg argv、NDJSON 解析、区域渲染(无依赖)
src/read.ts read 工具(ctx.fs + fs/observed)
src/edit.ts edit 工具(fs/edit-intent + 版本-CAS 写入)
src/grep.ts grep 工具(ctx.subprocess + 打包的 rg)
src/prompts/.ts 模型引导部分(即“提示注入”)
src/index.ts 插件契约:name/inject/Config/apply
preset/ 即插即用的 hashline 预设模板
tests/ 105 个测试:基于真实 fs-local、策略和 ripgrep 的单元 + 集成测试
限制
- 过期锚点会失败,不会自愈。 pi-hashline-edit 的三方快照合并恢复(ADR 0004/0005)被有意推迟;该工具会返回清晰的重新读取指引。快照和合并恢复是自然的 v2。
- 2 字符哈希是 256 个桶。 上下文哈希加上歧义拒绝使碰撞罕见且安全(它们会报错,绝不会误用),但对于非常大或非常均匀的文件,可以使用 hashLength: 3 或 4。
- 开发预览版变动。 基于 DSH v0.1 构建(源码 @ 47f943,npm @deepseek-ai/dsh-* rc.1/rc.5)。DeepSeek 警告该预览版会破坏兼容性——升级时请固定版本并重新验证。
开发
npm install
npm run check # 类型检查 + 105 个测试
npm run build # lib/index.js —— npm 包发布的内容
致谢
pi-hashline-edit 提供了协议(上下文哈希、操作集、严格锚点、grep 锚点循环),oh-my-pi 提供了 hashline 技术,Can Balioglu 证明了 harness 问题。
许可证
MIT