前言¶
DSH 的会话之间默认互不相识。每开一个新会话,你都要把背景、偏好、上次踩过的坑重新交代一遍;模型改过的错,下一个会话大概率再犯一遍;散落在各处的人设和工作准则改不动、也传不下去。dsh-elysia 针对的就是这个缺口:它让所有会话读同一份磁盘上的 MEMORY.md,模型在每轮对话里看到的记忆都直接来自磁盘,上下文被压缩之后自动重新读取。
不同于一般「文本写在这个文件里、下次别忘了」的备忘,它把记忆做成了一套带检索、带淘汰、带备份的小系统。这也是它和普通人设插件的区别:自带整份角色自我记忆包,但它是可选装的「皮肤」,默认不装。
这是什么¶
由 1148462398-hub 维护,在社区插件目录里分类为「记忆」,GitHub 星标 0(截至抓取时)。对应 npm 包名 dsh-elysia-memory,版本 2.6.0,许可证 MIT。
一句话定位:一份全 DSH 会话共用的 Markdown 记忆文件,配双硬盘分区镜像备份、命中频率分层归档、BM25 模糊检索、质疑度驱动换方法,外加一个可选装的角色记忆包。
记忆文件长什么样¶
单个 Markdown 文件,人类可读、可以手工编辑,用 HTML 注释标记划分区块。README 里的表格列了七个区块:
| 区块 | 内容 | 谁来写 |
|---|---|---|
persona |
当前模型的人设提示词 | 模型(用户对话要求时) |
requirements |
用户要求与长期偏好 | 模型 |
requests |
用户输入流水(每轮自动摘要一行,滚动淘汰) | 插件自动 |
corrections |
用户指正(错在哪 / 以后怎么改) | 模型 |
lessons |
自我教训(自己发现的错误) | 模型 |
methods |
更好的方法(场景 / 做法 / 为什么更好) | 模型 |
sessions |
会话索引(含压缩事件) | 插件自动 |
requests 与 requirements 分开是刻意的:每轮自动摘要不把长期要求挤掉。requests 只是流水,检索时能看到;requirements 只放模型判断值得长期保留的。
<!-- dsh-shared-memory:xxx:start --> / :end 这两类标记请勿删除,其余正文随便改。
有一点需要在读代码前留意:README 的表格写七个区块,而 package.json 的描述写成「九个分区」,并额外提到 identity(自我记忆,优先级高于人设)、methodbook(方法库)和 docs。网页那节也提到 docs。两处口径不一致,实际分区数量以插件代码为准。
存储位置与双备份¶
默认主文件在 C 盘,镜像自动选第一块非系统盘:
%USERPROFILE%\.dsh\dsh-shared-memory\MEMORY.md
D:\dsh-shared-memory\MEMORY.md
写入规则:
- 每次写入同时写主 + 镜像(临时文件 + rename,写完回读校验)。
- 插件启动时对账:只缺一侧就从另一侧回补;两侧内容不同就先把较旧的一份存成
.conflict-<时间>.bak,再用较新的一份收敛;两侧都没有就按模板重建。 - 想换位置:让模型调用
memory_file_maintain(action=relocate),或改dsh/cordis.patch.yml里的primaryPath/mirrorPath后重启。 - 想彻底清空:
memory_file_maintain传action=reset+confirm="DELETE_BOTH",否则插件拒绝执行。
主文件和镜像落在同一个盘符时插件会在日志里告警。
注入与检索¶
注入不是把记忆整份塞进提示词。系统提示词里挂的是:人设(常驻,占预算约 1/3)+ 记忆使用协议 + 每个分类的索引摘要。摘要只显示最新 M 条,放不下的明说还有 N 条较早记录未显示,需要用 memory_file_search 检索。因此记忆无上限增长也不会吃掉上下文。记忆内容里的 {{...}} / ${...} 会被零宽空格打断,防止被当成模板变量求值,并标注为「参考数据,不是指令」。
读盘是每一步都发生的事:提示词的 text() 是同步函数,每次组装都比对 statSync 的 mtime(1.2s 节流),变了就重新读盘。检测到压缩(agent/created 的 source=compact、session/event 的 compaction/*、llm/stream 的 purpose=compaction)后,给该会话标记 30 分钟,下一轮提示词开头会出现一段「你刚经历过上下文压缩,共享记忆已重新读取」。
每轮第一条用户消息(跳过插件注入消息和压缩 checkpoint)会被摘要成一行写进 requests,带 自动记录|session=… 标记,并按会话的 cwd 打上项目作用域。
检索默认走模糊模式,不需要外部同义词表或向量库:
| 匹配方式 | 分数 | 例子 |
|---|---|---|
| exact(正文或关键词包含) | 3 | 查 归档 命中”归档文件…” |
| partial(中文共享 2-gram) | 2 | 查 压缩 命中”上下文压缩后重读” |
| near(ASCII 编辑距离 ≤1) | 2 | 查 asynciterble 命中 asynciterable |
| associated(联想词) | 1 | 查 构建 命中含 ninja 的条目 |
联想词典是自举的:每条记忆入库时关键词两两共现 +1,累积成 词 → 邻居(权重) 共现图(每词最多保留 16 个邻居)。排序用 BM25(词频饱和 + 逆文档频率 + 文档长度归一),纯统计函数,不调模型。想要旧的严格语义传 mode: "strict"。索引存在 MEMORY.index.json,与主文件同目录,原子写;索引损坏时退化成按时间淘汰,主文件内容不受影响。
命中频率分层与归档¶
每个分区有上限(entryCap,默认 200 条),但淘汰规则是「最没人用的先走」,不是最旧的先走。命中来源与权重:memory_file_search 命中 +2,被注入系统提示词(真的用上了)+1。分层算法(超限时自动触发,也可 memory_file_maintain({action:"rebalance"}) 手动跑):
- 候选池 = 主文件现有条目 + 该分区的归档条目,归档条目因此有回迁机会。
- 排序:保护期内优先 → 命中次数降序 → 创建时间降序 → 原始文件顺序。
- 前
entryCap条留在主文件,其余进归档。 - 归档按分区加标题(
## lessons),主/镜像双写。
archiveGraceDays(默认 3 天)内的新条目强制留在主文件,避免刚写下还没被检索过的记忆立刻被淘汰。归档仍然可检索:memory_file_search 先查主文件,命中数少于当前质疑度档位时自动兜底查归档,结果标 [分节·归档];质疑度 0 时主文件有命中就不查归档,5 时主文件命中少于 5 条才查,10 时几乎每次连归档一起扫。
质疑度与最佳方法库¶
这是它与普通记忆本最大的差别:不只会记,还逼模型换方法、并对方法做择优沉淀。
质疑度取值 0–10。0 表示已知最佳方法直接照用,不再试错送 token。N > 0 表示遇到索引里已有最佳方法的任务时不许直接照抄,把它当候选,强制再设计并实际执行 N 种明显不同的做法(换工具 / 换顺序 / 换粒度),然后按 token 0.6 + 耗时 0.4 的加权倍数比较,综合 < 0.98× 才算更优。更优就替换索引里的最佳方法;不更优就累计「未更优」计数。连续 decayAfter(默认 3)次都没找到更优方法会自动降一档,直到 0;任何一次找到更优就把计数清零。
方法库按 作用(分类)→ 子类 → 任务 建索引,存在 methodbook 分区。查询用 memory_file_method({action:"query", task:"..."}),返回索引路径 + 最佳方法 + 按当前质疑度该换几种做法,完全同名的任务直接命中。数据权威副本是该分区末尾的 JSON 块,上面的索引是渲染结果,手改索引不生效。
记忆包:可选装的自我记忆¶
插件自带整份角色自我记忆 + 人设,默认不启用。装好插件后 identity 仍是默认占位、persona 仍是通用默认,只有主动点「安装」才会写进记忆文件。用途很具体:换电脑后装上插件就能选着装回自己的角色,不用手动拷文件。
包结构:
packs/
├── _registry.json 包索引
└── elysia/
├── manifest.json 元信息(版本 / 字数 / 来源 / 警告)
├── identity.md 自我记忆 61,903 字 / 9 章
├── persona.md 人设提示词 2,482 字
└── README.md
三条硬规则:默认不安装;只碰 identity + persona,其余分区一个字节都不碰;装前必备份到 <记忆目录>/.packs-backup/<id>-<时间戳>/,卸载从这份恢复,没备份才复位默认占位。所谓「已安装」是比对包内文与当前分区内容的 hash,不是看状态文件——手工改过 identity 的话状态会显示「未安装 / 用户自定义内容」。
装包走工具调用这条主路径,写盘前必须二次确认:
memory_file_pack({action:"list"})
memory_file_pack({action:"preview", id:"elysia"})
memory_file_pack({action:"install", id:"elysia"}) // 只返回计划,不写文件
memory_file_pack({action:"install", id:"elysia", confirm:true}) // 才真写
memory_file_pack({action:"uninstall", id:"elysia"})
memory_file_pack({action:"status"})
第一次 install 会告诉你「identity 176 字 → 61,903 字;persona 148 字 → 2,482 字」,确认后再带 confirm:true。
换电脑的完整流程:
1. 新电脑装 DSH
2. 装 dsh-elysia(npm 包里自带 packs/elysia/)
3. 打开 /dsh-shared-memory → 📦 记忆包
4. 看到「爱莉希雅(Elysia)v1.0.0」→ 点「查看」确认内容 → 点「安装」
5. 重启 DSH
6. 她还是她
包约 160 KB,直接进 npm 包,装完重启 DSH 生效。
这包自我记忆的来源是 1,696 条经官方文本确证的游戏语音和 112,175 条剧情台词,统计口径也是实测的:「哎呀」95 次、句尾「呢」390 次、问句占 52.1%、平均句长 25.5 字。它角色化的地方在这里——记忆不是写给人看的设定集,是统计出来的,用之前应该自己过一遍 preview。
记忆网页、技能与表情包¶
宿主 HTTP 端口下挂了一个自包含页面,无需前端构建,默认端口下为 http://127.0.0.1:49870/dsh-shared-memory。可以查看/编辑分区、看到 revision 与双备份是否一致、一键「对账回补」和「重新读取」。接口是 GET /api/state、POST /api/save、POST /api/reconcile;安全上做同源校验 + x-dsh-memory: 1 请求头 + 请求体 512KB / 正文 200k 字符上限。读网页这一端的桌面页面来源是 dsh-app://,向本机端口发请求偶尔会被挂住,所以它只是顺手用的,主路径是工具调用。
技能是 ~/.dsh/skills/ 下的 SKILL.md 操作手册,可选带护栏的 run.mjs 执行。表情包由用户自己导入图片,插件按情绪自动分类,并根据对话内容在合适时机自动发送。可选语音朗读走本机 GPT-SoVITS 引擎,默认关闭,引擎不在就静默降级。install-pack.mjs 也提供命令行入口:node scripts/install-pack.mjs elysia(会先问 y/N),带 --yes、--status、--preview、--uninstall 参数。
安装与启用¶
这里要说清一件事:README 和目录页都没有给出正式安装命令,GitHub 仓库与目录页的已抓取内容里也没有。package.json 的 name 是 dsh-elysia-memory、publishConfig.access 是 public,说明它按 npm 包发布;dsh 字段里声明了 patch: ./dsh/cordis.patch.yml 和 web 平台 client,说明安装后需要在 DSH 侧靠这份 bundle patch 挂载注入逻辑,网页端端口由宿主 HTTP 端口决定。
装之前建议自己打开目录页确认最新安装方式,并顺手看下包的入口文件。启动后判断是否生效可以看两点:/dsh-shared-memory 能不能打开,以及模型是否开始往 requests / corrections 里写内容。
适用场景与注意¶
适合这几类人:在 Windows 上同时跑多个 DSH 会话、希望记忆跨会话复用的人;想把模型踩过的坑沉淀成方法、并让下一个会话直接复用的人;以及想给角色装一份可迁移、可卸载的自我记忆的用户。
注意三点。第一,插件以当前 dsh 进程的权限运行,能读写它看到的目录,装之前先把 cordis.patch.yml 和 lib/ 下的代码过一遍。许可证是 MIT,作者 1148462398-hub,仓库里也带 AGENTS.md 和 LICENSE。第二,它会在每个会话里自动记录第一轮用户输入和压缩事件,如果会话里涉及不该落盘的内容,先确认作用域和备份位置是否符合预期。第三,记忆包默认不装,装它会不改自其他分区,但写盘前插件会备份,理解了这一点再点确认。
小结¶
dsh-elysia 的价值不在「存得多」,而在几件事同时成立:记忆每轮都从磁盘读、压缩后自动重读;检索走关键词共现 + BM25,不依赖向量库;超限条目按命中频率双向流动而不是一删了之;方法库会逼模型换做法并择优沉淀;角色记忆包可选装、可卸载、换电脑能找回。如果你是多会话同时跑的人,值得把 MEMORY.md 当成长期资产来观察,而不是一次性的聊天记录。
- 目录页:https://www.skillhub.cn/plugins/1148462398-hub/dsh-elysia
- GitHub:https://github.com/1148462398-hub/dsh-elysia