前言¶
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 / 幻方无官方从属关系。