🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

输出瘦身器 boxiaolanya2008/tokensqueezer

DeepSeek Harness
boxiaolanya200832 天前有提交已提供中文文档扫描:含敏感能力

压缩模型自身输出,降低每轮对话的 token 开销

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

该插件未发布到 npm,按作者文档从 GitHub 源安装即可(静态检查只覆盖 npm 路径,不代表插件不可用)。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add boxiaolanya2008/tokensqueezer
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · model
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 32 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包@local/tokensqueezer(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/8 09:41:51

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 10 处,展示前 10 条)
  • 读取本地文件
    index.js:434
    this.loadedCode = file + ' @ ' + statSync(file).mtime.toISOString();
  • 发起网络请求
    client.js:332
    const response = await fetch(url, { headers: { accept: 'application/json' } });
  • 发起网络请求
    client.js:692
    void fetch('api/tokensqueezer/status?diag=' + encodeURIComponent(diag), {
  • 写入剪贴板
    client.js:895
    ? writeClipboard(draftRow)
  • 写入剪贴板
    client.js:896
    : navigator.clipboard?.writeText(draftRow);
  • 读取本地文件
    lib/arch.js:103
    rootStat = statSync(cwd);
  • 读取本地文件
    lib/arch.js:178
    entries = readdirSync(current, { withFileTypes: true });
  • 读取本地文件
    lib/arch.js:228
    entries = readdirSync(node.dir, { withFileTypes: true });
  • 读取本地文件
    lib/arch.js:364
    statSync(join(cwd, file));
  • 读取本地文件
    lib/arch.js:385
    const raw = readFileSync(join(cwd, 'package.json'), 'utf8');
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 限制生成量
  • 压缩冗长回答与推理
  • 保持代码字节级一致

削减DSH代理自身输出的令牌用量:在调用前限制生成量,在调用后压缩冗长回答与推理内容,并保持代码字节级一致。

README

由 DeepSeek 最新模型翻译生成
TokenSqueezer 一个 DeepSeek Harness 插件,用来降低 agent 的运行成本。它作用于模型自己产出的内容,而不是喂给它的输入。 先读这一节:到底什么在省 token 这个插件里住着两套经济性完全不同的机制,把它们混为一谈是失望的最快来源。 | | 机制 | 省的是 | 为什么 | | 掐住生成 | brevityInstruction | 输出 | 模型自己少写,答案仍然完整 | | | reasoningBrevityInstruction | 输出 | 思考占模型全部产出的 ~87%,让它"走直线"是这里最大的杠杆 | | | outputTokenCap | 输出 | 调用之前经 agent/request 设下天花板。没生成的 token 不会计费 | | | reasoningEffort | 输出 | 钉住思考档位。只在模型广告了该档位时才应用 | | 压缩 | llm/stream 改写 | 只省重放 | chunk 到手时,那些 token 已经生成、已经付费 | | | session/event 兜底 | 只省重放 | 同上 | | | answer / reasoning / 各类折叠 | 只省重放 | 同上 | 压缩不能让当前这次回答变便宜 —— 那笔钱已经花掉了。
展开完整文档(README 剩余 1 节)
TokenSqueezer

一个 DeepSeek Harness 插件,用来降低 agent 的运行成本。它作用于模型自己产出的内容,而不是喂给它的输入。

先读这一节:到底什么在省 token

这个插件里住着两套经济性完全不同的机制,把它们混为一谈是失望的最快来源。

| | 机制 | 省的是 | 为什么 |
| 掐住生成 | brevityInstruction | 输出 | 模型自己少写,答案仍然完整 |
| | reasoningBrevityInstruction | 输出 | 思考占模型全部产出的 ~87%,让它"走直线"是这里最大的杠杆 |
| | outputTokenCap | 输出 | 调用之前经 agent/request 设下天花板。没生成的 token 不会计费 |
| | reasoningEffort | 输出 | 钉住思考档位。只在模型广告了该档位时才应用 |
| 压缩 | llm/stream 改写 | 只省重放 | chunk 到手时,那些 token 已经生成、已经付费 |
| | session/event 兜底 | 只省重放 | 同上 |
| | answer / reasoning / 各类折叠 | 只省重放 | 同上 |

压缩不能让当前这次回答变便宜 —— 那笔钱已经花掉了。它做的是把上下文压短,让这个回合里此后每一次请求少带一些字节。这种节省会复利,但在发生的那一刻你几乎看不见。

插件从不改动 usage,所以上报的 token 数字始终是真实的。

安装

1. 把仓库放到一个固定位置,再以 link: 方式装进 profile (profile 自己管理 node_modules;link: 安装让插件保持可编辑) cd
pnpm add link:

2. 启用。bundle 自带 cordis.patch.yml,会自动插入那一行。
在 \profiles\\cordis.patch.yml:
- id: tokensqueezer
disabled: false

必须重启应用。 两个半边的重载机制不同,这个不对称值得先知道,否则会白白耗掉一个下午:

| | 加载方式 | 运行中改它 |
| Host 半边(index.js、lib/) | loader entry,应用启动时读一次 | 完全无效,必须完整重启 |
| Client 半边(client.js) | 模块产物的 revision 由 mtimeMs/ctimeMs/size 推导 | 立即热重载 |

所以"界面更新了但行为没变"是 Host 陈旧的典型症状。status 会打印 Host 实际加载的那个文件,于是这个问题从猜测变成一次比较:

Host code: \index.js @ 2026-09-30T04:26:12.732Z.

工作原理

Host 半边 —— 五个表面,各自独立安装

| 表面 | 挂钩 | 作用 |
| 流改写 | llm/stream(waterfall) | 把每个 text/reasoning 块缓冲到 block-end,压缩后重新发出。这是唯一在显示之前生效的一条腿;由于 loop 是用它收到的 chunk 构造 assistant/message 的,它也决定了落库的内容 |
| 落库兜底 | session/event | 用可重放的 compaction/prune + surfaceOp: replace 协议,替换掉那些从别的路径进了日志的超预算 assistant/message。正常路径上是 no-op |
| 输出预算 | agent/request(waterfall) | "掐住生成"那一半:在 prepareCall 之前设 maxTokens、按需钉住 reasoningEffort |
| 工具结果 | tools/post-execute(waterfall) | 在模型读到之前压缩工具结果 —— 受下面的代码保证约束 |
| 状态路由 | webServer.register | 一条只读的 GET /api/tokensqueezer/status,让界面能显示一个数字。只答 GET,其余一律 405。payload 只有插件自己的计数:无会话内容、无路径、无凭据 |

每一个都是独立的安装步骤,所以某个失败会在 status 的 Installed: … 里报出自己的名字,而不会把另外四个一起带走。

Client 半边 —— 两个座位

- conversation.composer.dock —— 输入框下方的读数。每 3 秒轮询一次状态路由并显示本会话的节省量。
拿不到数字时它如实说明,而不是显示一个占位符。
- settings.section —— 设置页,用官方 primitives 搭成(Tag、Switch、SegmentedControl、 Input、CodeBlock、Button),按"每一项到底省什么"分组,并通过官方 locale 服务本地化。

管线

lib/engine/output.js 先把载荷切成"围栏代码段"和"散文段",所以没有任何代码块会进入语义层。
其余内容依次经过:

1. L1 无损 —— ANSI 与控制字符、\r 重绘、行尾空白、空行折叠、重复行/块折叠
2. L2 归一化 —— 按会话 cwd 做路径相对化、可选的符号驻留。两者对可执行种类都跳过
3. L3 语义 —— 每种检出类型一个压缩器:json、yaml、diff、stacktrace、log、 terminal、testreport、filetree、searchresults、deptree、markdown、html、code、 prose,另有在回答尺度上折叠的 answer 与 reasoning

可逆性

有损层删掉的一切都会按内容哈希(8 位 sha1)存入引用库,并替换成一枚裸标记 ⟦TS:id⟧,载荷末尾附一行图例。同一段文本永远得到同一个 id,所以对已压缩内容再压一次是 no-op。模型通过 tokensqueezer 工具的 expand 动作取回原文。

代码保证

结果是文件内容或补丁的工具,不做语义压缩。 这条约束在三个地方落实,而有三个地方的原因值得记下来:

第一版实现调用的是 engine.compress(text, { lossy: false }),以为这样就够了。用一段 40 行的重复代码实测,它返回了三行。会伤代码的重复行折叠跑在无损阶段,所以"关掉有损层"发生在伤害的下游。

因此:

1. 由工具名决定类型。 toolContentKind() 把 read/read_file/view/cat/write/edit/ str_replace 钉成 code,把 diff/patch 钉成 diff。这里用启发式是错的工具:一个被 detectKind 恰好读成 log 的源码文件,会被折掉重复行。
2. 这些种类根本不进管线,只走 losslessCleanup。EXECUTABLE_KINDS 不是这道防线 —— 它只保护 L2,而 compressCode/compressDiff 照样会折代码体。
3. 最终文本必须更短。 如果连同标记和图例都不比原文短,整条改动被原样丢弃。这正是"统一压缩" 之所以安全而不是自伤的原因:一枚 13 字符的标记加上约 100 字符的图例,否则会把小载荷撑大。

在出货的引擎上实测:

read_file,40 行重复代码 1079 → 1079 40/40 行存活 patch,30 条新增行 1231 → 1231 30/30 行存活含 ANSI 与空行的代码 1122 → 1111 41/41 行存活,转义已剥离

配置

每一项都有默认值,什么都不配也能跑。各门槛默认为 0,所以普通载荷总会进入压缩器 —— 是否保留结果由上面那条"必须更短"的规则决定。

| 键 | 默认 | 含义 |
| compressOutput | true | 输出压缩总开关 |
| compressStreamOutput | true | llm/stream 那条腿(唯一在显示前生效的) |
| compressDurableOutput | true | session/event 落库兜底 |
| compressReasoning | true | 折叠思考块。设 false 会在任何压缩器之前短路 |
| compressToolResults | true | 压缩工具结果,受代码保证约束 |
| outputMinChars | 0 | 可见 text 块的门槛 |
| reasoningMinChars | 0 | 思考块的门槛 |
| toolMinChars | 0 | 工具结果的门槛 |
| minSavedChars | 0 | "值不值"门槛。因为有"必须更短"那条规则,0 是安全的 |
| segmentMinChars | 200 | 回答被代码切分后,单个散文段的门槛 |
| reasoningElideMinChars | 0 | 压缩器内部的思考门槛 |
| reasoningFoldMinChars | 0 | 压缩器内部的思考折叠门槛 |
| answerElideMinChars | 0 | 压缩器内部的回答门槛 |
| answerFoldFloor | 0 | 压缩器内部的回答折叠门槛 |
| outputTokenCap | 未设 | 生成 token 的硬上限。设太低会截断答案(finish: max-tokens)。永远不会把已有的更严上限放宽 |
| reasoningEffort | 未设 | 强制思考档位。属质量取舍;只在模型广告了该值时应用 |
| brevityInstruction | true | 要求回答简洁。这是插件对文风做的唯一改动 |
| reasoningBrevityInstruction | true | 要求思考简洁 |
| level | 1 | 0 只无损,1 常规,2 激进 |
| relativizePaths | true | 相对化重复的绝对路径。不作用于代码与 diff |
| internSymbols | false | 驻留长重复标识符。不作用于代码与 diff |
| protectCodeFences | true | 让围栏代码留在语义层之外 |
| toolSkip | [] | 按工具名跳过(这些工具的结果永不压缩) |
| archMaxChars / archMaxDepth | 1200 / 3 | 架构摘要的预算与深度 |

outputTokenCap 与 reasoningEffort 作用于每一个 agent(包括 subagent)—— 这是刻意的,免得一次委派悄悄超出给它的预算。

工具

插件自带验证 —— 因为出问题的从来不是引擎那一层:

$node = ''
& $node scripts\linkcheck.mjs # 每个相对 import 都解析到真实导出 & $node scripts\selftest.mjs # 引擎 9 类样本:122537 → 32812 字符(73.2%) & $node scripts\hosttest.mjs # Host 半边,假 ctx + 和真 session 一样严的假 session & $node scripts\clienttest.mjs # Client 半边,假 loader、真渲染,以及设置表单所依赖的 schema & $node scripts\reasontest.mjs # 骨架折叠:骨架保留、引用可逆 & $node scripts\zstdtest.mjs # 会话日志读取器:拼接帧与截断的尾帧 & $node scripts\archtest.mjs # 架构摘要

另有三个诊断脚本,专门回答界面回答不了的问题:

| 脚本 | 回答什么 |
| scripts/audit.mjs | 插件真的改写已提交的输出了吗?它直接读持久会话日志,逐会话数有多少条 assistant/message 带标记 —— 并把回答与思考分开统计。界面是二手视图,这个才是日志 |
| scripts/sessionrepair.mjs | 哪些行会被 v4 准入拒绝,并提供修复其中两种形状的能力。默认只预览,--write 才落盘且先备份。它的第二条规则只在 v4 日志生效,所以不会去动别的项目里的 v3 会话 |
| scripts/asar-find.mjs · asar-extract.mjs | 出货的 Harness 到底怎么做的。两者只读应用归档的头部再提取指定条目 —— 下面那些契约就是这么读出来而不是猜出来的 |

hosttest.mjs 用的假 session 会强制真规则 —— assistant/message 的替换不得带 sourceEventSeqs、必须带 turn/step 且该 step 仍开着、surfaceOp 必须恰好是 {op, startSeq, endSeq}。

平台约束

下面每一条都是撞出来的,而且每条至少花掉一次重启。它们是 Harness 的性质,不是这个插件的问题。

- 装在 profile 里的 bundle 不能 import @deepseek-ai/。 那些包躺在应用归档里,Node 的解析永远走不到,整个 entry 只报一句 failed to import。所以 Host 半边是函数式插件、不 import 任何框架代码,需要的一点点帮助函数就地内联。

- cordis 只在上下文 inject 了某服务时才让它可解析。 未声明的服务不只是"取不到"——以属性方式读它会抛异常。这个抛异常在本插件里静默地干掉过一整个安装步骤。inject 是一道门,两个半边
都声明了自己需要的(['tools', 'webServer'] 与 ['slots', 'locale', 'configForms'])。

- 插件的 Config 是两套协议。 cordis 的激活走 Standard Schema
(Config['~standard'].validate,必须同步);DSH 的设置投影要 schemastery 商标
(Symbol.for('schemastery')、type、meta)。只满足后者时,inspect provider 会报一个健康的
status: "schema",而 entry 实际是 fiberPhase: "failed"。inspect provider 是只读投影,不是验证器。*

- 要让投影出现在客户端,key 必须编译期声明合并进 SessionProjectionMap,并提供 wire 编解码器;自建 typert Remote 命名空间则需要代码生成。两者纯 JS 插件都拿不到 —— 所以界面改读一条只读 HTTP 路由。

- SessionReference 描述的是行为,不是内容 API。 它有分页、最小条数与生命周期语义,但没有读取已加载消息的公开方法。

- agent/request、llm/stream、tools/post-execute 都是 waterfall,可以合法地替换自己的返回值。而 agent/assistant-stream 是 emit,永远只能观察、改不了。

诚实的局限

- 短内容压不动,而且本就不该压。 门槛全为 0 之后压缩器照样会被调用,它只是找不到可删的东西。
一段 46 字符的回答没有可折的中段,一个 11 字符的工具结果没有冗余。再往下压就不是节省,而是删信息。
- 真实会话上的实测节省是"有限"的 —— 够格的块里省个位数到十几个百分点,而大约一半的块根本没有冗余。
大数字在"掐住生成"那几个旋钮里,其中两个(outputTokenCap、reasoningEffort)默认关闭,因为它们会改变模型产出。
- 设置页的写入路径是按契约验证的,不是靠浏览器点出来的。 控件调用的是设置服务的
mutate(ops, revision) —— 从出货的 SettingsFormModel 里读来的,不是猜的。一个手搓的 schema 要能被
服务,得同时过两道闸,lib/config.js 现在两道都过了:这个 entry 的 Config 必须能应答 "toJSON" in schema,并且至少有一个字段带 meta.volatile。缺第一道,describe() 在读到任何别的东西
之前就把这一行丢掉;缺第二道,volatileForm() 在下一步把它丢掉。两种情况下都不会出现命名空间,
configForms.get() 什么都找不到,于是每一个开关和数字输入框都渲染成禁用(灰的)。clienttest.mjs
把两道闸都钉住了,所以这个页面不会再悄悄变灰。仍未被真实浏览器走通的是最后一步:改一个值,看到 Saved,确认 Host 应用了它。

- toolSkip 不能在设置页里编辑。 它是唯一一个非标量设置,而一个 rehydrate 失败的数组节点会把整个页面打回 status: loading —— 所有控件一起变灰,正是上面那个故障。它仍可通过 tokensqueezer 工具的
set 动作和 profile patch 行来改。
- dock 读数依赖状态路由。 路由不可达时它会明说,绝不显示一个它没有的数字。
- 引用库按会话隔离且有上限。 expand 只能解析产生该标记的那个会话;LRU 保持 32 个会话常驻。
原文始终留在持久日志里。

目录结构

index.js Host 半边:五个表面、工具、提示词段、状态路由 client.js Client 半边:输入框读数与设置页 cordis.patch.yml bundle 补丁:插入 tokensqueezer 行 package.json bundle 与客户端声明 lib/config.js 插件 Config(Standard Schema + schemastery 商标) lib/session-message.js 仍在依赖的 v4 producer-source 规则 lib/arch.js 架构摘要 lib/engine/ compress.js 编排器 output.js 围栏切分、代码保护、回答尺度接线 detect.js 内容类型识别 textsafe.js L1 无损 refs.js 内容寻址引用库 dedupe.js 行/块折叠 normalize.js 路径与符号归一化 tokens.js token 估算 kinds/ 每种内容类型一个压缩器 locale/ i18n:en.json、zh.json scripts/ 七个套件、共用的会话日志读取器,以及三个诊断脚本

许可

MIT。
预览分享卡片长什么样 ↓boxiaolanya2008/tokensqueezer
分享 · DeepSeek Harness Hub
boxiaolanya2008/tokensqueezer

压缩模型自身输出,降低每轮对话的 token 开销

回到顶部