dsh-compact-manager
面向 DeepSeek Harness(dsh)的分层压缩阈值管理器:让你按全局 → 上下文长度档位 → 模型三级覆盖自动压缩(compaction)的触发点,并在侧边栏里实时查看每个模型当前生效的阈值与策略。
Layered compaction-threshold manager for DeepSeek Harness. Precedence: global → context-window tier → model. Configure it from a sidebar page and see every model's resolved threshold live.

不幸被官方机制压缩到只有四分之一的 K3-256K,本仓库的设计缘由。
为什么需要它
dsh 内置的 @deepseek-ai/dsh-compaction-basic 触发阈值是:
floor(min(W × 0.8, W − O − 65536))
其中 W 是模型的上下文窗口,O 是该路由请求的输出预留(模型配置里的 maxTokens)。当模型把输出上限报得很高时,W − O − 65536 这一项会把阈值压到很低。以 256K 窗口、128K 输出预留的 kimi-coding/k3-256k 为例:
| 项 | 取值 |
|---|---|
W × 0.8 |
209,715 |
W − O − 65536 |
262,144 − 131,072 − 65,536 = 65,536 |
| 内置阈值 | 65,536(窗口的 25%) |
实测(同一 profile 的历史会话日志,7 次压缩):压缩全部发生在 65,934–69,573 tokens,正好贴着 65,536。也就是说窗口用到四分之一就开始丢历史。
本插件把「什么时候压缩」变成可配置的三级策略,例如把 256K 档设成 80% 或 W−32K,阈值就从 65,536 变成 209,715。
它只改变触发时机。一次压缩保留多少逐字历史仍由内置后端决定(最近
16% × (W − O))。区域选择、工具配对、摘要请求全部沿用官方实现。
三级策略与优先级
低 → 高,后者覆盖前者:
- 全局 — 所有路由
- 上下文长度档位 — 窗口长度落在档位值的 ±5% 内即算同一档(例如档位
256K = 262144,则249,037 ~ 275,251都命中;多档重叠时取最近的一档) - 模型 — 精确的
provider/model
每一层都是完整选择:四个项各自只有「启用 / 停用」,没有「继承」。高层一旦存在就整体覆盖低层,所以「档位层」或「模型层」里关掉的项不会从全局层漏回来。
为了不让你因为这条规则踩坑,界面里新增档位/模型覆盖时会以「当前继承到的策略」作为起点(新增档位复制全局策略,新增模型复制该模型当前生效的策略),而不是一上来把四项全关掉。
四个策略项
每个项都可以独立启用/停用,取值自定义;最终阈值取已启用项的最小值再向下取整,其中 absolute 是覆盖规则的例外:
| 项 | 公式 | 含义 |
|---|---|---|
ratio |
W × v |
上下文的比例(0 < v < 1) |
outputAware |
W − O − v |
扣掉该路由的输出预留 O 和固定值 v |
fixed |
W − v |
只扣固定值 |
absolute |
v |
硬编码阈值:v < W 时直接覆盖另外三项;v ≥ W 时永不触发,被忽略并在预览处给出提醒。只在档位层和模型层可用——全局层没有可比较的窗口 |
没有启用任何项时,插件完全不介入,继续使用官方内置阈值。
安装
在 dsh 中让 agent 调用插件管理器,或使用 CLI:
# 从 npm(发布后)
dsh plugin --profile <profile> add dsh-compact-manager
# 从本地目录
dsh plugin --profile <profile> add link:/path/to/dsh-compact-manager
安装后侧边栏会出现「压缩策略」页面。通过 plugin_manager / dsh plugin 安装通常即时生效;若侧边栏没有出现,先刷新浏览器页面,再考虑重启 dsh。
本地
link:安装不会自动安装被链接包自己的依赖,请在插件仓库里先执行一次pnpm install(本插件需要zod)。
侧边栏用法
打开侧边栏的「压缩策略」页:
- 模型下拉:选择任意一个已知路由,页面显示它的
W、O、当前生效阈值、官方内置阈值,以及各启用项的取值和决定项。 - 预设:一键套用常见策略(含
256K 档:80% 或 上下文−32K、256K 档:硬编码阈值 209,715)。 - 全局 / 档位 / 模型策略:每个项都只有一个勾选开关(开/关)加一个数值;档位可增删,模型覆盖的 provider/model 用下拉列表选择。全局层不提供「固定阈值」项,它只出现在档位层和模型层。
- 提醒:当
absolute的值 ≥ 上下文窗口 W(永远不会触发)时,或当outputAware因为O过大而主导阈值时,预览区会直接给出黄色提示。 - 保存:写回宿主并持久化;页面每 5 秒、窗口获得焦点时自动刷新,所以「实时看到阈值」不需要手动刷。
工作原理
- 宿主半(
lib/index.js):把策略文档存进ctx.storageDomain(域名compact_manager,json 后端落在$DSH_HOME/storages/),并通过两条自有/api/compact-manager/*Fetch 路由给浏览器半读写。 - 阈值钩子:Web 组合把压缩放在每个 agent preset 的隔离作用域里(
dsh-web-app停用了 profile 层的compaction-basic,preset 内以isolate: { compaction: true }各挂一份),因此 profile 层的插件注入不到ctx.compaction。本插件改为装饰@deepseek-ai/dsh-compaction-basic导出类的原型方法compactIfNeeded:压力达到策略阈值就交回内置实现,否则直接返回「不压缩」。这样无论引擎实例在哪个作用域都能生效,context-overflow恢复路径保持原样。 - 浏览器半(
lib/client.js):手写的window.__ModuleLoader__.load(...)经典脚本。第三方插件无法向页面推送自定义事件(转发事件白名单是构建期固定的),因此采用「自行轮询 + 窗口聚焦刷新」。 - 引擎被替换或卸载时,宿主半边通过 Cordis effect 还原原型方法。
HTTP API
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/api/compact-manager/state[?refresh=1] |
策略文档、模型表、预设、revision |
POST |
/api/compact-manager/policy |
提交 { document };校验失败返回 400 与 issues |
策略文档格式
每一层都是完整选择:四项必须各自表态,所以持久化的文档里每层都长这样(未提到的项按「停用 + 默认值」补齐):
{
"global": {
"ratio": { "enabled": true, "value": 0.8 },
"outputAware": { "enabled": false, "value": 32768 },
"fixed": { "enabled": false, "value": 32768 },
"absolute": { "enabled": false, "value": 131072 }
},
"tiers": [
{
"window": 262144,
"policy": {
"ratio": { "enabled": true, "value": 0.8 },
"outputAware": { "enabled": false, "value": 32768 },
"fixed": { "enabled": true, "value": 32768 },
"absolute": { "enabled": false, "value": 131072 }
}
}
],
"models": [
{
"provider": "kimi-coding",
"model": "k3-256k",
"policy": {
"ratio": { "enabled": true, "value": 0.7 },
"outputAware": { "enabled": false, "value": 32768 },
"fixed": { "enabled": false, "value": 32768 },
"absolute": { "enabled": false, "value": 131072 }
}
}
]
}
开发
无构建步骤:宿主半是普通 ESM,浏览器半是手写的 ModuleLoader 包装。
npm test # 纯函数策略测试(node --test)
lib/policy.js 纯策略词汇与解析(无依赖,可直接复用/测试)
lib/schema.js storageDomain 记录 schema(zod)
lib/index.js 宿主插件
lib/client.js 浏览器插件
已知限制
- 只覆盖压力触发;上下文溢出恢复(
context-overflow)仍走官方路径。 - 只改变触发阈值,不改变一次压缩的保留比例。
- 原型钩子作用于所有会话(策略本身就是进程级配置)。引擎模块被热替换后会重新导入并再次挂钩;若宿主改用不继承该原型的自定义压缩后端,钩子不会生效(宿主日志会给出告警)。
- 模型下拉来自
ctx.llm.listProviders()×listModels();不公开目录的 provider(例如某些账号型 provider 未登录时)不会出现在列表里,也就无法为它新增覆盖(已经存在的条目仍会保留并显示)。 - 页面数据来自宿主自有路由,因此不受 dsh 的 Remote 事件白名单限制,但也因此不会收到推送,只能轮询/聚焦刷新。
- 与任何同样装饰
compactIfNeeded的插件(例如本仓库同作者早期的compaction-threshold-override)功能重叠,建议只保留一个。
License
MIT
No comments yet. Be the first to write one.