ARTICLE · 1119808
官方刚说要建插件市场,社区已经交出了这种东西
官方刚说要建插件市场,社区已经交出了这种东西
DSH 十步路线图 × dsh-smart-compact 零丢失换窗 · 2026.10.03

封面图(900×383 公众号尺寸)
10 月 1 日,DeepSeek 把 DSH 的下一步规划摊开了,一共十条:
1. 加强沙箱与安全
2. 让 Agent Team 更好用
3. 上个性化长期记忆
4. 打通浏览器和其他 GUI
5. 支持远程和移动端
6. 探索会话分享与协作
7. 实验功能按需开,成熟能力默认开
8. Harness 跟新模型一起训、一起进化
9. 插件更好发现、安装、管理,并建官方插件市场
10. 插件 API 更稳定,减少破坏性变更,降低跨版本兼容成本
官方那句话总结得很到位:模型是灵魂,Harness 是手脚,插件是生态。
但有意思的是——第九、第十条还在"计划"栏里,社区已经把东西做出来了。
有个叫 dsh-smart-compact 的插件(作者 hoyyang,BSD-3-Clause 协议,48 次提交),干的事挺狠:让长会话换窗口时一个字都不丢。
而它正好是"插件该长什么样"的一个样本。
先说痛点:AI 帮你压缩历史,压出来的不一定是真的
跑过几天长会话的人都熟这个场面:窗口快满了,宿主兜底的 AI 摘要压缩开始工作——几万字的历史被"浓缩"成几段大意。
细节丢了,任务接不上了,token 还额外烧了一轮。
更要命的是:摘要这东西会编。
它"总结"出来的东西,可能跟你真实干过的不一样。
传统摘要压缩有三个结构性硬伤:
第一,会丢东西,还会编东西。 压缩之后你再想回查"上周那个报错当时到底怎么定位的",原文没了,只剩一段可能失真的大意。
第二,要花钱。 摘要本身就是一次完整的模型调用,窗口越大越贵——你正在应对窗口快满,却还要额外烧一轮大窗口的推理成本。
第三,任务容易"盲续接"。 新窗口里没有定向信息,模型接手后得猜"我刚才在干嘛",尤其换完窗直接开多窗口任务,猜错方向就是白跑。

三带策略与无损换窗流水线
换一条路:不总结,直接存档
dsh-smart-compact 走的是另一条路:不给旧对话写摘要,而是把旧窗口原封不动存档,机械地开一张干净的新窗口。
它是 DSH 的上下文窗口自动管理插件,当前 engine-state 0.5.x(安装示例显示 @0.5.2),核心卖点一句话说得清:换窗全程 0 次摘要模型调用,旧内容 100% 无损、随时逐字回查。
说人话版本:上下文快满(默认窗口的 85%)时,引擎不再把旧对话压成摘要,而是四步——
1. 旧窗口整体原封不动存档。 进的是会话本来就有的持久化事件流,零新存储。
2. 留 8192 token 缓冲(fallbackBufferTokens),让模型写交接笔记。
3. 开一张干净的新窗口,窗口里只放一段固定模板锚点:"旧窗口已完整存档,当前状态在 ctx_notes,细节用 ctx_history 查"。
4. 全程 0 次摘要模型调用;旧内容 100% 无损,随时精确回读。
锚点模板是机械推导的,不靠模型。
锚点固定开头 Context window #N opened(N 是会话内窗口序号),后面跟两行零模型调用、定长截断的定向信息:Task:(取最近一次会话标题,消除任务盲续接)和 Last action:(取最新内容事件首行)。
三带策略:什么时候提醒,什么时候动手
自动换窗不是按钮的附属品,而是一条宿主事件驱动的独立通路。引擎按当前消耗水位落入三带之一,逐级升级:
quiet(消耗 < 85%):什么都不做。 只有 25%、50%、75% 的分级提醒注入模型上下文,提示它该写交接笔记了。
grace(85% ~ 85%+8192 token):提醒一次。 该写 ctx_notes 了,窗口继续正常工作,给交接留缓冲。
forced(≥ 85%+8192 token):自动执行与手动完全相同的机械换窗。 零模型调用,新窗口第一条消息就是交接锚点。
这里有个容易被忽略的工程细节:提醒触达是可观测的。
25/50/75% 和 grace 的触达计数,从 v0.5.0 起会写进 engine-state.json 的 reminderObserved。这不是摆设——0.4.x 时代真的发生过"热会话零触达、最后被宿主 AI 摘要兜底"的事故,现在提醒静默失效一查便知。
手动入口一共三条,全部和自动路径同轨:
/smart-compact 命令,回执是人读中文,成功 ✅ / 失败 ❌ 前缀,绝不静默降级
输入框工具行的 26px 金色圆按钮,点击等于执行 /smart-compact;刚换完窗、会话无历史、槽位被占三态自动置灰
模型自请的 new_context,本步采样完成后生效,不打断当前步
最见功夫的一处:笔记新鲜度门
换窗的瞬间,引擎会把最新笔记段的时间戳和持久流对账。
如果笔记之后还有活动(手动早换窗时必然如此),锚点就不再无条件背书笔记,而是降级为 ⚠️ STALE 警示,附上最后笔记时间、其后的活动事件数,以及最近 ≤3 条工具名+时刻(只记名字,绝不记参数/结果)。
✅ 回执也会同步追加一行"交接笔记滞后"的提示。
笔记新鲜或无法判定时,锚点逐字不变;探针任何故障一律降级省略,绝不失败。
这个门是真实事故逼出来的:有一次换窗成功了,但笔记落后了 4 小时,旧锚点还在主动让新窗口信任过期状态。
另外两条规则也值得记住:
诚实化(v0.3.2):如果换窗前本会话从没写过笔记,锚点会降级成"ctx_history 召回"模式,并明确声明"本会话至今没有笔记",绝不指向空笔记通道。
强制脱敏(v0.5.0,无开关):锚点里 Task / Last action 两行写进新窗口前,强制过一遍手机号、邮箱、18 位证件号、中英文企业名的脱敏。日志只记数量与类别(handoff anchors sanitized — 3 redaction(s)),绝不回显原文。
边界是刻意为之:ctx_history 的逐字归档不脱敏——本机无损回查是核心契约,脱敏只覆盖"引擎自动生成、会自动传播"的那一层。
模型侧五件套

五个工具各管一摊
`get_context_remaining`:实时读剩余 token 预算,返回 total / window / remaining 三个数。输入框右侧的消耗表和三带判定都读它。
`ctx_notes`:write / append / read / search / list 五个操作的工作笔记,跨压缩、跨换窗存活。grace 提醒之后该写的就是它。
`ctx_history`:list 打窗口清单(含 seqs 区间、事件数、归档 token 量、live window 号),read 按 seq 精确回读,search 全文检索归档内容——事故复盘考古全靠它。
`new_context`:模型自己请求开新窗口,本步采样完成后生效,不打断当前步。
`/smart-compact` + 金色圆按钮:人工立即换窗。按钮几何全 !important 锁定外加 clip-path 物理裁成正圆(实测 26.00×26.00 敌意覆盖也不变形),点击写入命令走宿主原生提交,草稿原样恢复。
运维侧还有两件事值得知道:
一是 engine-state 探针。随时 cat ~/.dsh/dsh-smart-compact/engine-state.json,能查当前模式(engineMounted)、窗口号、rolloverCount 和最近失败原因。lastRolloverTrigger 取值 new_context / pressure / manual / context-overflow,拒绝原因写在 lastRolloverRefusedReason(相同原因 30 秒内合并写入)。
二是单槽谦让。compaction 服务是单槽,本插件装上来默认接管该槽,所以要在 profile bundles 里排在 dsh-glm / dsh-kiro / compaction-basic 之前;被让位的引擎凭内置谦让检查自动跳过挂载,其余功能不受影响。
同时官方 /compact 保持 disabled——避免"槽位被占时 /compact 静默退化成摘要压缩"这条跟无损承诺冲突的路径。槽位被占时 /smart-compact 会明确报错,绝不悄悄降级。
装它不需要任何配置
全部零配置开箱即用——所有配置键都是可选项,默认值即上线行为,装完启动 dsh web 就生效。
dsh plugin --profile web add dsh-smart-compact
npm 预构建形态(安装输出 dsh-smart-compact@0.5.2 (public, prebuilt),约 1.6 秒)或 github 源形态(dsh plugin add github:hoyyang/dsh-smart-compact)都可以。
更新和卸载:
dsh plugin --profile web update dsh-smart-compact@latest dsh plugin --profile web remove dsh-smart-compact
卸载即净:工具、监听器、引擎随插件 fiber 一起销毁,压缩行为恢复 DSH 默认;笔记文件保留在 notesDir,要彻底清理才手动删。
真要调,也就这几个键:enabled(总开关)、auto(自动换窗开关)、thresholdRatio(默认 0.85,进缓冲带的窗口占比)、retainRatio(默认 0.16,换窗后保留占比)、fallbackBufferTokens(默认 8192,缓冲带宽度)、maxToolOutputTokens(默认 8192,单次工具输出截断上限)、notesDir(笔记目录)。
真机证据:不是嘴上说说
这个项目(截至 48 commits)的证据链扎实得有点反常,挑关键的讲:
Vitest 123 项全绿。 覆盖预算读取、笔记读写原子性、历史回查截断、换窗三态、new_context 防吞 fallback、生命周期幂等、三级提醒、宿主 Session API 适配(含 snapshotEvents() 缺失时点名报错)、窗口编号口径、pruner 隔离自检、客户端按钮回归与 isInert 三态判定。
双安装形态 staging 实证。 npm 预构建和 github 源码两种形态各自装配,--dump-config 单条目无重复,boot-check [A]-[F] 六类冷启动静态检测全绿。
端到端实证(真实模型 glm-5.3-flash)。 模型依次调用 get_context_remaining → ctx_notes(写交接笔记)→ new_context → ctx_history 全链路成功;new_context 触发真实 rollover(rolloverCount: 1),ctx_history 回读到已归档窗口。
真机换窗实证。 窗口 #1 全量归档 393 events / 约 307k tokens,新窗口 handoff 头为 Context window #2 opened,跨窗 ctx_history search 命中 23 条。
演示输出(本机 2026-09-29 真实会话)长这样:
[smart-compact rollover] Context window #2 opened. The previous window was archived in full — nothing was summarized away or lost.
手动回执首行:✅ 已换窗 → 窗口 #2 · 归档 window #1(223 events / ~121k tokens)。
ctx_history list 输出:window #1: seqs 10–827 (223 events, ~121034 tokens archived) · live window: #2。
两条限制,如实说
第一,手动 /smart-compact 路径不做前置 toolResult 剪枝。
这不是疏漏而是设计:rollover 是整窗机械归档,保留范围由区间选择决定,前置剪枝没收益。代价是——手动路径在"窗口真正需要压缩"的场景下,可能收敛得不如宿主压缩少。
第二,宿主 submit 平面在智能体运行中拒绝提交(locked/busy)。
运行中点击金色按钮是静默无操作,属宿主既定语义,不是按钮 bug。
兼容性三条铁律:dsh >= 0.1.5-rc(会话日志经 Session.snapshotEvents() 读取,宿主不提供该 API 时点名报错,绝不静默失忆);升级 dsh 后必须重跑 npm install 并重建 lib/,否则会继续加载旧核心 API;v0.5.1 起附带的 token-meter 容错补丁每次升级 dsh 后重跑一次。
它的场景面,比你想的宽
长会话自动续命、手动早换窗、跨会话接力、事故复盘考古、多窗口任务定向、笔记滞后防护、敏感信息防护、成本控制、多引擎共存谦让、运维可观测——基本覆盖了长任务会遇到的所有坑。
回到开头那张规划清单。
DeepSeek 说要建官方插件市场,要让插件 API 更稳定、减少破坏性变更。而 dsh-smart-compact 这种项目说明了一件事:生态不是规划出来的,是先有人把东西做出来,做扎实,做可验证。
模型是灵魂,Harness 是手脚,插件是生态。手脚已经有了,灵魂也在进化,剩下的就看生态能长出多少这种"一个字都不丢"的东西。
如果你受够了"窗口一满,历史就被 AI 压成一段失真的大意",那么替代方案已经摆在这了:旧内容原封不动存着,新窗口拿着机械推导的锚点继续干,想考古随时逐字回查。装它不需要任何配置,卸它干干净净。
— END —
LZR,软件开发公司老板。文章编辑:LZR09029988业务范围:DAPP、小程序、APP、分销系统、商城系统开发,关注私信报价。