跳到主内容

dsh-file-mount

11Star0Fork0Issue0Watching

为 DeepSeek Harness 提供文件增量挂载:自动记录已读文件哪些行进了模型上下文,重复读取只补缺失或改动的部分,并在 Web 端给出可计账的「挂载文件」仪表盘。

机审证据5/5方法论数据来源安装命令持续维护DSH 版本风险扫描
机审证据安装命令仓库已核验dsh-plugin Topic许可证READMEAI 百科
语言
TypeScript
License
MIT
分支
main
contextcordisdeepseek-harnessdsh-plugin

安装

命令web profile
$ dsh plugin --profile web add github:acefun29/dsh-file-mount

在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程

对话式安装

帮我安装 DeepSeek Harness 插件 acefun29/dsh-file-mount:先查看仓库 https://github.com/acefun29/dsh-file-mount 确认安全性,然后执行安装命令并验证插件加载成功。

把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。

一句话定位

dsh-file-mount 把「AI 反复读同一个文件」这种场景下浪费的上下文窗口收回来——它替 DSH 的 read / write / edit 工具记账每个文件哪些行已经进过模型上下文,重复读取只补缺失或磁盘上改动过的行,再附带一个浏览器端的「挂载文件」仪表盘实时展示账本和节省量。

核心能力

  • 拦截 read 工具结果,对已挂载的行范围用一行「已挂载」标记代替正文,避免整段内容反复塞进上下文
  • 当文件磁盘内容发生变化时,按行级 diff 只补改动的行(追加型日志只补新尾巴;中段过大时按唯一行锚点切分 LCS)
  • 模型自己刚 write 写入的文件被自动标记为「已知道」,下次再读直接免单;edit 标记失效但保留行指纹底稿供增量比对
  • 提供 file_mount_forget 工具,允许模型主动放弃某个文件的挂载、强制下次 read 整本重发
  • 在 Web 端注册一个「挂载文件」标签页:列出每个文件、展开成行段、显示覆盖图(已挂载行在全文件中的位置)、按色带标记新鲜度,并展示净节省与粗略人民币折算
  • 支持压缩感知:DSH 的标准压缩 checkpoint 出现后,被它 shadow 掉的旧挂载消息不再计入账本,避免基于已被移除的内容做错误去重

技术实现

  • 语言: TypeScript(构建产物 lib/index.js + lib/client.js,双面发布)
  • 关键依赖: @deepseek-ai/cordis(Service / Context 容器)、@deepseek-ai/schemastery(Config schema)、@deepseek-ai/dsh-tools(defineTool 注册 file_mount_forget、tools/post-execute 拦截钩子)、@deepseek-ai/dsh-llm(createUserMessage 注入挂载提示)
  • 架构模式: 双面 Cordis 插件——cordis.patch.yml 通过 bundle.patch 在宿主挂一行名为 file-mount 的插件(宿主半部跑 tools/post-execute 钩子做增量去重),package.json#dsh.client 通过 dsh-client-ui-conversation 的 conversation.view slot 注册 file-mount-ui 标签页(浏览器半部渲染仪表盘);账本通过结构化 source 字段挂在标准 user/message 事件上,宿主压缩 / 会话恢复 / 浏览器折叠共用同一套合并规则(mount-source.ts)
  • 入口文件: src/index.ts(宿主半部 FileMountService,导出 name = 'file-mount'),src/client/index.ts(浏览器半部 apply(ctx),导出 name = 'file-mount-ui')

适用场景

日常 DSH 跟 AI 协作改一个中等规模项目时,模型经常会反复回头读 package.json、配置文件、工具脚本、UI 组件源码——这些文件里大部分行其实早就进过上下文了,再贴一遍只是浪费窗口。dsh-file-mount 让这种「读同一本书第二遍」变成只贴书签,模型真的需要新内容时才补行;同时也适合让 AI 写完一个文件后再确认自己写了什么——写入动作自动让该文件变成「已知道」,回头读不再付 token。

前置依赖与兼容性

依赖最低版本说明
DeepSeek Harness0.1.0-rc.5(实测)peerDependencies 全部声明 ^0.1.0-rc.5;plugin 走 cordis.patch.yml 注入宿主、走 dsh.client 注入 Web 客户端
Node.js^22.19.0 或 >=24.0.0package.json#engines 强制要求;dsh plugin 安装链路还会调用 pnpm
平台macOS / Windows / Linux无原生模块;paths.ts 仅在路径归一化时按 process.platform === 'win32' 决定是否折叠大小写与盘符
原生模块无仅依赖 Node 内置 node:fs/promises、node:path,以及上述 npm 依赖

安装方式

dsh plugin --profile web add github:acefun29/dsh-file-mount

这是用户在落地页能看到的安装命令。README 提示 github: 形式目前只装源码(仓库不含 lib/,且没有 prepare 脚本),实际生产路径更推荐 pnpm dsh:install(仓库内置的安装脚本会打 tarball 后用 file:E:/...tgz 装进 web profile)或使用 GitHub Release 上的预构建 dsh-file-mount.tgz。装完必须重启 harness,仅刷新 Web 页面不会激活。

配置项

配置类型说明默认值
enabledboolean总开关,关闭后所有 read 原生透传,账本完全停写true
capacityinteger文件身份缓存(mtime+size+sha256)的容量上限;已挂载的文件按引用计数钉住不参与淘汰32
ttlMsinteger缓存安全阀:mtime+size 未变但内容实际已改时的兜底重读间隔(毫秒)300000(5 分钟)
maxPinnedFilesinteger单个会话最多钉住多少个挂载文件(LRU 超过即淘汰最久未用)256
minSavedTokensinteger净节省低于这个 token 数时放弃本次去重/增量,原生透传且不写账本,也不计入安全阀次数16
maxFingerprintBytesinteger超过这个字节数的文件不留行级底稿,发生改动时只能整本重挂1000000
maxManagedBytesinteger超过这个字节数的文件根本不接管,原样放行16777216(16 MiB)
excludeGlobsstring[]这些路径永远原样放行,不写账本也不入仪表盘[](典型写法:['**/node_modules/**'])
statsFilestring可选:跨会话总账的 JSON 落盘路径,宿主可通过 ctx.fileMount.stats() 读取未设置
freshnessEnabledboolean是否启用「新鲜度」启发式:上下文接近窗口上限时把靠前的段判过期、下次读重发true
freshnessThresholdnumber段位次低于此阈值(0..1)即判过期0.6
safeRationumber当前上下文 / 窗口 低于此比例时,压力视为 0,不判过期0.95
safeTokensnumber可选:绝对安全 token 上限;设置后覆盖 safeRatio未设置
pinAfterinteger段被标记为过期的次数达到此值后钉住,最多只重发这一次1
contextWindowinteger当会话未报告窗口大小时使用的默认上下文窗口 token 数128000
resendBudgetnumber可选:大于此 token 估计的段即使过期也不摘账本,避免大段重新塞进上下文未设置
valveReadsinteger连续 N 次完全覆盖去重后,下一次 read 放行原生结果并刷新相关段(防呆;0=关闭)2

配置写在 cordis.patch.yml 同级的 config 节点下;schema 校验和默认值见 src/index.ts:103-121。

常见问题

Q: 这个插件和 DSH 自带的会话压缩、上下文截断是什么关系?

A: 完全不冲突,也不互相替代。会话压缩解决「当前窗口还装得下多少原始历史」,dsh-file-mount 解决「同一段文件内容反复塞进窗口」——前者看上下文,后者看文件账本,两者方向正交,可以同时启用。压缩发生后,被它 shadow 的旧挂载消息会自动从账本剔除,下次读取重新锚定。

Q: 为什么读文件时 Web 端 UI 的 read 卡片变成了通用卡片,原本的文件高亮/代码块没了?

A: 这是预期行为。插件在 tools/post-execute 替换了模型可见的结果文本(去重 marker 或增量正文),UI 的 read 卡片是按结果文本渲染的,所以降级到通用版本;canonical value 原样保留,下游审计日志不受影响。

Q: 卸载或禁用插件之后我的挂载账本还在吗?

A: 内存账本随会话结束而释放,磁盘上不存任何账本文件(除非主动配置了 statsFile)。下次重新启用时账本会从当前会话的注入消息 source 字段重新回放——所以关闭后短时间内重新打开,数据是连续的;关闭前若想保留跨会话累计统计,需要先把 statsFile 配出来。

Q: 仪表盘里某个文件的「行范围」列表太细,看不过来怎么办?

A: 点击文件行左侧的折叠箭头可以收起该文件的全部行段;顶栏提供搜索(按路径模糊匹配)和排序(按净节省或按路径名)。色带只能区分档位,不能调阈值——所有 freshness 阈值(freshnessThreshold / safeRatio / safeTokens / pinAfter)只在宿主配置里调整,仪表盘不可改。

Q: 增量补行的时候,万一行级 diff 漏改了怎么办?

A: 不会发生静默漏改。插件用 stat 校验(mtime+size 快路径 + sha256)确认磁盘身份,文件只要内容变了就走 hash 不一致分支;行级底稿丢失或改动过大时自动回退到「整本重挂」而不是放弃该文件。所以漏改只可能发生在 ① 文件超过 maxFingerprintBytes 没留底稿、② mtime+size 未变但内容实际改了的极端情况下,后者由 ttlMs 安全阀兜底。

Q: 文件名大小写、软链接、相对路径会不会识别错?

A: 账本内部用「绝对路径 + realpath + 大小写折叠(按文件系统实测,Windows / 默认 macOS 折叠、Linux 不折叠)」做唯一键,不会被软链接、相对路径绕开;模型看到的纸条头则用工作目录的相对路径(正斜杠),工作目录优先取会话 header.cwd,没有则取 dsh-fs-local 的 cwd。

上手难度

进阶 — 装上即用的默认配置就能工作,普通用户无需理解账本、哈希、行级 diff 也能受益;但要让仪表盘指标符合预期(比如 valveReads、pinAfter、safeRatio 这些阈值),需要先理解 DSH 的「工具结果 → 模型上下文」链条和 Cordis 配置机制。

已知问题与限制

  • 压缩(compaction)后「已挂载」保证失效:被 checkpoint shadow 的挂载内容已离开模型上下文,插件通过 sourceEventSeqs 识别并剔除,下次读取重新锚定;UI 端的 shadow 列表没通道同步,旧行会保留到该文件下次重挂
  • 增量 / 去重 / 重挂都替换了工具结果文本,Web 端 read 卡片因此降级为通用卡片(canonical value 完整保留,审计不受影响)
  • 依赖 read / write / edit 工具的 canonical value 结构;若 DSH 改动这些形状,插件守卫直接退化为原生透传,并在首次触发时向会话注入一次警告(src/index.ts:872-885)。形状变更由集成测试钉死
  • 超过 maxManagedBytes(默认 16 MiB)的文件与 excludeGlobs 命中的路径不接管,原样放行;插件不做抽样指纹——抽样有「改了没看出来」的风险
  • rc.6 的自定义会话事件类型无法安全持久化(持久化读取路径会硬性拒绝未知类型),所以账本载体选用标准 user/message 事件上的结构化 source 字段,而不是新增自定义事件类型
  • 「新鲜度」是启发式:段过期不代表内容真的被移出上下文(只有压缩才会),而是「注意力已衰减、模型基本看不见」,所以过期重发是刻意的 token 开销;没有 usage 数据的会话(如某些适配器)显示灰色「未知」,不判过期
  • 浏览器端的会话视图是分页历史窗口(默认尾页 50 条消息、上滚才加载更早页),仪表盘折叠会跨快照累积,挂载消息滚出窗口后该文件行仍保留在列表里,直到下次该文件重挂
  • 仪表盘的「点行跳回聊天」、跨会话总账的界面展示、「文件已变更」实时角标暂未实现(浏览器端没有对应通道),需要看细节请去查配置或日志
  • 安装提示:Windows 上 dsh plugin add . 会把盘符拼进 profile 路径导致插件装上但不激活,必须走 pnpm dsh:install 或预构建 tarball;npx @deepseek-ai/dsh 第一次跑可能长时间无输出(它在拉完整 CLI 包)

查看使用指南 →

该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。

收录徽章

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/acefun29/dsh-file-mount)

把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。

返回插件目录