dsh-better-edit:用內容哈希錨定 DSH 的文件讀寫與編輯

前言

在 DeepSeek Harness(DSH)裏跑編碼 Agent,文件編輯往往是 token 消耗和出錯的重災區。常見的 str_replace 或按行號定位,要求模型在輸出裏逐字複述要被替換的舊代碼——這部分是輸出 token,計費通常是輸入的約 5–6 倍。上方多插入一行,下方行號整體偏移,改錯行的風險隨之上升,且工具側往往缺少「這段範圍是否就是模型剛纔看到的內容」的校驗。

下面介紹 dsh-better-edit(維護者 Rianico)。它爲 DSH 提供基於內容哈希(hashline)的 readeditundo_last_edit 工具:每行分配一個 3 字符哈希作爲地址,編輯時只傳起止哈希和替換文本,不回顯舊內容;範圍在寫入前對照模型已讀狀態校驗,過期或未見行直接拒絕並回傳新錨點。項目採用 MIT 許可證,npm 當前版本爲 0.4.0,GitHub 約 15 stars。

這是什麼

dsh-better-edit 是 DSH 的客戶端插件,分類爲「客戶端」。它通過 cordis.patch.yml 掛載到 DSH 運行時,在 agent/session-start 時將 hashline 版 read/edit 註冊到 agent 作用域,從而替換 preset 內置的同名工具,並保留內置 write

與按行號或全文搜索替換不同,hashline 把每一行當作內容尋址:哈希由行內容推導,上方編輯不會使下方未改動行的錨點失效。插件在 SkillHub 社區目錄(skillhub.cn/plugins/Rianico/dsh-better-edit)可檢索;該目錄爲獨立社區站點,與 DeepSeek / 幻方無官方從屬關係。

核心功能

三個工具

工具 作用
read HASH│內容 返回文件,支持 offset(1 起始)、limit 分頁
edit remove_from / remove_to 哈希範圍替換;同文件最多 32 條編輯原子批量
undo_last_edit 撤銷指定路徑的上一次 hashline 編輯,重啓後仍可用

read 展示過的行、diff 回顯行、拒絕並回傳(reject-and-serve)的行,都計入「已提供」狀態。edit 寫入前逐行校驗:從未展示的行觸發 [E_RANGE_UNSERVED],磁盤內容與錨點不一致觸發 [E_RANGE_STALE],批次中任一項失敗則整批不寫([E_BATCH_ABORT])。

相對 str_replace 的差異

README 中的對比要點如下,均來自項目文檔與可復現基準,而非第三方案例:

  • 編輯調用不回顯被替換文本,只傳兩個 3 字符哈希加新內容
  • 錨點爲內容地址,連續編輯時未改動行哈希保持有效,diff 輸出帶新錨點,通常不必每次改完都 read
  • 範圍與模型所見逐行覈對;錯錨點、過期內容在寫入前硬拒絕,並回傳帶新哈希的當前行供重試
  • 對 ASCII 空白變化有一定容忍(如 prettierblack 介入後錨點仍可解析);字符串字面量內的空白不在此列

項目在固定 103 行語料、12 次編輯的 token 基準中報告:相對 str_replace,hashline edit 輸出 token 約省 31%(多行範圍 29–47%);同一外部漂移重構任務中,工具調用約 3 次 vs 6 次(對比 OMP 封裝,方法說明)。確定性正確性電池爲 23/23。本地可運行 npm run benchmark 復現計數部分。

存儲與撤銷

哈希快照、已提供狀態、撤銷歷史默認存放在 central 模式:

$DSH_HOME/plugins/dsh-better-edit/runtime/<name>-<hash8>/hash-store.sqlite

DB 爲可丟棄緩存,刪除後下次 read 會按文件內容重建哈希。撤銷默認 TTL 7 天(undo_ttl_s: 604800-1 爲永久)。

安裝與啓用

環境要求:Node ^22.19.0 || >=24.0.0(DSH 要求,存儲依賴 node:sqlite);已有一個 dsh profile。

任選一種安裝方式:

npx @deepseek-ai/dsh plugin --profile web add github:Rianico/dsh-better-edit   # 從 GitHub
npx @deepseek-ai/dsh plugin --profile web add dsh-better-edit                   # 從 npm
npx @deepseek-ai/dsh plugin --profile web add /path/to/dsh-better-edit          # 從本地源碼

無需額外配置。該 profile 的下一次會話即加載 hashline 工具。驗證插件層是否生效:

dsh --profile <name> --dump-config   # 輸出中應出現 "# == dsh-better-edit" 層

可選配置寫在 $DSH_HOME/plugins/dsh-better-edit/config.yaml,例如存儲位置、撤銷 TTL、central 清理策略。環境變量 DSH_BETTER_EDIT_STORE_DIRDSH_BETTER_EDIT_AUTO_GITIGNORE 可覆蓋 yaml。首次啓動時若文件不存在,插件會生成帶註釋的默認配置,不覆蓋已有文件。

典型用法

讀取:每行帶哈希前綴

read 返回的每一行,行首哈希即該行地址:

ve7│function hello() {
szJ│  console.log("world");
kQm│}

編輯:按哈希範圍定位

下面示例把 szJ 這一行替換爲新內容:

{
  "path": "src/main.ts",
  "edits": [["szJ", "szJ", "  console.log('hi');"]]
}

工具返回 diff,並附帶新錨點,便於鏈式編輯:

- szJ │   console.log("world");
+ a3m │   console.log('hi');
  kQm │ }

同一文件可一次提交多條編輯,全部成功才寫入:

{
  "path": "src/main.ts",
  "edits": [
    ["a1b", "a1b", "new line 1\n"],
    ["c3d", "c3d", "new line 2"]
  ]
}

撤銷

對剛改過的文件調用 undo_last_edit,傳入 { "path": "src/main.ts" }。僅當磁盤內容與上次編輯後快照一致時生效;若中間被外部修改,返回 [E_UNDO_STALE]

適用場景與注意

適合:

  • 長會話中的結構性改動,需要連續多次編輯且不能落錯行
  • 希望減少編輯相關輸出 token、降低 str_replace 式複述成本
  • 文件可能在編輯間隙被格式化工具或外部進程改動,需要過期檢測而非靜默覆蓋

不太適合:

  • 單行微調(token 節省接近持平,README 有說明)
  • 新建文件(繼續用內置 write;插件會在 write 後自動 read 以建立錨點)

安裝前請注意:

  • 插件以當前 dsh 進程權限讀寫工作區與 $DSH_HOME 下的存儲,安裝前應閱讀 源碼MIT 許可證
  • DSH 仍處於開發者預覽階段,插件 README 註明當前針對特定 dsh 版本接線,升級 DSH 後宜重新覈對兼容性
  • 基準數字衡量的是請求負載 token,未完全建模轉錄失敗重試等真實會話成本;正確性優勢需結合具體工作流評估

鏈接

若你已在 DSH 裏反覆遇到行號漂移或 str_replace 複述出錯,可以先按上文命令裝入 profile,用 readedit → 看 diff 新錨點走一遍最小閉環,再決定是否用於日常 Agent 會話。

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

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

小夜