Skip to content

dsh-token-optimizer

Verified

@zoria-lind/dsh-token-optimizer · v3.0.0 · MIT · Web UI

分层 Token 优化管道:输出阶梯 / 工具裁剪与 MCP 懒加载 / 压缩设置与状态 / runtime 原文归档,基于 DSH 真实插件 API

Install

dsh plugin add @zoria-lind/dsh-token-optimizer

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Readme

dsh-token-optimizer

v3.0.0 变更摘要(2026-10-29):重写 MCP 工具发现/懒加载(按名称与描述搜索、分页、真实可见性确认、重连恢复);暂停缺少可靠失效证明的 cache 与 fileDiff;通用设置新增“Token 优化与压缩”(旧驱动/分层/关闭、阈值、状态记录);新增 runtime 原文归档与 conversation_archive 回查工具;修复预设级摘要/清理服务的作用域读取。升级前请先读下面的“升级到 3.0”。

v2.2:分层压缩编排 layeredCompact(L0 观测 / L1 清理历史工具结果 / L2 模型摘要,默认关)、/token-status、outputLadder 基线重建、按会话分桶统计。

DeepSeek Harness 分层 Token 优化管道。在 DSH 已内置能力之外做真实增量: 把进入模型的文本压缩/裁剪/采样,降低上下文开销;摘要和采样可能丢失细节,任务质量与实际费用需要分别验证。

基于真实 DSH 插件 API(agent/pre-step、tools/execute、tools/post-execute、agent/status 等)实现, 与社区方案文档中虚构的事件(如 message:before / context:building)无关。

它做什么(30 秒版)

模块 钩子 作用
text2img agent/pre-step 长文本(≥1000 字符)→ 弹窗询问(转图摘要 / 直接阅读原文,推荐项与超时默认按内容类型定)→ 渲染成图 → vision 读图 → 摘要替换进上下文。动态分辨率分档(800×450 / 1440×810 / 1920×1080),摘要磁盘缓存跨会话 0 API 调用。单次样本曾省 ~72%;真正价值是长会话越省(后续轮次不再携带原文)
outputLadder tools/post-execute 工具输出出生点单次遍历分流:错误结果→300 字符摘要;JSON 数组/CSV(≥10k 字符)→结构感知压缩;shell 输出(≥8k 字符)→头尾+等距采样;≥50k 字节交核心 spill;read 类豁免。原文落盘可逆
cache(暂停) tools/execute 默认关闭;glob/grep 每次都重新执行,不复用可能过期的结果
fileDiff(暂停) tools/post-execute 当前始终保留原文;不能确认模型请求仍持有基线时不生成 diff
toolTrim agent/created 工具可见性管理:静态裁剪 + MCP 懒加载——不用的 mcp__* 工具 schema 不进原生工具定义列表;目录按名称/描述搜索与分页,加载后确认真实可见
compactionDriver / layeredCompact agent/status 旧驱动或分层互斥调度核心压缩;阈值可配置,准确区分尝试、成功和跳过原因
monitor session/disposed 会话结束输出节省统计 + 真实 usage 聚合与缓存命中率(长会话常态 97%–99.3%)

与 DSH 核心的边界

DSH 已内置 token-meter、compaction-basic、tool-result-pruner、spill、llm-retry、repeat-tool-reminder—— 本插件一律不重复实现,只做上面这些内置之外的增量。

安装

dsh plugin --profile web add @zoria-lind/dsh-token-optimizer

本地开发目录也可以直接挂载:dsh plugin --profile web add ./dsh-token-optimizer。

卸载:

dsh plugin --profile web remove @zoria-lind/dsh-token-optimizer

升级到 3.0

这是带破坏性配置语义的主版本升级。升级前请检查 profile 的 cordis.patch.yml:

  • toolTrim.allow: [] 的含义反转:2.x 里空数组表示“不限”,3.0 起表示“禁止所有可裁剪的继承工具”(与内核 restrict 的空 allow 语义一致)。想要“不限”请删除该键或写 allow: null。
  • 过时的内置工具白名单已移除:bundle 不再硬编码旧工具名。你自己配置的长白名单仍会生效,但会让名单外的新工具不可见,建议人工审阅。
  • cache / fileDiff 默认停用:两者都缺少可靠的失效/基线证明,3.0 不再复用缓存或只发 diff 原文片段,即使旧配置写了 enabled: true 也只透传原结果。相关参数保留仅为配置兼容。
  • 新增通用设置“Token 优化与压缩”和 runtime 原文归档,默认都不改变你现有的压缩策略。

工具发现与 MCP 懒加载

工具目录不再塞进工具 description 后截断。固定大小的发现工具支持按名称/描述搜索与分页,隐藏后仍可搜索描述,目录末尾也可找到。先成功注册并确认发现工具在当前作用域可见,再隐藏 MCP;注册失败、接口缺失或名字冲突时保留原可见性。以下行为按 DSH 0.2.1-rc.2 的 tools 服务源码核对;真实 API token 节省需要你自己测量。

  • 显式 allow/deny 与父作用域限制继续执行;不接管别人注册的同名工具。后续 tools/change 可重试。
  • 加载后检查当前作用域的真实 view;失败、用户限制或父作用域拦截会返回原因,不记为成功。重复加载不重复计数;同名重连刷新目录,断开最后一个 MCP 不撤销静态限制。
  • cache 和 fileDiff 已暂停,默认关闭;旧配置即使 enabled:true 也只透传。glob/grep 每次重新执行;fileDiff 保留内层决定中的全文、非文本内容及 additionalContexts,不再写其旧原文目录或记录虚假节省。3.0 未建立可靠的文件失效机制,也未证明某份完整文件基线仍在当前模型请求中;仅监听压缩事件不能替代这一证明。
  • bundle 移除旧内置工具白名单,避免新工具因名单过期而消失。显式用户策略仍保留,不自动扩大权限。

配置迁移:

  • toolTrim.allow 省略或为 null:不设置静态白名单,未来新增内置工具保留可见。
  • toolTrim.allow: []:禁止所有可裁剪的继承工具。allow 非空只允许列出的精确名称;deny 优先。未知/已断开的白名单名被移除后,即使名单为空,也不会变成无限制。
  • 旧版把 allow: [] 当作“不限”,3.0 起必须改为省略 allow 或 null。旧 bundle 生成的长白名单也需要人工审阅;保留它就会继续禁止名单外 MCP,加载器不能扩大该名单。
  • 核心对作用域自注册工具豁免 restrict;本插件的发现工具属于此类。显式 deny 发现工具名会停用该作用域懒加载。父层限制同样作用于继承能力,子代理不能靠本加载器越权;父层白名单若需要让子代理使用继承的发现工具,也应包含该名称。
  • cache.ttl 与 fileDiff 的旧参数保留配置兼容性,暂不生效。后续实现可靠失效与当前请求基线证明后,再另行评审是否恢复。

模型调用发现工具的例子(均为 mcp_load_tools):

{"query":"database","offset":0,"limit":10}
{"offset":10,"limit":10}
{"names":["mcp__server__exact_tool_name"]}

query 默认空字符串,支持名称和完整缓存描述的大小写不敏感子串匹配,最多取前 200 字符;offset 默认 0;limit 默认 10、上限 20;names 每次处理前 20 个并报告忽略数量。结果含 matched/nextOffset/items,加载后仍受限制会列在 failed 中。只在成功确认可见时增加加载计数。目录使用全局公开 view 中的定义作为元数据补充,实际加载始终按 agent 的 view 和过滤权限验证。

验证命令:

node test/smoke.mjs
node test/modules.test.js
node test/availability.mjs

smoke 已包含 availability 用例;3.0 发布前 smoke 245 项、modules 4 项、归档专项 19 项通过。测试覆盖 1000 个工具目录、父子作用域、失败恢复、断开重连、立即销毁、真实文件新增/修改,以及跨 cwd/会话/上下文重置时原文保留。定义规模只是测试夹具的 JSON 字节数,不能换算成真实 API token 节省或桌面体验结论。

压缩设置与状态

通用设置新增“Token 优化与压缩”:可选旧驱动、分层或关闭插件自动压缩;工具历史清理和模型摘要阈值支持百分比输入、滑块,观测线及旧驱动阈值在高级设置中。当前默认仍是旧驱动开启、分层关闭,不自动迁移策略。

分层默认值为:40% 仅观测,50% 清理历史工具结果;清理后复测仍达到 65% 才尝试模型摘要。清理会遮蔽部分历史工具结果;摘要可能丢失任务细节。“可以回查”并不保证摘要无损。旧驱动默认 45%,还受至少 6 轮、100000 估算 token 等条件限制。

保存时客户端和后端都校验 0 < 观测线 ≤ 清理线 < 摘要线 < 100%,旧驱动阈值也须在 0% 与 100% 之间。两套开关和阈值一次提交;保存后下一次 idle 检查读取新配置,已经执行的操作使用原配置快照。切换控制器保留各自成功配额和统计;两者不会并发压缩同一 agent。关闭插件自动压缩不关闭宿主自身的安全压缩。

在当前对话运行 /token-status 可查看生效控制器、阈值、估算压力、窗口来源,以及本插件在当前 agent 的最近六条检查/清理/摘要记录。记录区分尝试、成功、无安全有效区段、忙、超时、失败,包含时间、前后估算量、耗时和模型调用是否确认。空结果不记成功、不占成功配额;同一历史上的无效摘要短暂退避。分层在内核报忙后沿用原来的本会话停止自动摘要策略。

窗口来自最近有效 request/context 声明,缺失时采用配置回落值并标明不确定;它不是模型容量的实测结果。上下文估算量减少不等于账单净节省,宿主未提供逐次摘要 usage 时不推算摘要费用。内核自动/手动/其他插件发起的压缩不计入本插件记录。

设置依赖宿主 React、slots、configForms 和可解析的 @deepseek-ai/schemastery。复用宿主模块,不安装新依赖;schema 解析失败不阻断插件。设置未 served、未就绪或只读时,页面显示默认参考/不可编辑提示,仍可用命令检查状态。

设置投影、volatile 配置与 UI 逻辑由自动测试覆盖;真实桌面面板展示与保存仍需实机确认。3.0 未调整宿主摘要保留范围,也未证明模型摘要能保留所有用户原话和约束。

测试:node test/smoke.mjs 包含压缩和 UI 逻辑回归;单独可运行 node test/compression.mjs。设置投影/volatile 契约检查需将 DSH_OPTIMIZER_HOST_FIXTURE 指向隔离宿主夹具目录,缺失时明确跳过这些用例。

runtime 原文归档

在通用设置“Token 优化与压缩”中的“runtime 原文归档”,填写绝对目录、勾选并单独保存;默认关闭,不指定默认写盘路径。当前提供可编辑路径及前后端校验。切换目录不搬迁旧文件,旧目录自动保留为回查来源。开关不影响宿主原生会话日志,关闭或卸载不删除归档。

原始用户消息先经 agent/pre-step 捕获,等待 JSONL 写入和 fsync 成功,再交给文字摘要等改写及上下文接纳。模型输出先生成,再保存流片段、最终消息或中断/失败终态;普通请求和默认摘要请求通过 llm/stream、session/flush 等待归档。复用 DSH 0.2.1-rc.2 的公开接口及原生 checkpoint policy,不修改内核/ASAR;不同加载顺序下,失败可能表现为等待恢复或请求直接失败,两种都不会静默继续调用模型。直接失败后需重新发起请求。

写失败保留待写内容并暂停相关请求。可点击“重试归档”、在当前会话执行 /token-archive-retry、修改保存目录,或明确关闭归档后继续;/token-status 显示归档状态、已确认事件序号、待写数量、错误代码和回查工具是否可用。设置保存或重试提交成功不表示内容已落盘。取消等待会恢复本批尚未接纳的输入至待处理队列,不自动再执行;仅保留在内存中的失败缓冲不能跨强制退出恢复,原生仍保存的事件可在重启后补录。

每个会话使用稳定 key 去重,各进程/插件生命周期分别写独占段;内存索引可从当前目录及历史目录的 JSONL 重建。只有写盘确认后才推进归档游标;写入部分失败尝试截回本批起点,完整损坏行报错而不覆盖。崩溃留下的无换行尾段仅在确认所属进程已退出时修复,可能仍在使用的段报忙。开启前的流片段无法补录;历史消息只按宿主仍保存的事件回填,摘要不冒充缺失原文。文件中的摘要前 checkpoint 表示归档覆盖检查,不能当作压缩成功记录。

模型在当前会话使用 conversation_archive 按需取回原文:

{"action":"search","query":"截止时间","limit":10}
{"action":"read","key":"搜索返回的key","offset":0,"limit":2000}
{"action":"status"}

search 返回短摘录及 key;nextOffset 非空须继续翻页。默认查原始输入、接纳输入和模型终态;可用 role: "assistant-stream" 查流片段。每页最多检查2000条索引、读取约2MiB(允许完成一条最大16MiB的记录),匹配上限20条。超过16MiB的记录会明确列为未全文检索,单条读取也给出本地文件路径。read 按 Unicode 字符分页,默认2000、上限4000字;不把整个档案自动塞回上下文。回查工具注册在当前 agent 自有作用域,继承工具裁剪及 MCP 懒加载不会隐藏它。

归档专项验证直接抽取安装包中的 Inbox、preStep、flush、checkpoint policy、LLM 分发和压缩事务方法,使用虚构数据做真实文件写入、同步与故障注入;上下文组装、投影、会话校验器及模型提供者为夹具。它不能等同于整套桌面验收、断电实验、真实模型任务质量或净 token 节省。第三方绕开带 sessionId 的流入口不在当前保证范围;能回查原文也不保证模型主动找回每个细节。

test/archive.mjs 依赖本机抽取的宿主夹具(不走 npm 安装,因此不在发布包里),需要 DSH_TO03_STATE 指向隔离状态目录。

配置

下方是插件代码默认值;bundle 安装模板会启用 toolTrim。挂载后在 profile 的 cordis.patch.yml 中覆盖(示例,均为默认值):

- id: token-optimizer
  name: '@zoria-lind/dsh-token-optimizer'
  config:
    archive:
      enabled: false
      directory: ''            # 启用前在通用设置填写绝对路径
      previousDirectories: []   # UI 换路径时自动保留旧目录
      retryGeneration: 0
    text2img:
      enabled: true
      threshold: 1000
      askOnSkip: true        # false = 不弹窗,回退自动行为(自然语言自动转图/结构性强跳过)
      askTimeoutMs: 120000   # 询问超时,超时按内容类型默认执行
      maxAsksPerSession: 0   # 每会话弹窗上限(0=不限),嫌弹窗多可设 3~5,超限按内容类型默认静默执行
      summaryCache: true     # 内容 hash → 摘要磁盘缓存,跨会话命中 0 API(含原文落盘去重)
      dynamicResolution: true
      resolutionTiers:       # 按字数分档(尺寸经实测校准:YaHei 行高 ≈1.9×字号,
                             # 密度保持在已验证安全的 ~1千字/页 以内)
        - { maxChars: 2000, width: 800, height: 450, fontSize: 24 }
        - { maxChars: 6000, width: 1440, height: 810, fontSize: 24 }
        - { maxChars: Infinity, width: 1920, height: 1080, fontSize: 36 }
      renderWidth: 1200      # dynamicResolution=false 时的固定宽度
      pageFontSize: 24       # dynamicResolution=false 时用
      pageMaxHeight: 3000    # dynamicResolution=false 时用
      visionModel: 'deepseek-v4-flash-vision-exp'
      baseUrl: 'https://api.deepseek.com/v1'
      maxSummaryChars: 2000
      maxSummaryRatio: 0.4    # 摘要上限 = min(maxSummaryChars, 输入字数×0.4),保证替换后比原文短
      pagesPerBatch: 4        # 分批摘要:每批最多 4 页送 vision(防"只读开头几页"),再纯文本合并
      saveOriginal: true
    outputLadder:
      enabled: true
      structureThreshold: 10000
      compressionRate: 0.5
      preserveHeadTail: 1000
      shellTools: ['pwsh', 'bash', 'sh', 'powershell', 'zsh', 'cmd']
      shellThreshold: 8000
      headLines: 10
      tailLines: 10
      sampleInterval: 20
      errorSummaryChars: 300
      spillBytes: 50000
      readTools: ['read', 'read_image']
      saveOriginal: true
    cache:
      enabled: false          # 暂停:缺少可靠文件失效机制;旧 true 也透传
      ttl: 3600
    fileDiff:
      enabled: false          # 暂停:不能证明当前请求仍有完整基线
      tools: ['read']
      minSize: 2048
      maxFileBytes: 200000
      contextLines: 3
      collapseUnchanged: true
    toolTrim:
      enabled: false          # 默认关闭;启用后对每个 agent 作用域生效
      allow: null             # 省略/null=不限;[]=禁止所有继承工具
      deny: []
      mcpLazy: true
      mcpPrefix: 'mcp__'
      mcpLoadToolName: 'mcp_load_tools'
    compactionDriver:
      enabled: true
      pressureRatio: 0.45     # totalTokens / contextWindow 超过该比才触发
      minTurns: 6
      minTokens: 100000
      maxCompactionsPerSession: 3
      contextWindow: 1000000
      timeoutMs: 120000
    memory_bridge:            # dsh-memory-bridge 联动占位节(阶段 3b 完成后开开关)
      enabled: false
      sync_dir: '~/.dsh-memory'
      compress_on_sync: true
      compression_strategy: 'time_decay'
      text2img_threshold: 1000
      dynamic_resolution: true

v1 的 compress / sample / pruning / dedup 节已退役(合并进 outputLadder),旧配置节会被静默忽略并在日志提示,不会导致加载失败。

web 部署必读:重新启用核心压缩后端

dsh-web-app 的 bundle patch 默认禁用了 compaction-basic 与 command-compact(配合 /compact 命令), web 部署因此没有 compaction 服务,插件摘要调度无法运行,/token-status 会记录服务不可用。在 profile 的 cordis.patch.yml 顶层补:

- id: compaction-basic
  disabled: false
- id: command-compact
  disabled: false

依赖

  • text2img 渲染:Windows 需 PowerShell + .NET System.Drawing(scripts/render-text.ps1,免第三方依赖);非 Windows 渲染降级为仅落盘原文。
  • text2img 摘要:需 DEEPSEEK_API_KEY 环境变量(DSH 已配置)。
  • mcpLazy:需 profile 挂载 @deepseek-ai/dsh-mcp-client 并配置至少一个 MCP 服务器;无 MCP 时自动 no-op。

开发

node test/smoke.mjs          # 单进程全量自检(无需 API),npm test 同
node test/modules.test.js
node test/text2img-e2e.mjs   # 真实端到端(需 API key + Windows 渲染)

路线图

  • 自然语言配置工具(让模型改配置)
  • 长文本→图片的跨平台渲染 fallback
  • 与 dsh-behavior-enhancer 协同(内容压缩 × 行为管理,可独立安装)
  • dsh-memory-bridge 联动(配置节已占位,扩展 + bridge 服务就绪后开开关)