Back to home@JxaMe

dsh-condense

Token optimizer for DeepSeek Harness — condense your context, keep the essence. 为 DSH 的 agent 上下文减负并汇报每一分节省。

Stars
0
Language
TypeScript
Created
Aug 19, 2026
Updated
Aug 20, 2026

Introduction

dsh-condense mascot

✂️ dsh-condense

浓缩上下文,留住精华。 Condense your context. Keep the essence.

面向 DeepSeek Harness 的 token 优化插件 — 自动削减 agent 循环中的低价值内容,同时 保持 prompt 缓存命中

License: MIT Version Verified: DSH 0.1.0-rc.8 npm

中文 · English


🧐 为什么需要它

LLM 编程 agent 在很少有帮助的内容上烧 token:

浪费场景说明
📚 整文件读取node_modules、lock 文件、vendor 代码灌满上下文
🐘 超大输出工具输出在整个会话期间留在历史里
🔁 重复读取同一文件被连续读两遍
🎯 盲目检索候选 20 个文件时只读 5 个就够
📝 啰嗦回复一句话能说清时模型写一大段

dsh-condense 在每一个点上动手。


💡 核心考量:省 token,同时不破坏缓存命中

💰 API 侧的 prompt 缓存按 前缀匹配 计费:命中部分大幅折扣(约全价的 1/10),未命中的新增内容才是全价。

两种"省 token"的思路,结果截然不同:

思路缓存影响结论
事后削减(摘掉/重写已进历史的内容)历史前缀一变,后续请求从变化点起全部 cache miss省下的 token 被全价重算抵消,可能比不省更贵
入历史前削减(本插件的做法)历史从创建起就是浓缩形态,前缀 字节级稳定缓存命中率不受影响
模型请求 ──► 内容还没进历史 ──► dsh-condense 削减 ──► 浓缩版进历史 ──► 前缀稳定

🎯 省的是 未命中的全价 token(每次新增的大块输出),保留的是 已命中的折扣 token —— 这正是经济收益最大的位置。


⚙️ 功能一览

能力机制时机
🚫 屏蔽低信号读取tools/pre-execute 拒绝读取 node_modules/.git/dist/、lock 文件、.min.js自动
🧭 readsmart_read 引导模型全量 read 源码文件时拒绝并提示改用骨架读取;局部读不受影响(Config smartReadRedirect,默认开)自动
🗜️ 压缩超大输出tools/post-execute 对 >8 KB 输出做头尾截断自动
♻️ 重复调用去重相同调用且 输出哈希一致 即返回占位符(无时间窗口,输出一变就返回新内容,绝不误导)。覆盖只读工具 + bash自动
🤫 conciseness 指令系统提示注入"直接回答、不说废话"自动
🧠 smart_readtree-sitter 语法级骨架提取 — TS/JS/TSX/JSX/Python/Rust/Go按需
🔍 trim_contextBM25 候选文件排序(支持 中英文按需
📊 condense_stats统一节省量统计 + 真实用量计量 + 持久化按需

📈 实测效果

所有数字均来自真实运行(详见 EXPERIMENTS.md);token 估算口径 ≈4 字符/token,诚实标注。

实验结果
🧠 smart_read 单文件节省实现文件 45–74%;纯类型声明(.d.ts)≈0%(骨架≈原文)
🔗 trim_contextsmart_read 链路4 组查询 整体 91%,相关文件全部命中
🗜️ 输出压缩超大输出保留头尾 8 KB,削减率 77–82%
🚫 屏蔽低信号读取目标文件完全不进上下文(100%
💾 prompt 缓存影响 — 所有削减发生在内容进历史之前,前缀保持稳定

🏗️ 工作原理

                 ┌────────────────────────────────────────────────┐
                 │                 dsh-condense                    │
                 │                                                │
  model ────────►│  tools/pre-execute   ──► 屏蔽低信号读取         │
                 │        │                                       │
                 │  tool 执行            (或按需 smart_read /     │
                 │        │               trim_context)          │
                 │        ▼                                       │
                 │  tools/post-execute  ──► 压缩 + 去重            │
                 │        │                                       │
                 │  会话历史(已浓缩)── 前缀稳定,缓存命中不损      │
                 │        │                                       │
                 │  系统提示 section ──► conciseness 指令          │
                 └────────────────────────────────────────────────┘

两个组成部分,都是纯插件(零 DSH 源码改动):

  • 🧩 主插件(标准 Cordis 插件,dsh plugin add 一键安装):事件钩子(tools/pre-executetools/post-executesession/event 真实计量)、按需工具、统计持久化。
  • 🚀 宿主插件host-plugin/):运行在完整 Node 环境,因此能加载 tree-sitter WASM 语法 — 这是语法级符号提取的基础。

宿主插件通过 ctx.loader.create() 引导加载,随主插件自动启动,无需额外配置。


🚀 安装

✅ 已验证 DSH 0.1.0-rc.8(peer 范围:>=0.1.0-rc.7)。

# 从 npm(推荐,可版本化更新)
dsh plugin add @jxame/dsh-condense

# 或从 GitHub
dsh plugin add github:JxaMe/dsh-condense

安装即完成:包自带 bundle patch(dsh.bundle 声明),dsh plugin add 自动注册为 profile 层,无需手动编辑任何配置。重启 DSH 后宿主插件随启动加载,钩子和工具立即生效。

🔄 更新到新版本:dsh plugin remove @jxame/dsh-condense && dsh plugin add @jxame/dsh-condense。 🛠️ 开发期改代码可用本地路径 dsh plugin add /path/to/dsh-condense(symlink 跟随本地目录,npm run build 后重启即生效)。

📍 放置位置

dsh plugin add 默认装入 host 组成(全会话生效)。如需限定单个会话,把插件行放进对应 agent presetplugins: 列表:

位置生效范围
🏠 host 组成(默认)所有会话,全 harness 共享一份统计
🎯 agent preset单个会话,每会话独立统计

统计(condense_stats)与削减记录持久化在 ~/.dsh/plugins/dsh-condense/stats.json(Windows: %USERPROFILE%\.dsh\plugins\dsh-condense\stats.json),重启不丢。


🛠️ 工具

工具说明
🧠 smart_read源码文件的符号骨架(tree-sitter,TS/JS/Python/Rust/Go)。探索结构时优先于 read
🔍 trim_context对候选文件路径按 BM25 与查询排序,返回 top-N 及分数。支持中英文。
📊 condense_stats查询会话的 token 节省量(按机制细分)+ 真实用量(provider 实测,session/event 持久化事件)+ 持久化位置。

⚠️ 已知限制

  • 🧠 smart_read 对 Python/Rust 的类/结构体成员:方法签名化、字段保留(与 TS/JS 一致);Go 结构体保留字段。
  • 🇨🇳 单字符中文查询无结果(bigram 分词器至少需要 2 个字符)。
  • 🔄 宿主插件代码更新需重启 DSH 生效(模块缓存)。
  • 🚫 DSH 的 pre-execute 按设计禁止改写工具参数,因此无法做 quiet-flag 式命令改写;屏蔽读取是等价的替代防护。
  • 🖥️ 实时 UI 统计面板未提供:统计的 数据层已完全固化condense_stats 工具 + stats.json 持久化 + condenseStats 服务,重启不丢);浏览器端展示层需要 DSH 官方 client 插件构建工具(__ModuleLoader__ bundle 格式),当前版本未随发行提供,故未提供面板。统计经 condense_stats 工具查询。

🏛️ 架构说明

  • 🔌 用到的钩子tools/pre-execute(deny)、tools/post-execute(替换 content)、session/event(真实用量计量,官方推荐事件溯源方式)、systemPrompt.section()(conciseness + smart_read 引导)、ctx.loader.create()(宿主插件引导)。
  • 🧩 为什么是两个插件:标准插件环境无法加载 WASM/import npm 包;宿主插件运行在完整 Node 运行时。这个拆分正是 tree-sitter 可行的原因。
  • 🚫 陈旧输出截断有意不重复实现 — DSH 原生自带 toolResultPruner
  • 🚫 不做请求前历史裁剪:把已写进历史的内容摘掉会破坏缓存前缀(省下的 token 被全价重算抵消)。本插件只削减"将进入"的内容,不碰"已在"的历史 — 这是 DSH 缓存计费模型下的最优策略。

🧑‍💻 开发

# 边界测试:正则提取器在 dsh-src(87 个真实文件)上的翻车率
node bench-edge.js

# 组合链路测试:trim_context → smart_read 的 token 节省
node bench-combo.js

# 本地验证 tree-sitter 提取器(无需 DSH)
node --input-type=module -e "import { extractSymbols } from './host-plugin/dist/index.js'; console.log(await extractSymbols('def f(x): return x', '/tmp/a.py'))"

# 单元测试
npm test

实验数据、方法学与发布素材见 EXPERIMENTS.md


📜 许可证

MIT — 详见 LICENSE

🙏 致谢

ctxlite(MIT + Commons Clause)启发 — 同类问题,不同架构(DSH 原生插件 vs 外部工具)。BM25 参数与符号提取策略遵循其公开设计;实现为原创。署名义务见 LICENSE 声明。