dsh-memory-router:挂在 DSH 工具调用边界上的 Token 压缩插件

前言

Agent 每读一次工具结果,其实是一次「回读」:工具返回 8000 字,模型为了决定下一步,要把这 8000 字重新读一遍。下面介绍的 dsh-memory-router 做的就是在这次回读之前把事办掉——同一份内容不重付,长输出按字段裁剪,状态类问题不反复注入。

它需要先记一笔账。这个插件自带一套「省 / 花 / 赔」的账本,把截断省下的 token、注入花掉的 token、以及压缩过头导致模型重读的赔钱项都记下来,而不是只报喜。文末会给出它自己的实测结论:单次命中确实省,长期累计净收益目前是负的。

这是什么

dcd887/dsh-memory-router,维护者 dcd887,分类「工作流」。它挂在 DSH 的工具调用边界上,处理两类浪费:

  • 同一个文件、同一个命令被调用两次,第二次的文本模型又读一遍;
  • 工具返回很长,模型实际只需要其中几个字段。

它对标 HarnessMM(arXiv 2610.32813)里提出的 EDG / GDR / CCS 三个机制,是作者在 DSH 上做的可运行等价实现。注意作者自己也明确说明:DSH 的 PostToolDecision 只有 accept / block 两支,没有「执行下一个动作」这一分支,所以插件省的是上下文体积,不是模型回合数。

核心功能

插件由四个模块组成,均为生产环境验证状态(inject 注入闸门为单测通过):

  • dedupe:同工具同参数,在 TTL 缓存窗口内直接复用上次的文本,工具本身不再执行;
  • edg:声明式决策图,匹配工具名与参数,守卫条件为真时执行一条本地只读动作,用结构化结果替换原始输出;
  • liveState:会话延续,自动落盘「在处理什么、动过哪些文件」,新会话第一轮注入;
  • inject:注入闸门,用内容哈希去重、长度上限和账面行限频控制注入次数。

处理顺序是固定的:去重 → 决策图 → 阈值压缩 → 缓存最终文本。任一步抛异常都会回落,不阻断主循环。

edg 的门禁很窄:守卫只有 exitCode / fileExists / regex / minChars / jsonPath 五个纯本地算子;动作只有 readJson / readFileSlice / grep / stat 四个只读动作。写 exec 会直接抛错。设计意图是:决策图配错了,最坏结果是退化成没有它。

安装与启用

README 给出的安装方式是从仓库拉下来跑一遍测试,再以本地插件方式挂进 profile:

git clone https://github.com/dcd887/dsh-memory-router.git
cd dsh-memory-router && npm test      # 6 个测试套件,92 项
# 在 profile 的 node_modules 下建链接(Windows 用 mklink /J)
ln -s /path/to/dsh-memory-router ~/.dsh/profiles/web/node_modules/@local/dsh-memory-router

重启 DSH 后生效。仓库标注状态为 alpha,Node 要求 >=18,许可证 MIT(README 注明提交前应补 LICENSE 文件)。这个插件以当前 DSH 进程的权限运行,装之前应当把 index.js 和 lib/ 下的源码读一遍,确认行为符合预期。

典型用法

决策图配置放在 ~/.dsh/memory-router/edg.json,仓库内的 edg.example.json 给了十个节点的示例。一个节点长这样:

{
  "id": "tax-table-pick-fields",
  "match": { "tool": "read", "args": { "file_path": { "$re": "hs_codes" } } },
  "guard": { "minChars": 2000 },
  "then": [
    { "act": "readJson", "path": "${args.file_path}", "limit": 3,
      "pick": ["hs_code", "name", "import_tariff", "category"] }
  ]
}

这条规则匹配读取 hs_codes 相关文件的调用,命中后先看字符数是否超过 2000;超过则只取前 3 条的 4 个字段返回。

一个真实会话的对比数据来自 README:

场景 原生 插件后 省
读税则大表(8972 条) 6031 字 298 字(总条数 + 3 条样本 × 4 字段) 1433 token
读盲推记录(26 KB) 8035 字 1707 字(标题骨架 + 错误行 + 结论行) 1582 token
重复执行同一条命令 重新执行 命中缓存,未执行 账本记 dedupe

十案例 A/B(node scripts/ab.mjs,可复现)的结果:命中 6/10,命中时平均节省 96%;合计是挑过的样本,属于上界;按三成命中率折算约 29%。

记账口径

插件把每一笔开销写入 metrics.jsonl,口径如下:

净收益 = 裁剪省 + 去重省 + 决策图省 − 重读赔 − 注入花 − 摘要花
科目 记什么
trim 压缩省下的
trim-skip 省得太少没压的次数(不进账)
dedupe 复用缓存省下的
edg 本地执行替换输出省下的
reread 负收益:上次压过,同一调用又来了
inject 注入花的

查看账本:

node scripts/stats.mjs

README 明确写出的一段累计账本是:

裁剪省 1223  ·  去重省 0(2 次)  ·  决策图省 3015(2 次)
重读赔 0     ·  注入花 14755     ·  净 −10517

两个解释:注入开销是历史累积的,大部分发生在「注入闸门」装上之前;另外验证方式放大了它——作者一直在同类问句上反复测。所以「单次命中省 1400—1600 token」是真的,「长期净收益为正」还没有被证明。

作者额外加了一个论文里没有的科目 reread。理由是:压缩越多,账面越省,但模型可能因为信息被裁掉而重新读一遍,实际反而更贵。不记这笔账,账本就系统性偏高。

适用场景与注意

适合的场景是工具输出长、字段固定、调用还会重复出现的工作流。README 提到的负载类型是写作与调研类 Agent。

需要注意的几点:

  • 累计净收益目前是负的,作者把这段写在 README 靠前位置,并建议读完再决定要不要 Star;
  • 它是 alpha 状态,功能和配置格式都可能再变;
  • 它省的是上下文体积,不是模型回合数,跟论文 GDR 的起点不同,别把论文里的数字直接套用;
  • 插件以当前 DSH 进程权限运行,安装前读源码、确认许可证;
  • 星标为 0,生态位还早,用之前自己用 node scripts/ab.mjs 在本地跑一遍复现。

相关链接

目录页: https://www.skillhub.cn/plugins/dcd887/dsh-memory-router
仓库:   https://github.com/dcd887/dsh-memory-router
论文:   https://arxiv.org/abs/2610.32813

目录页是独立站点,与 DeepSeek / 幻方无官方从属关系。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜