中文EN

dsh-memory-tiers

memory已测通过npmMIT

dsh 的六层本地记忆插件:捕获对话轮次,经 L2 巩固、由分流模型沉淀为 DL3 摘要,每轮注入稳定记忆块并以占位符替代聊天历史。附五个记忆工具与配置页。

下载量 / Downloads
2,148
依赖体积 / node_modules
0.35 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-memory-tiers

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

dsh-memory-tiers

给 DeepSeek Harness 用的六层本地记忆插件:

  • 每轮对话结束后,把「你问的 / 模型答的 / 工具做的」写进 L1 即时层;
  • L1 字数超过上限,下一轮整理就分流成摘要与原文:被摘要引用的原文进 DL2 原文库,没被引用的进 DL1 遗忘中,少量留在 L2 巩固层;
  • 摘要进 DL3 摘要库,按热度截出一份 L3 长期视图;
  • 每轮把 L3 + L2 + L1 拼成一块注入上下文;
  • 可选地把 dsh 自己的对话历史替换成一条占位——用记忆替代历史,聊再久上下文也不涨;
  • 工作模式按会话独立:开过工作模式且对话过的会话会永久保留历史,不再被记忆接管;
  • 可插人格(系统提示词之后、记忆块之前),可另开「分流/分类也带人格」;
  • 自带记忆星图,随插件打开,读 storage.dir,不另起端口;
  • 大部分配置保存即生效,只有模型通道等少数项需要重载插件。

全部数据在本地,不依赖任何云端存储;模型只用来做分流(摘要)、融合(判关系)、算向量。


文件

文件 · 干什么

memory.mjs · 记忆系统:六层读写、分流/融合/遗忘、检索、注入块。不认识 dsh,不联网

llm.mjs · 模型层:OpenAI 兼容 HTTP + 「跟随当前会话模型」通道

index.mjs · dsh 适配:订阅事件、注入上下文、5 个工具、/memory 命令、历史压缩、装载诊断

settings.mjs · 配置:唯一的字段表(默认值/类型/范围/说明)+ 读写迁移 + 配置页服务端接口

client.mjs · 配置页(设置 → 记忆)与会话模式标记。配置字段全部由服务端 schema 渲染

star.mjs · 记忆星图页面与数据函数;由插件挂到 /dsh-memory/star,开发可用 tools/star.mjs

cordis.patch.yml · 告诉 dsh 把这个包装进配置树

测试在仓库的 ../test(不进包):npm test 或 node --test ../test/*.test.mjs。

实机验证照 ../docs/VERIFY.md 走;配置页字段核对表见 ../docs/CONFIG-PAGE.md;配套脚本在 ../tools:

preflight.mjs(装机前自检)、inspect-session.mjs(从会话日志 + status.json 验「工具/注入/压缩」)、

collect-report.mjs(一键打包取证)、seed.mjs(造假库看注入块)。


装在 dsh 里

# 在 dsh 的 profile 里 link 这个包(包根目录 = 本目录)
pnpm add "link:<这个目录的绝对路径>"

或者由 dsh 的插件管理器安装。装完重载插件,设置 → 记忆 里就能看到配置页。


配置

位置固定:<DSH_HOME>/memory-tiers/config.json(DSH_HOME 缺省 ~/.dsh)。

同目录还有 log.txt(插件审计日志)、status.json(装载与运行状态)、context.txt(/memory context file 导出)。

  • 启动时文件不在 → 用内置默认值生成一份;
  • 有但残缺 → 补齐并写回;
  • 有但坏了 → 改名 config.json.broken-<时间戳> 后重建;
  • 旧版(0.9.x)的 ~/.dsh/memory-tiers.json → 自动迁移,旧文件改名 .v1-bak。

改配置:设置页里改,或者直接编辑这个 JSON。大多数项保存即生效;模型通道、存储目录、写者、全局工作模式默认值、整理定时器间隔这几类需要重载插件,页面上会标「需重载」。直接改文件时,插件不会自动重读,仍需重载。

数据目录(storage.dir,默认 <DSH_HOME>/storages/memory)可以随时改、可以搬,

但旧目录里的内容不会自动搬过去——那是你的数据,插件不替你搬。

会话状态在 <DSH_HOME>/memory-tiers/sessions.json(工作模式/接管豁免名单),跨重启和插件升级保留。


六层与七个步骤

层 · 内容 · 进上下文

L1 即时 · 刚发生的原文(含工具做了什么) · 是

L2 巩固 · 近期沉淀的原文 · 是

L3 长期 · 从 DL3 按热度截出来的摘要视图(不落盘) · 是

DL1 · 没被摘要引用的原文,慢慢遗忘 · 否

DL2 · 被摘要引用过的原文,保细节,按需检索 · 否

DL3 · 摘要库,融合去重在这里做 · 否

流程:收(写 L1)→ 分(分类 + 摘要 + 分流)→ 合(新摘要 vs 旧摘要)→

沉(L2 满了连同 DL1 再压)→ 忘(DL1/DL3 按规则清理,先写台账)→

喂(注入块)→ 替(压缩历史,写成功才丢)。

分流规则(两阶段)

两个阶段、两套 prompt,条目本身不带任何标记:

阶段 · 触发 · 模型输出 · 去向

L1 分流 · L1 字数超过 hotChars(不等安静期,下一轮整理就分) · ★ 摘要《行号》 · 摘要 → DL3;被引用的原文 → DL2

· · + 行号 · 原话 → L2

· · 不写 · 原话 → DL1

L2 分流 · L2 满了 · ★★ / ★ / ☆ 摘要《行号》 · 摘要 → DL3(importance 0.9 / 0.6 / 0.3,都算长期记忆)

· · + 行号(最多 l2KeepMax 条) · 原话 → L2,其余 → DL1

· · 不写 · 原话 → DL1

  • 没有「·」这一档了:旧版的 ·(0.7) 与 first-pass 的 0.9 过滤线结构互斥,会让摘要必灭。
  • 只有带标记的行才算数;其它行忽略(原文走「没被引用」的路,沉 DL1)。
  • 术语:summary 阶段叫分流模型(挑 + 摘要 + 保留一次完成);chat 阶段叫融合模型

(分类 + 判重复/矛盾/进展/新增)。L2 存的是原话,摘要只在 DL3/L3。

清理规则

层 · 规则

DL1 · 遗忘曲线(layers.forgetThreshold)+ 容量上限 layers.dl1MaxChars:超了按「越旧越先清」清到 80%,优先清已整理过的(pendingDigest 的最后动)

DL3 · 只淘汰琐事档(importance < 0.45):按保持率衰减,低于阈值才删;中/高档只靠融合合并/作废;不足 1 天的不动;被删摘要独占的 DL2 原文一起清理

所有删除 · 一律先写遗忘台账(graveyard/forgotten.jsonl),写不进去就不删;pinned 不动

几条硬约束(改代码前先看):

  • L1.tmp/<writer>.jsonl 只追加、追完就关,不长期持有句柄;
  • 先写目标层、最后写 L1,崩了重跑靠 id 去重;
  • 不删别人的临时文件,rename 认领成功才算自己的;
  • 同一 id 只出现在一层;
  • 没有模型就不产生摘要:原文只能下沉 DL1 等模型,不许假装整理过。

工具与命令

名字 · 干什么

memory_write · 明确把一条结论写进记忆

memory_search · 检索(summary / detail / full 三档深度)

memory_attend · 确认哪些检索结果真的相关(热度 +1;只搜到不算数)

memory_forget · 删掉记错的一条(下次整理生效,会写遗忘台账)

memory_stats · 六层条数、待整理、整理锁、数据目录

/memory · list 看六层;context [all\ · file] 导出「模型这一轮收到什么」

/memory context 的导出 = 系统提示全文 + 本轮人格 + 本轮将注入的记忆块 + 其余消息原样;

人格和记忆块实际落在本轮用户消息之前(inject-order),导出里也按这个顺序排。

不列工具定义、不转储请求配置。默认写 context.txt(不刷屏),context all 强制刷屏。

⚠ 注入块不是从会话消息里反推的:dsh 的 systemPrompt.context() 贡献在请求组装时才合成
runtime-context 消息,而命令执行在组装之前(加上「全部替换」的压缩会清掉上一轮快照),
所以会话消息里看不到它。插件用 mem.buildBlock() 按当前库实时构建这一块——文件里那一段就是
本轮真正会注入的内容;注入关闭/工作模式/已豁免时会写明原因。

人格槽位

配置页「人格」组:

项 · 默认 · 说明

persona.enabled · true · 人格注入总开关;关掉后配置正文和外部片段都不生效

persona.text · 空 · 人格正文。空 = 不注入,不留空行

persona.inSummary · false · 分流/分类时临时带人格;默认关,和注入开关独立

  • 注入位置固定在「系统提示词之后、用户消息之前」:人格 order 90;记忆块动态取 WEB_SURFACE - 5(通常 205),排在稳定环境段之后、端口/URL 块之前;DSH 默认把快照放在用户消息后,插件用 agent/pre-step 把它移到本轮消息之前;
  • 人格逐字稳定:不要写时间戳或每轮会变的内容;
  • 其它插件可以通过 Cordis 服务 memoryTiersPersona 追加片段,返回 disposer 即可撤销:
const off = ctx.get('memoryTiersPersona').register({ id: 'my-persona', order: 100, text: '…' })
off()
  • persona.inSummary 只改分流/分类的 system 前缀,不改三档判定标准、不写进摘要正文。

记忆星图

安装后打开 设置 → 记忆 → 打开记忆星图,或直接访问 <api.baseUrl>/dsh-memory/star(例如 http://127.0.0.1:7307/dsh-memory/star)。

  • 数据来自插件内存里的六层,跟随 storage.dir,不另起端口、不每 30 秒读盘;
  • 页面 UI 与单独跑 node tools/star.mjs serve 时一致;开发时仍可用该 CLI 生成静态快照。

工作模式(专注干活)

工作模式按会话独立,不再是一个全局开关。配置页的 workMode.enabled 只是「新会话默认值」(改它需要重载插件);单个会话在输入框旁的小标记里随时切换。

维度 · 普通 / 记忆接管 · 工作模式 · 已豁免

注入记忆块 · 每轮 · 不注入 · 不注入

替代历史(压缩) · 每轮 · 不压缩 · 不压缩

收 / 分 / 合 / 沉 / 忘 · 正常 · 正常(粗骨架记录) · 正常(粗骨架记录)

抓取/层容量 · capture. / layers. · workMode.(更大) · workMode.(更大)

  • 豁免:开过工作模式、且确实对话过的会话,即使之后关掉工作模式,也永久保留历史、不再被记忆接管(落盘在 sessions.json,跨重启/升级保留)。
  • 解除豁免:输入框旁标记或设置页会话表里可以解除,但会先提示「历史可能被压到 0」,并要求二次确认。
  • 粗记忆:工作模式进 L1 前先压成一条骨架(地点 / 事件 / 做了什么 / 结论),不记命令输出和过程噪音;可用 workMode.skeleton.enabled 关掉。
  • 状态标记:工作模式 / 工作模式 · 已豁免 / 记忆接管 / 普通,与实际行为同源。

排障

先看两个文件:

  • <DSH_HOME>/memory-tiers/status.json → boot.steps(哪一步成功了

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:13,最后更新 2026-11-05

链接

GitHub · Homepage · npm

同类插件