前言¶
DSH(DeepSeek Harness)每个会话都会把全部工具的说明塞进上下文。工具装得多,说明本身就占掉几万 token;同时模型每轮要从这堆工具里挑,工具列表越长,挑错或绕弯的概率越高。
已有的做法是写在 preset 里的模式切换。dsh-mode-switch 从另一个角度处理:不改 preset,而是给会话单独配一层「档位」,让一个会话只带当前用得上的工具,在界面上就能切档、看省了多少、改规则。插件由 MOLMOORE 维护,分类属于工作流,目前 GitHub 星标为 0。
这是什么¶
一句话:给 DeepSeek Harness 加一层工具档位,让每个会话按档携带工具。
它不声明 preset,也不动 preset 注册表。官方那几种模式照旧,档位是叠在上面的另一层。预先声明的工具集无法够到的场景(preset 自带工具、agent 作用域注册的工具、其它插件的界面卡片)不在这层治理范围内,后面「适用场景与注意」会具体说明。
安装与启用¶
需要 DSH 0.2.1 或更新。安装命令:
dsh plugin --profile desktop add github:MOLMOORE/dsh-mode-switch
装完重启。输入框上方会出现一行胶囊:
档位 基础档 · 标准模式 · 62 工具 · ≈14.9k tok schema
其中 62 和 14.9k 是作者机器上的数,装了什么插件,数字就不一样。这一步只负责把插件加进来,具体表现要重启后在界面确认。插件的 package.json 里标了 MIT 许可证。
核心功能:四个界面动作¶
- 点右边的小胶囊换档。只有还没发过消息的会话能换。
- 点主胶囊展开明细:各档的工具数、token、比全量档省多少,以及这个会话第一个请求实际带了多少工具。
- 右上角「编辑档位」:加档、改名、删档、勾选每档保留的工具。改完保存,新会话生效。
- 编辑器里的「AI 分配」:把当前机器的工具名和说明交给默认模型,让它按用途分档。结果先填进编辑器,人工看过再保存。
「AI 分配」要调一次模型(走默认路由),耗时几十秒到一两分钟,费用算在使用者账上;没有可用模型时按钮会报错,手动勾选照样能用。
规则怎么算¶
核心规则只有一条:
可见工具 = 全局工具 − 当前档的 deny 规则
deny 里 foo_* 按前缀匹配,其它按完整名字匹配。preset 自带的工具(读写文件、todo、问用户)和 agent 作用域注册的工具不在全局名单里,任何档都裁不掉它们。
规则存放在 ~/.dsh/state/mode-switch/catalog.json,首次运行自动生成。面板改的就是这个文件;直接编辑文件也行,不用重启。结构如下:
{
"version": 1,
"modes": [
{ "id": "mode-basic", "name": "基础档", "order": 10, "deny": ["mcp__*", "ego_*", "ppt_*", "office_*"] },
{ "id": "mode-full", "name": "全量档", "order": 40, "deny": [] }
]
}
deny 为空就是全带。档位被删掉后,指向它的会话按 order 退到最前面那个档位,不会变成不裁剪。
什么时候生效¶
| 时机 | 行为 |
|---|---|
| 新建会话,还没发消息 | 可以切,选择只记下来,还没生效 |
| 发出第一条消息 | 按所选档位裁一次,没选就用默认档 |
| 对话开始后 | 不能切,服务端返回 session-started |
| 插件装之前建的会话 | 不改写,显示全量档 |
对话中不能切,是因为 DSH 在第一次组装请求时把工具目录固定了,之后 ctx.tools.restrict() 只能收紧不能放宽。想换档就新开会话。
默认的四个档¶
| 档位 | 留下的东西 |
|---|---|
| 基础档 | 核心工具。MCP、浏览器、PPT、Office、论文、论衡都摘掉 |
| 办公档 | 办公文档、PPT 相关留下,建模和浏览器摘掉 |
| 建模档 | SolidWorks 的 MCP 留下,办公、PPT、浏览器摘掉 |
| 全量档 | 不裁 |
建模档是按作者自己的机器写的:作者装了 SolidWorks 的 MCP,所以专门留一个档给它。没装 CAD 的机器上,这个档和办公档基本一样,分不出区别。装完先看一眼自己的工具列表,或者直接点「AI 分配」重来一遍,比照搬默认值靠谱。
少带工具的效果¶
以下是作者机器上的实测数,工具数量取决于各自装了哪些插件,仅作量级参考。
- 省 token。作者机器上全量 198 个工具、约 54.8k token;基础档 62 个、约 14.9k。工具表在首次组装时固定,之后每次请求都带着同一套,省的是整段会话的每一次请求。
- 模型少分心。工具表越长,读到的无关描述越多,挑工具时更容易挑错,或者围着一轮用不上的能力打转。把用不上的先摘掉,选择面小一些,回答也短一些。这是使用下来的判断,作者没有做过量化实验。
- 界面上的动作也少。工具少了,模型不会再在「要不要用浏览器查一下」这类选择上反复试探。
典型用法:按项目类型先建档,再新开会话¶
适用于工具集长期固定、按场景划分的情形。
- 在右上角「编辑档位」里加一个名为「调试档」的档,deny 里填
mcp__*,order放在基础档之前。 - 保存,新会话即生效。
- 进入新会话,确认输入框上方的胶囊显示刚建的档位。
- 若本机装了 CAD 组件,改成在面板里勾 SolidWorks 相关的 MCP,而不是直接套用默认的「建模档」。
按文件直接配置也行,例如编辑 ~/.dsh/state/mode-switch/catalog.json,加一段:
{ "id": "mode-debug", "name": "调试档", "order": 5, "deny": ["mcp__*", "ppt_*"] }
保存后不用重启,新会话会读到它。插件改名或新加工具时,规则要跟着改,否则会漏裁,因为它靠的是名字匹配而不是能力描述。
适用场景与注意¶
适合这几种情况:DSH 工具数量较多、token 占用明显;按项目类型划分工具集;想让团队成员用同一套档位约定。
使用前需要确认三件事。
- 插件以当前 DSH 进程的权限运行,安装前应先读一遍源码与许可证,确认不引入额外敏感权限。
- 只能裁全局工具:preset 自带工具、agent 作用域注册的工具裁不掉。官方 slots 也没有移除其它插件界面卡片的接口,那些条目会原样留在界面上。
- deny 是名字规则,覆盖面取决于工具命名是否稳定。
插件暴露的接口¶
插件本身带一组 HTTP 接口,插件作者和调试脚本可以用来核对档位的实际效果:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/mode-switch/status?sessionId= |
胶囊用的数据 |
| GET | /api/mode-switch/detail?sessionId= |
面板数据:各档足迹、逐工具开销、全部工具 |
| GET | /api/mode-switch/verify?sessionId= |
请求级证据:会话日志里每个请求真实带了多少工具 |
| POST | /api/mode-switch/select?sessionId=&toolset= |
选档,仅限没开始的会话 |
| POST | /api/mode-switch/modes |
保存整个档位列表 |
| POST | /api/mode-switch/auto |
调模型提一版档位方案(不写入) |
对要验证省下多少 token 的场景,用 /api/mode-switch/verify 取请求级证据比较直接。细节和实测记录在仓库的 docs/LIMITATIONS.md。
结尾¶
dsh-mode-switch 解决的是「一个会话不该带全量工具」这件事:用档位把工具声明和作用范围分离,界面上切档、编辑、按模型分配一次到位,不改 preset 注册表。目录页:https://www.skillhub.cn/plugins/MOLMOORE/dsh-mode-switch ;源码:https://github.com/MOLMOORE/dsh-mode-switch 。