DeepSeek Harness 插件

dsh-compaction-instant

Near-lossless deterministic compaction engine for DeepSeek Harness, a drop-in replacement for stock compaction.(英文原文)

跳到安装方式

来源信息

GitHub 仓库
KitDoesIt/dsh-compaction-instant
最近更新
2026年8月14日
分类
记忆
GitHub stars
8
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/KitDoesIt/dsh-compaction-instant
插件名:dsh-compaction-instant
作者:KitDoesIt

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器4 个文件
README.zh-CN.md来源说明 · 只读预览
README 语言

dsh-compaction-instant

DeepSeek Harness 打造的即时、近无损上下文压缩引擎——装上就能直接替换官方引擎 @deepseek-ai/dsh-compaction-basic,用 lllyasviel/VCC 的"对话编译"思路取代原来的 LLM 摘要。

对话太长了怎么办?普通方案是让模型把旧内容"总结"一遍(慢、花钱、还会丢细节)。本引擎不总结,而是把旧内容重新整理成一份紧凑的存档(后面统称"检查点"):毫秒级完成、不调用模型、只使用原来的原文,不改写、不编造。被收进存档的内容随时可以原样找回来。

主要特性

  • 免 LLM——压缩过程完全不调用模型:没有摘要请求、没有推理等待、不花 token。它只是确定性的文本处理,哪怕一百万个 token 的历史也是毫秒级搞定。
  • 近无损——存档里只有原文;每处被省略的内容都有标记并注明出处(seq 序号),之前的存档会原封不动地保留。
  • 即时——把旧内容扫描一遍就完成;不联网、不调模型、不占 KV 缓存。
  • 完全兼容的替换——对外接口、事件、计费和报错方式都和官方引擎一致;内置预设不用改任何东西就能用(见"别名安装")。

示例

一段包含用户提问、助手回答 + 工具调用及其结果的历史,压缩后长这样:

[user]
please fix the bug
[assistant]
on it
* read "a.js" (seq 2 -> result 3)
[user]
next question

每个工具调用只占一行:白名单里的工具(toolArgTools)显示关键参数,其他工具只显示名字(* job_kill (seq 9 -> result 10)),hideTools 里列的工具完全不出现。工具结果不占位置——通过 -> result N 指针,用一次 recall(type:"result") 就能取回。较长的用户/助手文本按预算截断,并在末尾标注 ...(truncated from seq N);每处省略都写明了完整内容存在哪个事件里。

Recall:把丢掉的内容找回来

本包还配套了"找回"能力——同一会话内的回读,模型和人都能用。因为会话日志只增不改,编译器省略过的每一个字都还在,随时可取:

| 入口 | 模块 | 作用 | |---|---|---| | recall 工具(给模型用) | dsh-compaction-instant/tool | 按类型恢复原文:type:"seq" 配合 (seq N)/(seqs A-B) 标记,type:"result" 配合 result N 指针,type:"checkpoint" 配合 [checkpoint N] 序号——把原始内容一字不差地恢复到当前工具结果里 | | search 工具(给模型用,grep) | dsh-compaction-instant/tool | 在整个持久日志里按关键词/正则搜索——包括被压缩掉的内容——返回带 (seq N) 指针的匹配事件,可直接交给 recall 取回 | | /recall 命令(给人用,grep) | dsh-compaction-instant/command | /recall <关键词|正则> 追加一条持久的用户消息,内含匹配事件和 seq 指针,下一轮模型就能看到 | | 共享核心 | dsh-compaction-instant/recall + dsh-compaction-instant/search | seq 解析(123-7seq 12 / seqs 3-7)、日志展开、预算、字段筛选;正则编译与命中展示 |

Recall 能取回一切:文本、推理过程、工具调用的完整参数、嵌套的工具结果;只在日志里出现过的事件会以带标签的原始数据展示;找不到的 seq 会明确报错。maxRecallTokens 预算(默认 16000)超限时会截断并标注来源、统计跳过多少;搜索限制展示条数(maxSearchHits,默认 50)。这两个插件是独立的一行,可以挂在任何压缩引擎旁边——它们只读日志,不依赖本引擎。

每个检查点开头还附了一段简短的 RECALL 使用指南,告诉模型怎么用 recall / search 找回被省略的内容。如果更早的检查点因为空间不够被省略,它不会无声消失:会留下一行 [checkpoint N](N 是压缩序号,1 = 最早),用 recall(type:"checkpoint", id:"N") 就能完整恢复。

配置

所有配置项都可选,括号里是默认值。

默认含义
thresholdRatio0.5上下文用到多大比例时自动触发压缩(0.5 = 用到一半)
retainRatio0.05对话最新的一段(按窗口比例)一字不差地保留,不压缩
retainTokens直接指定保留多少 token;与 retainRatio 二选一
manualRetainRatio0.05手动 /compact 时保留当前对话的比例(保证正在聊的内容不会被收走)
manualRetainTokens手动模式直接指定保留 token 数;与 manualRetainRatio 二选一
autotrue开启自动压缩:监听 agent/pre-step 压力事件和 agent/request-error 溢出恢复
maxTokens8192单个检查点总预算的下限(按内容密度估算的 token)
checkpointScale0.1实际预算 = max(maxTokens, 被压缩掉的 token 数 × checkpointScale),再封顶于 checkpointCap——内容很多时不会把每条都压成一句话
checkpointCap65536检查点预算的封顶值
textTokens512每条助手文本的预算
userTextTokens1024每条用户文本的预算
toolCallTokens128每个工具调用单行的预算(这个永远不缩放——见下面的省略规则)
toolResultExcerptTokens256仅为兼容官方配置而接受;不起作用——工具结果本来就不占位置
includeReasoningfalse是否在检查点里保留推理过程
stripNoiseXmltrue是否去掉用户文本里配置的噪音标签
noisePatterns见 compiler噪音标签的正则来源,按 s 模式匹配
toolKeyFields内置额外的"工具名 → 参数里的关键字段"映射,用于单行展示
toolArgTools见 compiler白名单:这些工具的关键参数会显示在单行里(read/write/edit/glob/grep/bash/shell/web_search/skill/subagent/…);其余工具只显示名字
hideTools完全从检查点里去掉的内部管理工具
modelPolicies按 provider/model 单独覆盖 thresholdRatio/retain*(与官方配置格式一致)
compactionRetries / maxOverflowRetries1 / 1重试次数,含义和官方引擎一样
summarizationProvider / summarizationModel仅为兼容官方配置而接受;不起作用——本引擎从不调用模型

recall 工具和命令插件各自接受 { maxRecallTokens?: 16000, maxSearchHits?: 50 } 配置。

> Cordis 配置坑: 插件行的配置要经过 schemastery schema 校验,它的 ~standard 适配器会给每个没写的数组项注入 []toolArgToolshideToolsnoisePatternstoolKeyFieldsmodelPolicies)。本引擎把空数组当作"没设置",会回退到默认值——所以不写 toolArgTools 就自动用内置白名单(千万别用 toolArgTools: [] 想关掉它;空 = 默认)。debug: true 会把每次压缩的诊断写进 debugLogPath 指定的文件(默认 $DSH_HOME/compaction-debug.log)。

预算有两道保险:按 token 数限制,再按"预算 × 4"的字符数限制——所以再长的连续字符串(base64 大块、压缩过的文件)也绕不过去。工具调用永远是单行:不会缩放,预算不够时只压缩对话文本(每条最少留 32 token)。如果压缩结果还是超过(缩放后的)预算,先删最旧的工具行[N tool/result entries elided: seqs a-b]),再删其余最旧的条目([N earlier entries elided: seqs a-b])——工具调用永远挤不掉对话。最新的内容总能保住。

浏览器设置卡片(设置 → 插件)

从 0.1.4 起,引擎在任何装配了 settings 域的部署(标准 web/desktop profile 都有)上暴露一个用户设置命名空间(compaction-instant)。可编辑子集持久化到 settings.yaml叠加在插件行的 cordis 配置之上:

字段含义
checkpointScale压缩预算 = 被压缩 token 数 × 此比例
checkpointCap缩放后预算的绝对封顶
maxTokens一次编译检查点的总 token 上限
auto注册步骤间自动压缩
debug向日志文件写入引擎调试行
debugLogPath调试日志路径(留空 = $DSH_HOME/compaction-debug.log

其余字段(modelPoliciestoolArgTools 等)仍只由 cordis 配置管理。设置层永远弄不坏引擎:每次设置写入都会先经过完整配置解析器的重新校验才会持久化;未暴露的配置字段保持组合层的值。没有 settings 服务时引擎行为与之前完全一致(只看组合配置)。卡片注册在客户端 bundle 上,所以只要装上这个包就会出现,无需改任何部署配置——重启一次 dsh web 让启动图拾取 dsh.client bundle 即可。

分词与多语言

分词器是简单的字符规则:连续的英文字母算一个 token,连续数字算一个,标点一个字符一个,空格免费,其他每个字符算一个。具体:

内容Tokens
中文(你好,世界!每个字 1(共 6)
西里尔 / 阿拉伯文每个字符 1
带重音拉丁文(café英文部分成组(caf + é
Emoji(😀2(一个 emoji 占两个 UTF-16 单元)

所有截断都发生在字符边界——绝不会把一个 emoji 从中间切开(有 test/multilang.test.js 保证)。字符数上限按 UTF-16 长度算,对 emoji 这类字符偏保守。

另外,Harness 自带的 token 计量器(用于"压缩后必须变小"的检查、/compact 的用量报告)用的是另一套 字符数 / 4 + 固定开销 的估算,两套算法故意并存——详见设计说明。

保证

  • 即时——把旧内容扫描一遍就完成;不联网、不调模型、不占 KV 缓存。
  • 近无损——输出里只有原文;每处省略都有标记并注明出处 seq;之前的检查点原封不动保留。
  • 完全兼容的替换——接口、事件、计费(走同一个 ctx.tokenMeter)和报错方式与官方引擎一致,包括"压缩后必须变小"的检查(如果压缩完反而没变小,会被拒绝)。
  • 可选 pruner 兼容——和官方引擎一样会使用可选的 toolResultPruner 服务(它负责整理*保留部分*;被压缩的旧内容由本引擎自己处理)。

实测压缩率(真实会话、一条不丢)

数据来自真实会话日志(本项目的开发会话),编译时不丢弃任何一条——每条都保留,只做条目级截断和工具调用单行化。百分比是相对原文 token 数的比例。

负载原文 tokens编译后保留压缩
工具密集会话全量(3,181 节点:1,438 个工具调用 + 1,540 个工具结果)2,523,012226,2059.0%91.0%
另一个会话全量(864 节点)685,08862,7059.2%90.8%
同一个工具密集会话,最近 800 条消息625,92745,0317.2%92.8%
纯文本(同一会话去掉全部工具行)160,963109,94568.3%31.7%

压缩主要来自哪里(不丢条目的情况下):

  • 工具结果零成本——结果不产生条目,靠 -> result N 指针一个 recall 就能取回,这是最大的来源。
  • 工具调用一行化——每个调用压成一行(≤ 128 tokens,平均约 100)。
  • 思考过程不保留——reasoning 增量整体省略(有标记,不是悄悄丢)。
  • 对话文本近乎无损——纯文本对照组保留了 68.3%;文本上那约 1.5 倍压缩基本是剥掉 JSON 包装,外加只截断最长的几段。

预算扫描(同一个 252 万 tokens 的工具密集会话):从 cap ≈ 22.6 万 tokens(原文的 9%,正好接近默认 checkpointScale 0.1,但被 64K 硬顶截断)才开始丢条目。低于这个值代价是悬崖不是斜坡

Cap编译后保留条目数被丢
8,1928,2430.33%1112,090
32,76822,2630.88%2321,969
65,536(部署默认)55,7372.2%3251,876
65,53655,7372.2%3251,876
131,072131,0475.2%1,1421,058
226,205(一条不丢的临界值)226,2059.0%2,1990

安装

下面三种方法都用 Harness 自带的插件管理器安装(包发布在 npm,名字 dsh-compaction-instant;插件管理器会在 profile 目录里跑 pnpm,装完后宿主配置和每个 agent preset 都能找到它):

dsh plugin --profile web add <spec>

/compact 命令(dsh-command-compact)和用哪个引擎无关,任何安装方式下都照常工作。

方法 1 —— 顶替内置引擎(别名安装)

dsh plugin --profile web add "@deepseek-ai/dsh-compaction-basic@npm:dsh-compaction-instant"

dsh 目前没法让你选压缩引擎,内置预设(standardcodecordis)在配置里写死了包名 @deepseek-ai/dsh-compaction-basic。要让这些内置预设用上本引擎,就顶替内置插件:预设配置里的包名是从 profile 的 node_modules 解析的(优先级高于 Harness 自带的安装),所以把本包装到内置这个名字下面,所有内置预设就会自动加载本引擎——不动任何预设文件,预设以后升级也不受影响。

这样顶替是天然安全的:本引擎和官方引擎对外完全兼容——同一个 ctx.compaction 接口、完全相同的依赖注入列表llmtokenMetersessions)、相同的事件和报错方式,官方配置里的每一个键也都接受。把别名依赖删掉就恢复官方的引擎。

这种安装方式不会被识别成 bundle(Harness 会从自己的安装目录解析 @deepseek-ai/dsh-compaction-basic 这个名字,那里是官方包,没有 dsh.bundle 声明),所以没有任何自动化——需要把 recall 工具和 /recall 命令自己加进 profile 的 cordis.patch.yml(新行必须放在 insert 列表里;这个文件热重载,不用重启)。行名必须用别名包名(这种安装方式下只有它能解析);引擎行可选,只在需要给"没有压缩配置的预设"(如 minimal)提供宿主兜底时才加:

- id: compaction-basic
  disabled: true                     # 宿主层替换(可选兜底)
- insert:
    - id: compaction-instant
      name: '@deepseek-ai/dsh-compaction-basic'   # 给没有压缩配置的预设兜底
    - id: tool-recall
      name: '@deepseek-ai/dsh-compaction-basic/tool'
    - id: command-recall
      name: '@deepseek-ai/dsh-compaction-basic/command'

方法 2 —— 直接安装 + 让 AI 复制一份预设(dsh 创作模式)

dsh plugin --profile web add dsh-compaction-instant

然后用"预设创作"预设(内置的 cordis 预设,即「创造模式」)开一个会话,让 AI 执行:

> 复制 standard 预设,把它的压缩引擎行换成 dsh-compaction-instant

AI 会用 agentPresets.copy('standard', '<id>') 创建一份本地预设,在副本里改掉压缩行的 name,用 standingKeyFor('<id>') 校验能不能正常挂载,还可以通过改 agent-presets 行(config.default: <id>)把它设为默认。新预设会出现在 UI 选择器里;内置预设不受影响。

从 v0.1.1 起,本包还声明了 dsh.bundle,所以直接安装会自动注册成 profile 的配置层:自动禁掉内置的摘要引擎行、自动插入本引擎和 recall 工具(见包内 cordis.patch.yml)。宿主这边不用手动配置,只需复制预设。

方法 3 —— 直接安装 + 手动配置预设

dsh plugin --profile web add dsh-compaction-instant
mkdir -p "$DSH_HOME/.agent-presets/<id>"
# 从你想作为基础的内置预设复制配置和元数据
# (预设列表里能看到每个预设的真实路径):
cp <built-in-preset>/agent.cordis.yml "$DSH_HOME/.agent-presets/<id>/agent.cordis.yml"
# 在旁边写 preset.yml,包含 name + description

然后手工编辑副本里的压缩组——只改一行 name,仍在同一个隔离域(realm)里:

- id: compaction
  name: cordis:group
  group: true
  isolate:
    compaction: true
    toolResultPruner: true      # pruner 必须和引擎在同一隔离域
  config:
    - id: compaction-instant
      name: dsh-compaction-instant   # 原来是 '@deepseek-ai/dsh-compaction-basic'
    - id: command-compact
      name: '@deepseek-ai/dsh-command-compact'
    # ... 保留 pruner 行

规则:绝不改内置预设的安装文件;保留 isolate 隔离域;真正的检验是 standingKeyFor 挂载成功(或直接在预设上开一个会话)——预设列表里的 broken 标记只能发现解析错误。

方法 2 和 3 不需要任何宿主配置行:上面提到的 dsh.bundle 会自动注册好一切。

方法内置预设里的引擎要改预设文件吗选择器里多出预设安装成本
1. 别名替换✅ 自动(standard/code/cordis)一条命令 + 手动 patch
2. AI 复制副本只有新预设副本一句提示
3. 手动预设只有新预设副本手动编辑

> 每个上下文只能挂载一个 ctx.compaction 实现(接口文档写明"每个上下文加载一个实现");预设挂载各自有独立的隔离域,所以宿主和预设的实例永远不会冲突。

开发

npm test        # node --test(编译器单元测试、配置校验、会话集成、引擎)
npm run check   # 对所有源码做 node --check

本包依赖很少:@deepseek-ai/schemastery 用于配置校验;其余依赖都是 Harness 自己提供的。src/compiler.js 刻意零依赖,没有运行中的 Harness 也能单独跑单元测试。

和官方引擎的区别

  • 不调摘要模型 → 压缩从几秒变成几毫秒;不花摘要的 token。
  • 不改写 → 事实、文件路径、命令、变量名都一字不差;模型继续用自己的话接着聊。
  • 确定性 → 同样的内容永远压缩出同样的检查点。
  • 之前的检查点原样保留,而不是重新摘要一遍(又快又无损)。
  • 手动 /compact 会保留最近的一小段原文(manualRetainRatio,默认保留当前对话的 0.05)而不是压缩全部历史,正在聊的内容永远不会被收走;只有更早的部分进检查点。
  • compaction/summary 事件携带压缩后的条目本身——UI 里可展开的检查点行显示的就是模型实际看到的内容,外面包一层能自动变长的代码框(框线永远比内容里的 `` 长,所以含 markdown 的消息也能整齐地显示成一个代码块),检查点开头还有一段简短的使用指南,告诉模型怎么用 recall / search` 找回被省略的内容。
  • 权衡:对以长对话、叙述为主的历史,检查点的信息密度可能不如 LLM 摘要(长句是截断而不是合并)。正在进行的对话有逐字保留的尾部(自动 retainRatio 和手动 manualRetainRatio)兜底,其余内容都能通过 (seq N) 指针 + recall 找回来。

MIT 许可证。