dsh-terse-mode — 少想、少搜、少废话
一个 DSH(DeepSeek Harness)插件,给同一 profile 里的所有会话(含子 agent)加一层可随时调的约束:
- 少想:把模型请求的推理强度压到档位值,简单问题不再想很久;
- 少搜:
web_search/web_fetch按档位或开关关闭——新会话里模型根本看不到这两个工具,老会话里真调用也会被拒绝; - 少废话:系统提示词最后加一条「直接答、别复述、别总结自己」的指令,不设硬性输出上限,回答长度只由指令引导;
- 少委派:可一键禁用子代理(
subagent/subagent_fork/spawn_teammate/workflow四个工具从模型眼前隐藏)。
四档强度 + 三个独立开关(思考强度 / 联网搜索 / 子代理),在对话页顶部的常驻控件和 DSH 设置页的「简洁模式」一节里都能改,改完立即生效。
顶行只放「档位」这一组和 ⋯ 入口,另外两个开关收在 ⋯ 弹层里 —— 一行只做一个决定。
| 入口 | 位置 | 能做什么 |
|---|---|---|
| 顶部控件 | 对话页 header(「智能体团队 / 标准模式」那一行) | 切档位(四格等宽、选中实心品牌色);⋯ 展开全部说明与另外两个开关 |
| 设置页 | 设置 → 简洁模式 | 同样的控制项 + 每档解释 + 当前实际生效值 + 改在哪里的说明 |
快速开始
node tools/install-terse-mode.mjs # 桌面端(profiles/desktop)
node tools/install-terse-mode.mjs --profile web # 网页端(dsh web 用的 profiles/web)
装完刷新一次页面即可看到控件;改档位/开关不需要重启。
档位
| 档位 | 思考强度 | 单次输出上限 | 联网搜索 | 适合 |
|---|---|---|---|---|
off |
不动 | 不限 | 允许 | 关掉插件(总开关) |
light |
压到 low |
不限 | 允许 | 只想让它别啰嗦 |
standard(默认) |
压到 low |
不限 | 禁止 | 日常问答 |
strong |
关到 off |
不限 | 禁止 | 只想快速得到短答案 |
四个档位都不设输出上限:回答长度只由提示词指令引导,不会被硬截断。想给某次会话硬上限,才显式写 maxTokens: <正整数>。
档位给的是默认值:思考强度与联网搜索两个开关只要不是 auto(跟随档位),就以开关为准;子代理开关完全独立于档位。所以上表的「思考强度 / 联网搜索」两列读作「该档位的默认值」。
思考强度(可单独调)
档位给的思考强度是上限(只降不升);想直接指定强度,用顶部控件或设置页里的「思考强度(覆盖档位)」。 文案与官方模型菜单一致,用官方的 effort 名:
| 选项 | 含义 |
|---|---|
auto(跟随档位) |
由档位决定:light / standard = low,strong = off,off(档位)= 完全不碰请求 |
off |
完全关闭思考(最快) |
low |
轻量思考 |
high |
比档位更高——只给确实需要深思的任务 |
max |
最大强度,最慢最贵 |
- 点了就是决定,不是上限:选
high会把请求强度设成high(即使模型菜单里选的是低);只有该模型确实公布了这个强度时才设,否则保持原样。 - 点档位会把思考强度与联网选择重置为「跟随档位」:想固定就先点档位、再点强度/开关。
- 面板选择(档位 + 强度 + 联网 + 子代理)都记在
$DSH_HOME/storages/dsh-terse-mode/level.json。 - 命令行等价写法:POST
/dsh-terse-mode/api/state,body{"reasoningEffort":"high"}(或{"level":"light","search":"allow"})。 - patch 里也可以写:
reasoningEffort: auto | none | off | low | high | max(auto跟随档位,none从不碰请求)。
细项可以覆盖档位(写在 cordis.patch.yml 那一行的 config 里):
- id: terse-mode
config:
level: standard
reasoningEffort: auto # auto | none | off | low | high | max
maxTokens: 0 # 0=跟随档位, -1=不限, 或正整数
search: auto # auto | allow | deny(面板里有开关,auto=跟随档位)
subagents: allow # allow | deny(也可写 true/false)
subagentTools: # 可选:覆盖被隐藏的工具名单
- subagent
instruction: auto # auto | none | 你自己的提示词
applyToAllModels: false # true=对非 DeepSeek 模型也压强度
联网搜索开关
和档位互相独立的另一个开关(和子代理开关同款)。它在 ⋯ 弹层的「联网搜索」一节里,
三选一:跟随档位 / 允许 / 禁止:
简洁模式 [关][轻][标准][强] (⋯)
- 禁止做的事:
web_search/web_fetch从模型眼前隐藏,运行期也硬拦(guard 消息「Web tools are turned off…」), 并在系统提示里加一句「联网已关,需要外部事实就直说,不要猜」。 - 允许做的事:即使当前档位是「标准/强」(默认禁止联网),也会放行联网工具。
auto让你随时回到「由档位决定」:关/轻允许,标准/强禁止。- 点档位会把这个显式选择重置为「跟随档位」(和思考强度一样),想固定就先点档位再点开关。
- 不依赖联网的外部事实无法获得时,模型会明说而不是编造 —— 这是禁止联网的预期代价。
- 顶部看不到这个状态,只把鼠标停在
⋯上:提示里会写当前生效值。
禁用子代理
和档位互相独立的一个开关(不跟着档位变、改档位也不会重置它),同样在 ⋯ 弹层里:
简洁模式 [关][轻][标准][强] (⋯)
「子代理」一节里选「允许 / 禁用」。禁用做的事:
把四个创建子代理的工具(subagent、subagent_fork、spawn_teammate、workflow)从模型眼前隐藏,并在运行期硬拦它们的调用
(guard 的消息是「Subagents are turned off…」)。团队记账类工具(team_task_* 等)不动:没有创建入口它们本身做不了事。
要自定义名单就写 subagentTools。默认 allow,不改变原有行为。
在设置页面里调
除了对话页顶部的小控件,DSH 设置页里也有一节「简洁模式」(客户端插件注册 settings.section 槽),里面有:
档位四选一 + 每档解释、思考强度五选一、联网搜索三选一、子代理开关、当前实际生效值、以及「改在哪里」的说明。
两处是同一份状态:在设置页里改,顶部控件立刻跟着变,反之亦然。
两个部署(桌面端 + 网页端)
插件装在 profile 里,桌面端和网页端用的是不同 profile,所以要各装一次:
node tools/install-terse-mode.mjs # 桌面端(profiles/desktop)
node tools/install-terse-mode.mjs --profile web # 网页端(dsh web 用的 profiles/web)
--profile <名字> 对应 $DSH_HOME/profiles/<名字>;--status 看当前状态,--uninstall 撤销(都要带同一个 --profile)。
两端共用同一个记忆文件 $DSH_HOME/storages/dsh-terse-mode/level.json,所以档位/强度/子代理选择是共享的 —— 并且是运行时就同步的:
插件监听这个文件,一端改了,另一端 150ms 内跟上,不用重启。
改档位有两种办法,任选:
- 在插件目录里执行
node tools/install-terse-mode.mjs --level strong(改的是插件自带的 patch); - 在你 profile 的
cordis.patch.yml里按id: terse-mode-profile覆盖安装脚本插进去的那一行 —— 这一层优先级最高,升级插件也不会丢, 而且改 profile 的 patch 是热生效的(约 1 秒),不用重启。 (插件自带的 bundle patch 里那一行 id 是terse-mode;profile 里的是terse-mode-profile,两者不要混。)
注意区分:改配置(档位/细项)是热生效的;改插件代码(
index.js/lib//client.js)需要重启一次 DSH 才换用新模块, 因为已安装的模块不会重新导入(实测:加一条注释触发 profile 重组合后,新路由仍然 404)。新增 client 半侧同样需要重启。
面板里点档位则不需要重启:那是运行时改策略,不走模块加载。
可视化面板
对话页顶部那一行(「智能体团队 / 标准模式」旁边)有一个常驻控件:
简洁模式 [关][轻][标准][强] (⋯)
- 点一下档位就立即生效,不用改文件、不用重启:提示词、思考强度、输出上限、联网搜索一起跟着变。 当前档位是实心品牌色块,一眼能看到;四格等宽,选中块不会随字数跳动。
- 每个档位鼠标移上去都有说明(原生提示,一句话说清这一档压什么、放什么)。
⋯打开说明与设置面板(原来行上的子代理、联网、?都收进这里,顶行只留一个入口):- 「每一档在做什么」:四档逐条解释,当前档高亮;
- 「思考强度(覆盖档位)」:
跟随档位 / 关 / 低 / 高 / 最高,每个都有 hover 说明; - 「子代理」:
允许 / 禁用,附一句当前语义; - 「联网搜索」:
跟随档位 / 允许 / 禁止,附一句当前语义; - 「当前实际生效」:思考强度 / 输出上限 / 联网搜索 / 提示词指令,显示的是实际生效值(模型菜单里选得更高也会被压到档位值);
- 「改在哪里」:细项在插件的
cordis.patch.yml(或 profile patch 里按id: terse-mode-profile覆盖);面板选的档位存在$DSH_HOME/storages/dsh-terse-mode/level.json,优先于 patch,删掉即回到 patch;点档位/改配置立即生效,改代码要重启。
⋯的 hover 提示会写出「思考 / 上限 / 联网 / 子代理」四项的当前生效值 —— 顶行不显示开关状态,这是不打开面板也能核对的地方。- 弹层用
position: fixed挂在按钮下方:顶部那一行不归插件管,绝对定位的盒子可能被裁掉。 - 选择会记住(存到
$DSH_HOME/storages/dsh-terse-mode/level.json)。面板选的优先于 patch, 但两层是分开记的:点档位只清掉面板自己的那两项,patch 里写死的reasoningEffort/search会立刻回来, 不会被一次点击永久抹掉。想连 patch 的值一起回到默认,改 patch 或删掉那个文件。 - 面板没连上宿主时按钮右边会显示红字「未连上宿主」(通常是插件刚更新,还需要重启一次 DSH)。
- 写不进
level.json时(只读目录、磁盘满)选项目前仍然生效,但日志里会留一条 warning:plugin.log与dsh-terse-mode的 logger 都能看到,重启会丢。
面板与宿主之间走的是 DSH 自己的 HTTP 路由:GET/POST /dsh-terse-mode/api/state(仅回环,
和插件市场 /dsh-market/* 同一个通道)。手工核对:
curl http://127.0.0.1:19387/dsh-terse-mode/api/state
curl -X POST -H 'content-type: application/json' -d '{"level":"strong"}' http://127.0.0.1:19387/dsh-terse-mode/api/state
实测效果(本机 desktop profile,同一个会话)
| 装之前 | 装之后 | |
|---|---|---|
| 推理强度 | high |
low |
| 单次输出上限 | 256000(适配器默认) |
不限(档位不再设上限) |
| 工具表 | 含 web_search、web_fetch |
两者都不再出现 |
http://127.0.0.1:19387/dsh-market/installed 里显示 dsh-terse-mode: state=live、findings: []。
安全设计(为什么它不会把你搞崩)
- 配置写错不会让插件启动失败:插件的配置校验器永不报错,认不出的值一律回落到安全默认,并在日志里留一条 warning。 (本机曾因插件启动失败触发过 Desktop 安全模式,把 profile 的 bundles 砍回 in-box,所以这里必须这么设计。)
- 绝不强行给不支持思考的模型加推理强度:只有请求本身已经带了
reasoningEffort时才压,而且只降不升、只认off/low/high/max这组 DeepSeek 的取值。 默认只对 provider 以deepseek开头的路由生效,applyToAllModels: true才放开。 - 工具禁用是双保险:
tools.guard()让调用必定失败(对所有会话立即生效),tools.restrict()让新会话的模型看不到这两个工具。restrict在报「未知工具名」时会被吞掉并记日志,绝不让 agent 创建失败。 - 面板路由只认同源:
/dsh-terse-mode/api/state拒绝跨站Origin、Sec-Fetch-Site: cross-site和非回环Host(DNS rebinding),POST 还要求显式content-type: application/json;桌面端 shell 转发时这些头都缺失,仍然放行。 这样本机任意网页无法再用一个no-cors表单把档位静默切到off。 - 零运行时依赖:纯 JS,不 import 任何 DSH 包,也不带 node_modules。
已知边界(先说清楚)
- 输出不再有硬截断:四个档位都不设
maxTokens,长回答不会被切断;长度只由提示词指令引导。若你想要硬上限,显式写maxTokens: <正整数>(插件只会在模型/路由已有的值上取更小的那个)。 - 禁止搜索后,你明确说「搜一下」也搜不了。要搜就把
search设成allow(或整个切到light/off)。 - 「让模型看不到工具」在装上的那一刻就对已开会话生效(插件会扫一遍在跑的 agent);靠 guard 兜底的拒绝路径由单测覆盖。
- 对所有会话生效,包括子 agent;没有「只对这个会话」的开关(
off档就是总开关)。 - 改代码要重启,改配置是热生效(见上)。
- 诊断噪音:本插件的配置校验是零依赖手写实现(
link:安装的插件解析不到@deepseek-ai/*), 所以dsh --dump-config-schema会对本行多报一条Config is not a native Schemastery schema。 这条命令不参与启动,插件运行不受影响。
安装 / 卸载
# 看当前状态
node tools/install-terse-mode.mjs --status
# 只预演,不写文件
node tools/install-terse-mode.mjs --dry-run
# 安装(默认 standard 档)
node tools/install-terse-mode.mjs
node tools/install-terse-mode.mjs --profile desktop --level light
# 卸载(会先把 profile 清单与 patch 备份到 工作区/.backup/<时间戳>/)
node tools/install-terse-mode.mjs --uninstall
安装只动 profile 这四处:package.json 里一条 link: 依赖、node_modules/dsh-terse-mode 这个 junction、
profile 自己的 cordis.patch.yml 里一行带标记的 insert(非 desktop profile 还会补 dsh.profile.bundles)。
不跑 pnpm、不动 lockfile,所以其他已装插件不会受影响;卸载时全部还原。
为什么不靠 dsh.profile.bundles:2026-10-01 12:29 实测,Desktop 宿主启动时重写了 desktop profile 的 package.json,
把 dsh-terse-mode 从 dsh.profile.bundles 里删掉了(依赖条目还在,market 日志与 plugin-manager 都没有对应操作),
插件于是在下一次启动时不再挂载。profile 的 cordis.patch.yml 是用户层,宿主只做外科式改动、保留它 —— 把行插在那里才是稳的。
name: dsh-terse-mode 由 profile 的 node_modules(junction)解析,与 bundles 无关。标记注释 >>> dsh-terse-mode >>> / <<< 让改档位与卸载都能精确替换那一段。
实测补充:改宿主模块代码(
index.js/lib/)必须重启一次 DSH。即便把 profile patch 里那一行删掉再插回来(重新挂载一次), 宿主仍然复用内存里的旧模块(三个档位 POST 后 effective 值完全一致,即可判定跑的还是旧代码)。改配置/点档位不需要重启。
开发
cd terse-mode
npm test # 全部 95 个用例(node --test test/*.test.mjs)
node --test test/logic.test.mjs # 档位与钳制规则
node --test test/plugin.test.mjs # apply() 的接线(用一个假 Cordis context)
node --test test/level-api.test.mjs # 面板路由与同源校验
node --test test/client.test.mjs # 两个界面真的渲染一遍
node --test test/这种只给目录的写法在 Windows + Node 24 上会报MODULE_NOT_FOUND,要用上面的 glob 或npm test。
设计说明与取舍见 ../docs/superpowers/specs/2026-10-01-terse-mode-design.md。
No comments yet. Be the first to write one.