DSH Plugins Marketplace

DSH Plugins

Plugins

/

Memory & Context

/

dsh-GOkifu-compact

d

dsh-GOkifu-compact

Identified

Kifu-style context compression for long DSH sessions: each step folds new turns into a DAG (node = position, edge = attempted fix), injects only a ~415-token hot list (2000-edge fixture, L5 tier), and

dsh-GOkifu-compact

当前版本:1.16.0 · npm dsh-gokifu-compact · GitHub Releases · 更新记录见 CHANGELOG.md

DSH 的棋谱式上下文压缩后端 —— 把「历史 → 一段摘要」换成「历史 → 可复盘的棋谱 DAG + 每步只有 351 tokens 的热清单」。

热清单     351 tokens       (2000 边合成夹具 · L5 降级档 · 2026-10-30/10-31 两次实测同值;旧版全量 28,800)
失败保留   8 / 8            (历史口径 †;官方 8 段模板 4.67 / 8)
清单开销   未复现/待测       (原载 0.2% = 历史单会话 v1.3.1 后实测;无复跑命令、无对照组;源 evidence/真实计费核对.md)
验证       615 项单测(0 skipped) · 真实包 8/8 † · 真实进程 fold 3~6/6 †

复跑: node scripts/bench-repro.mjs —— 一条命令重新打印「热清单 tokens」与「失败保留」两个数字; 与基线不一致时以退出码 2 报出(算法或夹具改动需人工确认后更新基线),复跑失败退出 1。 当前基线:热清单 387 tokens(1.13.0 加权校准后)、失败保留 8 / 8;上面那个 351 是 2026-10-30/31 校准前的实测同值。

GO = 围棋,kifu = 棋谱,compact = 压缩。一局棋下完,棋谱上不只有落子顺序,还有每一手的评语。 这个插件把 agent 的每一步变成一手棋(节点)、把当时的思考变成评语(目标 / 约束 / 失败原因), 整个任务变成一局可以复盘的棋。棋谱是给模型用的,不是给人看的 —— 热清单里的每个字都为模型决策服务。

† 历史口径(未复现):失败保留 8/8、真实包 8/8、真实进程 fold 3~6/6 都是早期真机测量,本轮没有复跑命令、没有复现,不要当现行指标引用。

351 tokens 的口径:这是 2000 边合成夹具在 L5 降级档下的结果,不是真实会话均值。 真实会话里预算按 字符数/3 估算,实测系统性低估 5.2%~22.1%(中位 9.7%)(见 计划表.md 的 OPT-TOKENS 节);真实会话口径尚未校准 —— 正解是引入宿主 tokenizer(ctx.tokenMeter)后重测,未做。 ⇒ 1.13.0 已校准:热清单预算改成按字符类别加权 —— CJK 1 token/字 + 其余 1/4 token/字 (ASCII 侧对齐宿主 dsh-token-meter 的 CHARS_PER_TOKEN = 4;全角标点算 CJK)。 锚点:2478 字符的真实热清单,旧口径 826(−8.8%) → 新口径 933,网关实测 905(+3.1%)。 归档 176 会话复算:avg 412.40 → 417.88、max 826 → 933、over-500 25 → 25 (张数没变是渲染器自适应降档换来的;只换公式不重渲染会是 over 56 ⇒ 旧口径那 25 张里有 31 张靠低估撑出来)。 注意两套口径并存:会话压力 / fold 触发由宿主 ctx.tokenMeter.measure(session) 定价,热清单是本文这套加权估算。


功能

  • 增量 fold —— 只压「上一个 checkpoint 之后」的新内容;一段历史一生只被摘要一次。
  • 失败记忆 —— 每条失败尝试的意图 / 动作 / 报错原文 / seq 由规则抽取并逐字保留,模型没有丢弃它的权限。
  • 手割(tewari) —— 同一条失败边相对每条成功路径分别给结论:同型 / 绕路 / 探新,不是一个笼统的「失败」。
  • 热清单 —— 每步重建的小清单:语义标记(blocked:permission / dead retry-if:e1)+ 动态图例 + 报错原文;就地替换,surface 上永远只有一条。
  • 置换检测 —— 状态哈希命中历史节点时不新建分支,只在图上加一条边,并提示「回到节点 N —— 这里试过的路都记着」。
  • 三层树 —— index.md(全量索引)/ nodes/<id>.md(单节点细节)/ graph.json(数据源),模型按需往下查。
  • 压缩永不失败 —— 摘要三层降级:配置的摘要模型 → 当前路由模型 → 规则摘要(零模型调用),fold 一定能落地。
  • 可诊断 —— doctor 一条命令体检、measure-billing 按真实 usage 对账、rewash 回洗历史误报。

怎么工作

每一步:事件流 ──► 棋谱 DAG(节点 = 状态;边 = 尝试 + 验证信号)
                        │
                        ▼
              热清单(根目标 / 约束 / 成功路径 / 失败边)──► 注入模型
                        │
             到阈值(默认窗口 45% 且增量 ≥ 40K)
                        ▼
              增量 fold:只压上一个 checkpoint 之后 ──► 棋谱摘要(失败边逐字保留)

和官方 dsh-compaction-basic 的区别:

官方 compaction-basic本插件
压缩范围从 surface 第一个非 system 节点起(含上次 checkpoint)上一个 checkpoint 之后
保留率每轮重摘 → 按 ρ^k 衰减(实测安全规则 5 轮后剩 10%)一段内容只摘一次
失败记录融进散文摘要,模型可以丢规则抽取 + 逐字注入,模型无权丢
热上下文无351 tokens / 步(2000 边合成夹具 · L5 降级档;真实会话口径未校准),带语义标记与报错原文

⚠ 棋谱落盘:graph.json 的语义(1.9.2 起)

graph.json 不再代表「最新状态」,而是「上一回合基线 + 当前增量」。

每次都重写整图(≤1.9.1)      增量落盘(1.9.2 起)
graph.json = 最新             graph.json              = 上一个回合边界的完整基线
                              graph.json.delta.jsonl  = 本回合的增量帧(带 baseHash + checksum)
                              (两者合并 = 最新状态)

⇒ 它在回合内落后一回合。 任何直接 JSON.parse(graph.json) 当「最新」的脚本,都会少一回合的数据。 graph.json 只在回合边界(agent/status idle)落一次完整快照;回合内的每一步只往 graph.json.delta.jsonl 追加一帧。

你要什么怎么拿
最新状态(推荐)基线 + 增量一起读:fromJSON(graph.json 文本) → 用基线内容哈希 decodeDeltaFrames(delta 文本, baseHash) → 逐帧 applyDelta(g, frame)。三个函数都从包入口 dsh-gokifu-compact/graph 导出(源码 src/rooms/kifu-model.mjs,随包发布);落盘/读盘侧(graphRoot / sessionPaths / createPersistStore 等)走 dsh-gokifu-compact/persist
上一回合基线(做 diff / 审计)直接读 graph.json 可以,但要说明「这是基线不是最新」
崩溃安全每帧带 baseHash(generation)+ checksum31:半写帧解码时就地停止,加载时把 delta 截到最后一条好帧;旧 generation 的帧整体忽略

为什么这样设计:写放大从 ×80 / ×70 / ×62 降到 ×37 / ×33 / ×31(三张真实图 60 步 + 1 回合边界), fold 后 flush 从 429–836 ms 降到 ≤95 ms;代价是「读的人必须知道这是增量结构」。

三条已知余量(选型时要知道)

  1. 短回合写放大:每回合边界落一份完整基线(0.5–0.6 MB)。真实分布 p50=40 步/回合 ⇒ 写放大 ≈×20–25; 但**极短回合(<10 步,p10=13.9)**摊销不足,写放大仍可能 >×50。
  2. dirty > 100 的 flush:fold 后只写 dirty 节点 —— 5–20 个 dirty 时 9–23 ms,100 个时约 87–89 ms (改前全量 429–836 ms)。dirty 数极大时收益收窄。
  3. appendFileSync 的原子性依赖 OS:本机 NTFS 上 1 KB 级追加已过半写测试;跨平台(尤其网络文件系统)未验证。

热上下文长什么样

每步 agent/pre-step 注入(内容不变时复用;变了就就地替换上一条,surface 永远只有一条):

<chess-ledger>
ROOT USER (verbatim): 把 tests/case*.test.js 跑绿:缓存键算错了。不要动 prod 配置。
CONSTRAINTS (verbatim):
- 不要动 prod 配置。
CURRENT GOAL: 缓存键修好,case7 通过
WORKING: user → n2 (exit 0)
LEARNED (3 failed attempts):
TRACE: <sessions>/<sid>/index.md  (per-node detail: nodes/<id>.md)
# markers:
#   dead = a working path avoids it — retry only if retry-if breaks
#   redundant = working edge <edge> reaches the SAME position — take it
#   blocked:permission = needs a permission this environment lacks — retry when it changes
- e2 "把缓存键改成 JSON.stringify 全部参数" → AssertionError: case7 expected 1 got 2 … [dead retry-if:e1]
- e3 "装全局 sqlite 依赖后再跑" → npm ERR! EACCES: permission denied, mkdir … [blocked:permission]
</chess-ledger>

预算不够时降级不丢边:先缩短意图与报错,再砍 seq,最后只列最近 N 条 + 汇总行。 标记档位可调:semantic(默认)| terse(只写三态)| off(不打标记)。

安装

一条命令,和装别的 DSH 插件一样。 本包自带 dsh.bundle.patch:装进 profile 后会自动进 dsh.profile.bundles,并由这一个包同时完成两件事 ——

  1. 插入 UI 页(/gokifu/api + 设置页);
  2. 按 id 整体覆盖四个官方 agent preset 的 config:把每个 preset 的 compaction group 里 @deepseek-ai/dsh-compaction-basic 换成 dsh-gokifu-compact/engine —— 标准 / PTC / 极简 / 创造 四个模式都变成棋谱压缩,模式本身与选择器不变。

⇒ 装上即接管,不需要选模式:不管挑哪个内置模式,压缩都走棋谱(失败记忆逐字保留、每步热清单、 置换检测、压缩永不裸截断)。不新增 preset、不改「新会话默认 preset」,所以也不会多出一个要学的模式。

桌面版最省事的是 插件市场 → 安装(点一下)。命令行等价于:

dsh plugin --profile <profile> add dsh-gokifu-compact

然后重启 DSH(bundle 层在启动时合并)。重启后随便选个模式发一条消息,压缩就是棋谱压缩了。

怎么确认生效:设置页「上下文压缩」能正常加载;或 POST /gokifu/api {"action":"health"} 看 mounted:true;更硬的判据是看 <DSH_HOME>/chess-context/sessions/<id>/graph.json 有没有出现。

代价要说明白:patch 里的 preset 清单是按宿主版本生成的快照(生成时读取宿主 asar 里的官方 preset), DSH 升级后需要维护者重跑 node scripts/make-presets-override.mjs --write 并发一版新插件。 生成器有「不新增 preset / 引擎行恰好 4 条 / !!js 表达式逐字保留」的机器判据,漏了会拒绝产出。

从源码(开发用)

node scripts/make-presets-override.mjs           # dry-run:看将从当前宿主 asar 生成什么
node scripts/make-presets-override.mjs --write   # 重写仓库根的 cordis.patch.yml
dsh plugin --profile <profile> add <本仓库路径>    # 或按下面的说明用市场/registry 安装

⚠ 压缩后端只能有一个:patch 覆盖后,四个 preset 的 compaction group 里都只有 dsh-gokifu-compact/engine(bundle.test.mjs B-2 与生成器都有机器判据)。 若之前装过 1.15.x 的 dsh-gokifu-preset 包(或 profile 里留着 preset-gokifu 行), 先 dsh plugin --profile <p> remove dsh-gokifu-preset,否则同名 preset 会重复注册。

配置

- id: gokifu-compact
  name: 'dsh-gokifu-compact'
  config:
    auto: true                # 自动压缩(继承基类的 between-step 压力触发)
    thresholdRatio: 0.45      # 压力闸:min(窗口×0.45, 窗口−输出预留−64K)
    growthFloorTokens: 40000  # 增长闸:距上次 fold 至少新增这么多 token
    retainRatio: 0.16         # 逐字保留的近期尾部
    summaryMode: hybrid       # hybrid | rules(零模型调用)| llm
    maxTokens: 8192           # 摘要输出上限(实测一次 fold 用到 2,902,留足余量防截断)
    summarizationProvider: '' # 留空 = 跟随当前路由(最稳)
    summarizationModel: ''    # 想用免费模型,先确认 provider 的模型表里有那个 id
    hotLedger: true           # 每步注入失败清单
    hotLedgerMaxTokens: 500
    hotLedgerMarkers: semantic # semantic | terse | off
    hotLedgerReplace: true    # 就地替换旧清单(surface 永远一条)

全部配置项与含义见 docs/性能与成本.md 与 src/engine.mjs 的 Config。

常见问题

关掉原生压缩,自动压缩还在吗? 在 —— 本插件就是那个自动压缩后端:它继承官方的 BasicCompactionEngine(同一套 between-step 压力触发、context-overflow 兜底、事务语义), auto 默认 true,装的不是「替代品」而是「换引擎」。变的只是「压缩范围 = 上一个 checkpoint 之后」 与「失败记忆逐字保留」。

压缩之后数字会降吗?会不会只增不减? 会降。一次 fold 用一个 checkpoint 替换掉整段被遮蔽的 历史,tokenMeter 重新计算后数字直接下降;但不会归零 —— 还会保留逐字尾部(retainRatio,默认 16%) 和摘要本身。典型形状是锯齿:涨到阈值(窗口 45%)→ 压到约 20% → 再涨。如果你看到「只涨不降」, 先跑 npx dsh-gokifu-compact doctor 看压缩是不是在失败(compaction/end 的错误会直接列出来)。

装完没反应 / 压缩没触发? 插件在 DSH 启动时加载,必须重启。重启后跑 npx dsh-gokifu-compact doctor (在源码仓库里是 node scripts/doctor.mjs),它会告诉你四件事:装没装上、摘要模型能不能解析、 最近的压缩成功/失败、棋谱与树健不健康。

会不会把失败记忆弄丢? 不会。失败边由规则抽取并逐字注入摘要 prompt,模型输出后还会机械追加约束段; 模型没有「决定丢掉某条」的权限。真实模型对照里本插件保留 8/8,官方 8 段模板平均 4.67/8。

摘要模型要配吗? 不用,留空就跟随当前路由。配了但 provider 的模型表里没有那个 id 时, 引擎会退回路由模型;再不行就退回规则摘要(零模型调用)—— 宁可摘要朴素,也不让压缩失败。

历史数据会不会把压缩弄坏? 不会。插件加载棋谱时会自动修复旧格式(worldHash 对象 → 字符串、状态索引重建); 旧版本追加出来的几十条热清单会被一次性换成一行占位。全库 1,279 个坏字段实测归零。

为什么压缩还是会让 prompt 缓存失效? DSH 的 surface replace 语义决定:替换点之后的 KV 前缀会失效。 增量 fold 让替换点尽可能靠后,但无法消除(这是 seam 的语义,不是实现选择)。真实会话实测缓存命中率 94~97%。

能和多分支/子代理一起用吗? 子代理各自独立会话、各自一张棋谱;主会话的置换提示只在同一会话内生效。

参考源

只借鉴结构与规律,未复制代码:

来源用在哪
magpie-plugin-scaffold(MIT)README 模板、发版七步、维护检查脚本(scripts/)
billion-context(MIT + 署名附加条款)「增量 fold / 只压已消费内容」的架构不变量、缓存与保留率的判据
opencode-dcp(MIT)「每个机制一节」的说明结构、对 prompt 缓存影响如实交代的写法
DSH 官方 dsh-compaction / dsh-compaction-basic(随 DSH 分发)继承 compactRegion / surfaceOp: replace 事务语义,只覆盖策略层

设计依据与实测数据在 docs/市场对标.md 与 evidence/。

文档

更新记录:CHANGELOG.md(发版流程见 scripts/release.mjs;维护侧的 HANDOFF.md 不随 npm 包发布,在 GitHub 仓库根目录)

许可

MIT。见 LICENSE。

Comments

Loading…

Similar plugins

dsh-long-memory

by dogbotowo-oss

Long-conversation memory for DeepSeek Harness (DSH): keeps settled decisions, user corrections and exact numbers, with their conditions and sources, available across compaction and restarts in 100-100

Memory & ContextSessions & MessagesManifest valid

★ 1

MIT

JavaScript

Oct 31, 2026

dsh plugin --profile web add dsh-long-memory

by zhaoyuntao-wl

Decision-and-goal memory with lineage: explicit commands and a model tool record decisions deterministically, a status card re-anchors them across compaction, a lossless event stream with BM25+jieba r

Development & InfrastructureMemory & ContextManifest valid

★ 2

↓ 208/wk

MIT

TypeScript

Oct 19, 2026

dsh plugin --profile web add dsh-thread

by zhubaohi

Compaction fix for NInfer-hosted qwen3.8-27b gateways: disables thinking on dsh context-compaction and session-title calls so xhigh reasoning stops burning the whole output budget; the same idea appli

Memory & ContextModels & ProvidersManifest valid

★ 4

↓ 140/wk

MIT

JavaScript

Sep 6, 2026

dsh plugin --profile web add dsh-qwen38-ninfer-compaction-fix

by snow-The

Scans and repairs DSH session logs: re-encodes single-frame corrupt zstd files back to the multi-frame layout and marks unknown event types (e.g. llm/failover) as ignorable so older harnesses can load

Manifest valid

★ 0

MIT

TypeScript

Nov 1, 2026

dsh plugin --profile web add @snow-the/dsh-session-repair

by hzh5021

Warns the session to flush what matters before context compaction kicks in, and rolls a long-term ledger into a frozen archive with a one-line digest per moved section.

Development & InfrastructureMemory & ContextManifest valid

★ 1

MIT

JavaScript

Oct 26, 2026

dsh plugin --profile web add dsh-memory-watch

by NoxTyrannus

Cipher memory platform as a DSH bundle: four memory types (attention, experience, preference, cognitive) sedimented per turn by four memory agents, cross-session deterministic recall injected via syst

Memory & ContextSessions & MessagesManifest valid

★ 2

↓ 87/wk

NOASSERTION

TypeScript

Aug 31, 2026

dsh plugin --profile web add dsh-cipher