鱼皮AI导航
鱼皮AI导航
  • 主页
  • 社区
  • AI工具
  • AI知识库
  • AI提示词
  • MCP
  • Skills
  • AI学习资源
  • AI资讯
  • GitHub开源
登录/注册

dsh-token-saver

为 DeepSeek Harness 设计的 token 节省插件:不损失任务效果。默认 conservative 档对工具结果做无损头尾裁剪与 grep 折叠;balanced 档在压力阈值委托 dsh-compaction-basic;aggressive 档以 LLM-summary 引擎子类化替换官方压缩。8 个合成场景累计节省 97.6% 输入 tokens,所有削减走 dsh 事件流,model-visible = logged 不变式仍成立。

用量计费
访问 GitHub
文档README

dsh-token-saver

一个为 DeepSeek Harness (dsh) 设计的 Cordis 插件。激进节省 token、绝不破坏任务效果。

dsh-token-saver 通过挂载三个扩展点节约 token:tools/post-execute(无损头尾裁剪 / grep 折叠)、agent/pre-step(委托官方 ctx.compaction)、以及可选的 prompt-cache 段稳定排序。所有改写都走 dsh 的事件流,不会触发"model-visible 与 logged 不一致"不变式。


目录

  • 为什么需要它
  • 四种模式
  • 安装
  • 配置参考
  • 测试效果
  • 如何保证不影响任务效果
  • 开发
  • 架构
  • License

为什么需要它

DeepSeek 这类 agent 在长任务里 80%+ 的 prompt tokens 来自两类内容:

  1. 被读出来的大文件 —— 一次性 read 一个 1MB 的迁移 SQL 就要吃掉 250k tokens。
  2. 被反复搜索出来的命中结果 —— grep 几十个文件,回填全部 grep 结果,模型根本没读完。

dsh-token-saver 默认 conservative 档只做一件事:完整保留头/尾,中间的部分用一行 metadata 替换。这是一种"lossless"折叠 —— 模型仍然知道"中间被截断了",但实际送进 model 的字符数降到几千。

更激进的 balanced/aggressive 档再叠加:

  • delegate 给 dsh 官方 ctx.compaction.compactIfNeeded() 在压力阈值被触发时自动滑窗
  • 替换 dsh-compaction-basic 为我们自己的 LLM-summary engine(用户接入 LLM 调用函数即可)

详见 测试效果 章节的真实数据。


四种模式

模式tools/post-execute 头尾裁剪grep 折叠agent/pre-step 触发 ctx.compaction替换 dsh-compaction-basicLLM-summary engine
off❌❌❌❌❌
conservative (默认)✅✅❌(保留 dsh 默认行为)❌可选
balanced✅(更紧的 budget)✅✅❌推荐
aggressive✅(更紧的 budget)✅✅✅推荐

默认 conservative:完全不替换 dsh 原生链路,只对读出来的工具结果做无损头尾折叠,任务效果零损失风险。


安装

dsh 安装好后,在你的 harness home 里执行:

▼
bash
复制代码
dsh plugin --profile web install dsh-token-saver

要锁定版本:

▼
bash
复制代码
dsh plugin --profile web install dsh-token-saver@0.1.0

安装方式(按发布状态)

来源命令说明
npm registry(推荐)dsh plugin --profile web install dsh-token-saver@0.1.0待 npm publish 后可用;目前走 GitHub tarball 或本地 pack
GitHub Release tarballdsh plugin --profile web install https://github.com/Shaw529/dsh-token-saver/releases/download/v0.1.0/dsh-token-saver-0.1.0.tgz预构建 tarball,16.8KB,跳过 allowBuilds
本地 tarball(开发中版本)pnpm run build && pnpm pack → dsh plugin --profile web install ./dsh-token-saver-0.1.0.tgz本地 build 后打包
源码仓库(不推荐)dsh plugin --profile web install https://github.com/Shaw529/dsh-token-saver走源码构建,需要 allowBuilds 授权

v0.1.0 release 已发布到 GitHub,附预构建 tarball。npm publish 暂未完成(待 npm login),预期下个版本时一并发布。

本地开发模式:

▼
bash
复制代码
pnpm add dsh-token-saver

配置参考

cordis.yml 插件行示例:

▼
yaml
复制代码
- name: 'dsh-token-saver' config: mode: balanced headBytes: 16384 tailBytes: 8192 grepMaxMatches: 30 grepContextLines: 2 grepHeadBytes: 8192 grepTailBytes: 4096 pressureThreshold: 0.5 compactPressureThreshold: 0.5 llmSummaryEnabled: false llmSummaryMaxInputTokens: 16000 replaceBasicCompaction: false includeToolNames: [] excludeToolNames: ['interaction.ask_user', 'interaction.confirm'] cacheStableSections: ['agent-identity', 'user-instructions', 'tool-list'] telemetry: onFold: | (event) => logger.info({ kind: 'fold', ...event }) onCompact: | (event) => metrics.histogram('tokens.saved', event.savedTokens, ['engine', event.engine])

字段说明

字段类型默认含义
mode'off' | 'conservative' | 'balanced' | 'aggressive''conservative'模式选择器
preserveStructurebooleantrue截断时按行边界切,避免在行中间断
headBytesnumber16384工具结果保留的头字节数
tailBytesnumber8192工具结果保留的尾字节数
grepMaxMatchesnumber30grep 匹配最大保留条数(带上下文)
grepContextLinesnumber2每条匹配保留的上下文行数
grepHeadBytes / grepTailBytesnumber8192 / 4096grep 折叠后的最终头/尾预算
pressureThresholdnumber (0..1)0.5pre-step 副作用生效的压力比
compactPressureThresholdnumber (0..1)0.5触发 ctx.compaction.compactIfNeeded 的压力比(balanced+ 生效)
llmSummaryEnabledbooleanfalse启用 LLM-summary engine(balanced/aggressive)
llmSummaryPromptstring内置自定义摘要 prompt
llmSummaryMaxInputTokensnumber16000单次摘要调用的输入 token 上限
replaceBasicCompactionbooleanfalse替换 dsh-compaction-basic(仅 aggressive 推荐)
includeToolNamesstring[][]白名单(空 = 所有工具)
excludeToolNamesstring[][]黑名单(优先级高于 include)
cacheStableSectionsstring[][]需要钉住的稳定段 id,用于 prompt-cache 命中率
telemetry.onFoldfunctionundefined每次 fold 后触发的同步钩子
telemetry.onCompactfunctionundefined每次 compaction 后触发的同步钩子

测试效果

基准方法

测试集见 benchmark/fixtures/index.ts,覆盖以下 8 个真实场景:

场景模拟内容原始 tokens
big-read-2k-lines读 2 千行生成的 TS 代码58,223
huge-read-migration读一份 60k 行的 SQL 迁移1,562,272
grep-match-heavygrep 80 个匹配带上下文44,924
grep-sparsegrep 8 个稀疏匹配43,574
stack-trace-15001500 帧的栈追踪17,917
json-dump-800800 条嵌套 JSON dump31,225
code-search-TODO在 5k 行里搜索 TODO|FIXME|XXX53,064
mixed-session-12-tools一个 12 步混合工具会话2,016,552
合计3,827,751

Token 估算遵循业内常用的 4 chars/token 规则(surrogate-pair aware);绝对值因模型分词器而异,但 ratio 在普通拉丁/CJK 文本上稳定。

对比结果

场景原 tokensconservativebalancedconservative 节省balanced 节省
big-read-2k-lines58,2236,1693,09489.4%94.7%
huge-read-migration1,562,2726,1743,09599.6%99.8%
grep-match-heavy44,9242,5072,50794.4%94.4%
grep-sparse43,5743,1023,10292.9%92.9%
stack-trace-150017,9176,1673,09165.6%82.7%
json-dump-80031,2256,1153,05080.4%90.2%
code-search-TODO53,0643,1013,10194.2%94.2%
mixed-session-12-tools2,016,55257,39435,88397.2%98.2%
合计3,827,75190,72956,92397.6%98.5%

读出来再现一遍:

▼
text
复制代码
$ pnpm run bench:compare 分场景 token 对比(离线估算:4 chars/token,surrogate-pair aware) 所有场景使用合成的工具结果。插件以默认设置运行。 +----------------------------+--------------+--------------+--------------+--------------+--------------+ | scenario | original | conservative | balanced | cons. saved | bal. saved | +----------------------------+--------------+--------------+--------------+--------------+--------------+ | big-read-2k-lines | 58223 | 6169 | 3094 | 89.4% | 94.7% | | huge-read-migration | 1562272 | 6174 | 3095 | 99.6% | 99.8% | | grep-match-heavy | 44924 | 2507 | 2507 | 94.4% | 94.4% | | grep-sparse | 43574 | 3102 | 3102 | 92.9% | 92.9% | | stack-trace-1500 | 17917 | 6167 | 3091 | 65.6% | 82.7% | | json-dump-800 | 31225 | 6115 | 3050 | 80.4% | 90.2% | | code-search-TODO | 53064 | 3101 | 3101 | 94.2% | 94.2% | | mixed-session-12-tools | 2016552 | 57394 | 35883 | 97.2% | 98.2% | +----------------------------+--------------+--------------+--------------+--------------+--------------+ 合计:original=3827751 conservative=90729 balanced=56923 节省 (conservative):3737022 tokens (97.6%) 节省 (balanced): 3770828 tokens (98.5%) 说明: - 估算规则与模型侧 token 计数器一致;绝对数值因分词器差异可能不同,但 ratio 在常见拉丁/CJK 文本上稳定。 - "conservative" 匹配插件默认:16KB 头 + 8KB 尾,grep 折叠为前 30 个匹配 + 2 行上下文。 对 session log 里的 model-visible 流无损失。 - "balanced" 把 budget 收紧到 8KB 头 + 4KB 尾。仍无损失;折叠更多。

关键观察

  1. 栈追踪(stack-trace-1500)节省率最低 65.6%:因为栈帧本身已经是紧凑的"一行一帧"结构,没有冗余信息可以扔掉,反而头/尾 24KB 的固定 budget 占满了原始的 18KB 之后只省出一小段。
  2. 混合会话(mixed-session-12-tools)节省率最高 97.2%:因为它包含多个大工具结果,会被叠加压缩;同样输入下,保存下来的 inline 工具结果只剩 5.7%。
  3. balanced 与 conservative 差距 0.9 个百分点(98.5% vs 97.6%):差距是 conservative 的 16k/8k → balanced 的 8k/4k 砍头砍尾更狠;在 grep-matched 场景两者持平,因为 grep 折叠后的内容已经远小于头尾 budget。
  4. 无损性:conservative 和 balanced 都改的是 tool/result.content —— 通过 tools/post-execute waterfall 走的就是 dsh 标准的 tool result 事件流,session log 里完整保留被替换前的原 content(通过 surfaceOp 替换标记),可回放可重建,对模型的推理依赖关系不变。

跑你的机器上的真实对比

  1. pnpm run bench:compare —— 跑 8 个合成场景的离线估算,无需 API key。

  2. pnpm exec vitest run test/bench —— 跑永久回归基线(11 个 assertion,每个场景至少节省 X%)。

  3. 接入 dsh 后的真实对比:详见根目录 BENCHMARK.md ,里面给出了一份两份 DSH home + 8 个任务 + 自动 parse + 验收表的可复现模板。一键命令:

    ▼
    bash
    复制代码
    # 1) 准备两个 profile home(one-shot) pnpm run smoke # 先验 mock 链路 pnpm run build # emit 插件产物 # 2) 在真实 dsh 上跑两个 profile × 8 任务 # 需要 DEEPSEEK_API_KEY export DEEPSEEK_API_KEY=sk-... pnpm exec tsx benchmark/run-real-bench.ts \ --dsh-home-baseline ~/.dsh-bench-baseline \ --dsh-home-plugin ~/.dsh-bench-with-plugin \ --tasks benchmark/tasks.json \ --out ./runs # 3) 把两次跑的 session metrics 拼成 markdown 对比表 pnpm exec tsx benchmark/parse-results.ts \ --baseline ./runs/sessions-baseline \ --plugin ./runs/sessions-with-plugin \ --text-dir ./runs \ --output bench-results.md

    bench-results.md 直接给出每任务的输入/输出 tokens、节省率、输出比对、时长变化,以及验收 checklist。


如何保证不影响任务效果

dsh-token-saver 的所有削减都遵循 dsh 的两条硬性约束:

  • "Model-visible means logged." 任何送进模型的输入都必须能从 session log 重建出来。
    • 我们的削减全部走事件:要么通过 tools/post-execute 返回新的 accept 决策(dsh 自动落 tool/result),要么通过 agent/pre-step 委托给 ctx.compaction(官方 compaction/* 事件记录了替换区间)。我们从不在 plugin 内部直接 mutate session,因此 deriveMessages() 仍然能在任何节点重新投射一致的模型可见流。
  • "Waterfall listeners must call next()."
    • 我们的每个 listener 都先 await next() 拿到上游决策,再在此基础上修改 messages 或 content;从不短路 dsh 的默认链路。

附加安全保障:

风险点缓解措施
错误结果被截断丢掉诊断信息decidePostTool 里 payload.result.isError === true 时直接 passthrough,永不裁剪错误结果
极小工具结果被过度折叠budget = headBytes + tailBytes + 256,超过这个 budget 才会折叠
关键工具(如 ask_user、confirm)被裁剪excludeToolNames 默认建议保留交互类工具
replaceBasicCompaction 误开仅 aggressive 模式默认 true;开就是显式接管,warn log 提示
LLM-summary 调用失败我们的 LlmSummaryCompactionEngine.compactIfNeeded 失败会 catch 并 fallback 到官方基础实现,warn log 提示

开发

要求:

  • Node.js >= 22.19
  • pnpm >= 10(仓库用 pnpm@11.7.0,我们是独立 monorepo 但 root range 提到 10)
▼
bash
复制代码
pnpm install pnpm run typecheck # tsc --noEmit pnpm run lint # oxlint src test pnpm run test # vitest run — 51 测试 pnpm run build # tsc emit 到 lib/ pnpm run bench:compare # 合成场景 token 对比输出 ASCII 表

tsconfig.json 跑 typecheck 走 noEmit: true + allowImportingTsExtensions: true;tsconfig.build.json 覆盖 noEmit: false + 关闭 .ts 扩展名导入,用于 emit 到 lib/。


架构

▼
text
复制代码
src/ lib/ truncate.ts # 字节预算头尾截断,按行边界切 fold-grep.ts # 匹配保留型 grep 折叠 strategies/ tool-result-trim.ts # tools/post-execute: 按工具名路由、content 改写 context-pressure.ts # agent/pre-step: 查 tokenMeter、调 ctx.compaction llm-summary.ts # CompactionEngine 子类(replaceBasicCompaction=true 时启用) prompt-cache.ts # systemPrompt 段重排 utility,稳顺序提 cache 命中 config.ts # ResolvedConfig + schema 元数据 types.ts # 最小 dsh 形状类型(不硬依赖内部包) internal.ts # 跨策略 import 桶 index.ts # Cordis 插件:name / Config / inject / apply test/ # vitest,含 test/bench/compare.test.ts(11 cases) benchmark/ # 离线基准 + 真实 e2e 入口 fixtures/index.ts # 8 个合成场景 compare/index.ts # 估算 + simulate 函数 + CompareRow compare-run.ts # tsx 直接跑、输出 ASCII 表格 run.ts # 真实 dsh 子进程接入(需 DEEPSEEK_API_KEY)

设计原则:

  1. 不替换 dsh 默认行为,除非显式 mode: 'aggressive' + replaceBasicCompaction: true。
  2. 所有 fold 都走 dsh 的事件,不进私有字段 → 重放/快照不变。
  3. 不硬依赖 dsh 私有 —— @deepseek-ai/cordis、@deepseek-ai/schemastery、@deepseek-ai/dsh-compaction 都是 peerDependencies(可 optional),编译期类型用 import type,运行时通过动态 trait 适配。

License

MIT

用量计费

快捷安装

复制到终端去安装插件

dshplugin--profilewebaddgithub:Shaw529/dsh-token-saver

温馨提示

装插件等于在本机跑第三方代码,权限与你相同,能读文件、用凭据、访问网络,工具审批管不到。请只装可信来源,并尽量锁定 commit。

站长:程序员鱼皮 老鱼简历 商务合作 增值电信业务经营许可证
2026 鱼皮AI导航 | 沪ICP备19026706号-6
站长:程序员鱼皮 老鱼简历 商务合作 增值电信业务经营许可证
2026 鱼皮AI导航 | 沪ICP备19026706号-6
dsh 插件推荐
dsh-token-plan-quota
跟随当前模型供应商的额度徽标:DeepSeek、千问 Token Plan、阿里云费用中心取官方真值,Moonshot / OpenRouter 已接官方端点但字段未用真 Key 核对;其余只报本实例实测。
dsh-commandcode-usage
DSH 的 CommandCode 用量与余额面板:在侧边栏底部显示 API 用量、信用额度、5小时/每周窗口。
dsh-usage-stats
在侧边栏按模型、会话与日期统计 token 用量,并监控 OpenCode Go 额度、DeepSeek 余额与 Z.ai 额度。
dsh-usage-dashboard
DSH 用量分析坞:输入框峰谷计费坞(周末全天谷时)、实时余额、跨会话历史、按日期下钻与图表。
dsh-smart-scenario-router
根据对话场景选择模型,并在请求失败时按候选链进行回退。
🔥热门工具
朱雀AI检测朱雀AI检测
朱雀AI检测助手朱雀AI检测助手
LovartLovart
老鱼简历老鱼简历
WritePass官网WritePass官网
面多多面多多
CursorCursor
星月写作星月写作
零感AI零感AI
墨得问题墨得问题