Skip to main content
G

dsh-headroom

giter00/dsh-headroom

deepSeek harness上下文压缩工具

Install

dsh plugin --profile web add github:giter00/dsh-headroom

README

dsh-headroom

适配 DeepSeek Harness (dsh) 的上下文自动压缩插件,思路参考 Headroom

工具输出在进入模型之前先被压缩:JSON、搜索、日志、表格与长文本各自走专用压缩器; 所有有损压缩都会把原文存入本地 CCR store,并在压缩结果里注入一个短 marker, 模型需要精确原文时调用 headroom_retrieve(id=…) 即可逐字节取回。

 tool body settles
        │
        ▼
 tools/post-execute   ← dsh-headroom 在此压缩
        │
        ▼
 tool/result 进入 session log / 模型历史(压缩后内容 + CCR marker)
        │
        ▼
 模型需要原文时调用 headroom_retrieve(id=…)

特性

  • 自动压缩工具输出:挂载 tools/post-execute,在工具结果物化之前替换文本内容。

  • 内容路由,专用压缩器

    内容类型压缩策略
    JSON 数组/对象SmartCrusher 风格透视:_keys + _rows + _common,长单元格截断
    grep/ripgrep 结果按文件折叠:file (N matches) + line[:col]: rest
    构建/测试/日志连续重复行折叠 + 保留 error/fail/exception/assert 上下文
    CSV/TSV/markdown 表格保留表头与首尾行,中间行 offload
    长文本Kompress 风格 ML 压缩(默认):逐词打分 + must-keep 保护 + CCR 可逆取回;textStrategy: 'head-tail' 可切回首尾截断
    代码默认不压缩(JS 端口不做 AST 压缩,避免破坏可补丁字节;read/str_replace_editor 的行号前缀会先剥离再识别)
    文件工具默认不压缩read/str_replace_editor/edit/write 及其匹配 *.js/*.ts/*.json/*.yml 的路径)

Kompress 文本压缩(参考 HeadroomKompress-v2-base ML 模型): 文本按词切分 → 每词打分(score = keep概率 × (0.5 + 0.5 × span分数),模拟模型的 token 分类头 + span CNN 双头)→ score > 0.5 保留(或 targetRatio 取 top-k)→ 数字 / hex / 全大写标识符 / 路径 / 扩展名 / CLI flag / CamelCase 等语义脆弱词强制保留 → 保留词重组。默认评分器是确定性纯 JS 启发式;如需接入真实 Kompress-v2-base 模型,可库级注入自定义 scorer (compressKompressText(text, { scorer }) / createKompressCompressor({ scorer })), 管线完全一致(插件配置暂不暴露 scorer 项)。

  • 可逆压缩(CCR):所有有损压缩都保存原文,headroom_retrieve 按 id 精确取回; headroom_stats 查看节省量;headroom_compress 压缩任意文本。
  • 持久化:CCR store 默认写入 <DSH_HOME>/storages/dsh-headroom-ccr.json (1 秒去抖、原子替换、TTL + 最大条目数可配)。
  • 无害跳过:短文本、代码、错误输出、excludeTools 命中的工具、本插件自身工具 都不会被压缩。
  • 跨平台:纯 JavaScript + Node 内置模块,无原生编译依赖;路径全部通过 node:path 处理,DSH_HOME 支持环境变量覆盖,Windows / macOS / Linux 行为一致。 CI 矩阵见 .github/workflows/ci.yml

实现方式

flowchart LR
  A[ToolRuntime 工具执行完成] --> B[tools/post-execute]
  B --> C{文本块总长 >= minChars?}
  C -- 否 --> Z[原样返回]
  C -- 是 --> D[ContentRouter 类型检测]
  D --> E[json] --> E1[SmartCrusher 透视]
  D --> F[search] --> F1[按文件折叠]
  D --> G[log] --> G1[重复折叠 + 错误保留]
  D --> H[tabular] --> H1[首尾行保留]
  D --> I[text] --> I1[Kompress 逐词打分 + must-keep 保护]
  I1 -. 无收益 .-> I2[回退首尾截断]
  D --> J[code] --> Z
  E1 & F1 & G1 & H1 & I1 & I2 --> K{压缩后 + marker 更小?}
  K -- 否 --> Z
  K -- 是 --> L[写入 CCR store]
  L --> M[替换 decision.content]
  M --> N[模型看到压缩内容 + headroom_retrieve marker]
  • lib/compress.js:纯函数压缩器,无 node:* 依赖,可独立测试。
  • lib/kompress.js:Kompress 风格文本压缩管线(word 级评分 + must-keep 保护), 参考 Headroom 的 Kompress-v2-base ML 模型;评分器可插拔(默认纯 JS 启发式)。
  • lib/ccr.js:CCR store,内存 Map + 去抖持久化到 <DSH_HOME>/storages/
  • lib/index.js:dsh 插件入口,注册 tools/post-execute 监听器与三个工具。
  • dsh.plugin.json + cordis.patch.yml:dsh 插件/bundle 清单与补丁。

压缩效果

压力测试配置(更激进,用于验证压缩器上限)

node scripts/verify-compress.mjsminChars=120, maxRows=40, maxCellChars=80, maxTextChars=400 下的结果:

样本类型压缩前(字符)压缩后(字符)节省
JSON 数组 200 行json62 4919 30285.1%
grep 结果 270 条search10 7724 60357.3%
日志 180 行log3 9091 12571.2%
CSV 201 行tabular19 8143 02984.7%
长文本 400 段text29 50654698.1%
Kompress 长文本(事实+重复词)text16 4392 02987.7%
代码code4934930%(故意不压)
短文本text19190%(未达阈值)

token 估算:脚本按 chars / 4 粗估,实际 token 与模型 tokenizer 相关。 所有有损压缩均保存原文,headroom_retrieve 可精确取回。 Kompress 样本:关键事实(HTTP/500/hex/路径/IndexError)全部保留, 重复的 boilerplatephrase 被删除且可从 CCR 恢复。

默认配置

默认配置更保守(minChars=600, maxRows=80, maxCellChars=200, maxTextChars=2400):

样本类型节省
JSON 数组 200 行json65.6%
grep 结果 90 条search41.3%
日志 180 行log56.8%
CSV 201 行tabular59.8%
长文本 400 段text94.7%

不损害效果的验证

node scripts/verify-compress.mjs 同时断言:

  1. 结构化输出中的关键事实(JSON 键/计数、文件分组、ERROR/WARN 行)在压缩后仍可见;
  2. 代码、短文本、错误输出保持字节不变;
  3. 每个有损压缩的原文都能通过 headroom_retrieve 逐字节取回
  4. 长文本中间被省略的 NEEDLE-42 事实,压缩视图不可见,但 CCR 能精确恢复;
  5. Kompress 压缩后 HTTP/500/0x1f4d2a8b//var/log/app.log/IndexError 等 语义脆弱事实仍可见,重复的 boilerplatephrase 被删除且可经 CCR 恢复。

node scripts/verify-apply.mjs(需要能解析 @deepseek-ai/dsh-tools)进一步验证:

  • apply() 注册了 tools/post-execute 监听器和 3 个工具;
  • 大 grep 输出在进入模型前被压缩并带 marker;
  • headroom_retrieve 取回原文与压缩前完全一致;
  • fs-* 排除工具、自身工具、代码、错误、短输出全部原样。

安装

环境要求

项目要求
Node.js>= 22.0.0(推荐 Node 22 LTS 或更高)
DeepSeek Harness>= 0.0.1-rc.5 < 0.1.0
包管理器推荐 pnpm >= 11npm / yarn 也可用于本地开发
操作系统Windows / macOS / Linux(纯 JS,无原生编译)

一键安装(推荐)

直接从 GitHub 仓库安装(Windows / macOS / Linux 通用):

dsh plugin --profile web add github:giter00/dsh-headroom

如果 dsh 不在 PATH 上,可先定位 profile 内的 CLI 再执行同一命令:

# Windows PowerShell
node "$env:USERPROFILE\.dsh\profiles\node_modules\@deepseek-ai\dsh\lib\bin.js" plugin --profile web add github:giter00/dsh-headroom

# macOS / Linux
node "$HOME/.dsh/profiles/node_modules/@deepseek-ai/dsh/lib/bin.js" plugin --profile web add github:giter00/dsh-headroom

pnpm 会在安装时拉取 GitHub 仓库的默认分支(main),并自动把 dsh-headroom 追加到 profile 的 bundle 列表。

手动安装

也可以直接编辑 <DSH_HOME>/profiles/web/package.json

{
  "dependencies": {
    "dsh-headroom": "github:giter00/dsh-headroom"
  },
  "dsh": {
    "profile": {
      "bundles": [
        // ...其他 bundles
        "dsh-headroom"
      ]
    }
  }
}

然后进入 profile 目录安装依赖:

cd "$DSH_HOME/profiles/web"      # Windows PowerShell: cd $env:DSH_HOME\profiles\web
pnpm install

重启 dsh 后生效。

卸载

dsh plugin --profile web remove dsh-headroom

配置

在 profile 的 cordis.patch.yml(或 --patch 覆盖层)中可覆盖默认配置:

- id: dsh-headroom
  config:
    enabled: true
    minChars: 600
    maxRows: 80
    maxCellChars: 200
    maxSearchMatchesPerFile: 60
    maxLogLines: 80
    maxTextChars: 2400
    maxTabularLines: 80
    excludeTools: []
    noFoldForTools: ['read', 'str_replace_editor', 'edit', 'write']
    noFoldForPatterns: ['*.js', '*.ts', '*.json', '*.yml', '*.yaml']
    markerStyle: full          # full | compact
    includeErrors: false
    textStrategy: auto        # auto | kompress | head-tail
    kompress:
      enabled: true
      minWords: 10
      chunkWords: 350
      scoreThreshold: 0.5
      targetRatio: null       # null=阈值决策;0.3=强制保留 30% 最高分词
      mustKeep: true
      maxWordChars: 64
    ccr:
      enabled: true
      persist: true
      ttlMs: 86400000
      maxEntries: 2000
字段默认值说明
enabledtrue总开关
minChars600文本块至少多少字符才考虑压缩
maxRows80JSON 透视保留的最大行数
maxCellChars200JSON 单元格字符串截断长度(search 匹配行保持全文)
maxSearchMatchesPerFile60每个文件保留的搜索命中数
maxLogLines80日志保留的首尾行数
maxTextChars2400长文本首尾保留字符数(head-tail 策略)
maxTabularLines80表格保留的首尾行数
excludeTools[]* 通配符;命中的工具不压缩
noFoldForTools['read','str_replace_editor','edit','write']文件内容类工具永不压缩,避免 read→edit 快照不一致
noFoldForPatterns['*.js','*.ts','*.json','*.yml','*.yaml']匹配到的文件路径/工具名不压缩;保护源码与配置文件
markerStyle'full'full=保留策略/节省量与 headroom_retrieve 提示;compact=只保留 id="hr:…",减少标记噪音
includeErrorsfalse是否压缩工具错误输出
textStrategy'auto'长文本策略:auto=Kompress 优先、无收益回退 head-tail;kompress=仅 Kompress;head-tail=仅首尾截断
kompress.enabledtruefalse 时文本走 head-tail
kompress.minWords10少于该词数的文本跳过(与 Headroom 一致)
kompress.chunkWords350每块词数(Kompress-v2-base 训练口径,与模型耦合)
kompress.scoreThreshold0.5保留阈值:score > 阈值 才保留(与 Headroom 默认一致)
kompress.targetRationull强制保留比例(按分数取 top-k);null 用阈值决策
kompress.mustKeeptrue语义脆弱词(数字/hex/全大写/路径/扩展名/flag/CamelCase)强制保留
kompress.maxWordChars64超过该长度的词(如无空格中文长串)细分后评分
ccr.enabledtrue关闭后不进行有损压缩
ccr.persisttrue是否持久化 CCR store
ccr.ttlMs86400000原始内容保留时长(毫秒)
ccr.maxEntries2000内存/持久化 store 最大条目数

模型可见工具

工具参数作用
headroom_retrieveid取回被压缩工具结果的完整原文
headroom_compresstext压缩任意文本,返回策略与压缩结果
headroom_stats查看本进程压缩统计

压缩后的 tool result 会携带如下 marker:

[headroom: search-fold 12345→987 chars; headroom_retrieve(id="hr:0123456789abcdef")]

项目结构

dsh-headroom/
├── lib/
│   ├── index.js          # dsh 插件入口:post-execute 钩子 + 3 个工具
│   ├── compress.js       # 内容路由与确定性压缩器(纯 JS,无 node:* 依赖)
│   ├── kompress.js       # Kompress 风格文本压缩管线(词级评分 + must-keep 保护)
│   └── ccr.js            # CCR store:内存 + 去抖持久化
├── scripts/
│   ├── verify-compress.mjs   # 压缩效果 / 信息保留 / CCR 可逆验证
│   └── verify-apply.mjs      # apply() 集成冒烟(需要 dsh-tools 可解析)
├── tests/
│   └── compress.test.js      # 单元测试
├── dsh.plugin.json           # dsh 插件清单
├── cordis.patch.yml          # bundle patch
├── package.json
├── README.md
├── README.en.md
└── LICENSE

开发与验证

# 语法检查
node --check lib/index.js && node --check lib/compress.js && node --check lib/ccr.js

# 单元测试(无需 harness 依赖)
node tests/compress.test.js

# 压缩效果 + 信息保留 + CCR 可逆验证(无需 harness 依赖)
node scripts/verify-compress.mjs

# apply() 集成冒烟(需要 @deepseek-ai/dsh-tools 可解析,
# 例如链接 dsh checkout 的 node_modules)
node scripts/verify-apply.mjs

已知限制

  • 默认评分器是启发式模拟,不是真实模型推理lib/kompress.js 忠实移植了 Headroom Kompress-v2-base 的管线结构与评分公式,但默认打分来自确定性纯 JS 启发式; 需要真实模型语义打分时,可库级注入 ONNX/PyTorch scorer。
  • Kompress 输出是保留词碎片:为追求高压缩率,默认阈值会删除大量普通词,输出可读性 有限,适合给模型看要点;精确原文始终可通过 headroom_retrieve 逐字节取回。
  • 保守不压缩场景:全部由 must-keep 类词组成的文本、纯重复中文文本会直接走 head/tail 回退或原样返回,防止把内容删光。
  • 模板文本不去重:高频重复的数字/标识符会逐个保留(must-keep 语义),模板化输出 可能保留较多重复事实 token,压缩率低于普通散文。

与 Headroom 的差异

维度Headroomdsh-headroom
集成方式proxy / wrap / MCP / SDKdsh 原生插件,直接挂 tools/post-execute
JSONSmartCrusher(Rust core)JS 透视压缩(_keys/_rows/_common
代码AST CodeCompressor默认跳过(保证可补丁字节安全)
文本Kompress-v2-base ML 模型(ONNX/PyTorch)同款 Kompress 管线(词级评分 + must-keep + 阈值/top-k);默认纯 JS 启发式 scorer,可通过 createKompressCompressor({ scorer }) 库级注入真实模型后端(插件配置暂不暴露)
可逆性CCR本地 CCR store + headroom_retrieve
原生依赖部分 extra 需要(onnxruntime/torch)无(默认启发式);接入真实模型时才需要外部依赖

License

MIT

致谢

本项目的设计思路与压缩策略参考 Headroom(Apache-2.0)。

Related plugins