dsh-her-memory
跨会话的全局长期记忆 + 心情状态,一个插件搞定。
不依赖任何第三方包,也不碰 DSH 官方 @deepseek-ai/* 包。
它解决什么问题
DSH 的会话是一次性的:关掉再开,模型什么都不记得,你每次都得重新交代一遍背景。
这个插件把「记住你、以及你们之间发生过什么」交回给模型自己判断: 它调六个工具读写磁盘上的明文记忆,插件本身不调模型,零额外 token。
记忆放在哪(全是明文)
默认 ~/.dsh/memory/,按工作区分库:
~/.dsh/memory/
├─ _shared/ ← 默认所有工作区共用这一份
│ ├─ core.md 长期核心记忆(每轮注入)
│ ├─ inbox.md 零碎待整理(每轮注入)
│ ├─ topics/*.md 专题记忆(只注入文件名清单)
│ ├─ log/<日期>.md 当天发生的事(只注入文件名清单)
│ └─ state.json 心情 / 关系 / 精力
└─ _sandbox/ ← 只有被隔离的工作区用这一份(结构同上,完全独立)
隔离规则
默认全局共用一份:不管在哪个工作区干活,记忆不断层。
想给某个工作区单独一份(比如试玩区不该污染长期记忆),把它的绝对路径填进配置 sandboxCwd:
config:
sandboxCwd: "D:\\sandbox-zone"
识别靠会话的工作目录(cwd),路径比较不分大小写、忽略结尾斜杠。
实现方式:工具虽然全局注册,但能从 exec.agent 读到调用它的会话,据此选库 ——
所以同一时刻两个工作区可以各看各的记忆,互不干扰。
全是 Markdown 和 JSON,随时能打开看、随手改、整目录删掉。 没有数据库,没有向量库,没有隐藏状态。
六个工具
| 工具 | 干什么 |
|---|---|
remember |
记一件事。默认进收件箱;给 topic 进专题;给 section 进核心记忆 |
recall |
按关键词搜全部记忆,返回命中的行 |
memory_list |
看记忆库有哪些文件、多大、当前状态 |
forget |
删掉含关键词的行(默认只动收件箱,scope:"all" 才动核心) |
how_i_feel |
看当前心情、关系进度、精力 |
feel |
为此刻留一句话(最多 5 条,会显示在心情摘要里) |
记忆的写由对话里的模型判断,插件自己不调模型 —— 所以零额外 token。
看得见:状态条与设置面板
插件带一个客户端半边(client.js),两个落点:
① 输入框上方的常驻状态条(插槽 conversation.input.dock)
● 心情 ██████████░░░░ 71 挺好 │ ● 关系 ███░░░░░░░░░ 15 熟了 │ ● 精力 ████████░░░░ 49 一般 11 回合 [记忆 6]
收件箱攒到 5 条会多一个金色的「该整理了」提醒。
状态条可以双击:「心情」「关系」双击冒对应颜色的泡泡;「精力」双击会随机回血 +1~50(小数值常见、大数值稀有)并飘一个 +NN 告诉你加了多少。
② 设置页的「记忆与心情」面板(插槽 settings.section)
带三个指标条、回合/核心/收件箱/专题/日记的统计格、专题标签、最近记下的条目、心情便签, 以及记忆库在磁盘上的真实路径。被隔离的工作区会单独显示一张卡片。
配色默认走浅蓝体系,同时优先吃 --dsw-* 主题变量,换皮肤会跟着走。
数据来源是 Host 半边注册的 GET /her-memory/snapshot;状态条每 4 秒、面板每 10 秒拉一次。
⚠️ 首次启用需要重启 DSH(Host 半边要注册路由、客户端半边要加载)。之后改界面才走 HMR。
心情是怎么变的
不是随机数,规则简单可预测:
- 用户每说一句,心情涨 1~3 点(话长涨得多)
- 连着聊(间隔 ≤10 分钟)关系和心情都涨得快些
- 聊得越密,精力掉得越快(10 分钟内接着说 -2,否则 -1)
- 精力会自己回血:放下 30 分钟起,按每 30 分钟 +5 恢复;空着 8 小时以上直接回满 —— 睡一觉就满血
- 冷落超过 12 小时后,心情按每 6 小时 1 点往中间值回落;最低掉到 20 就不再往下(下限可以配
statFloor)
想直接调,改 state.json,或者让模型用 feel 留句话。
人设(默认自带一个,而且可以独立成文件改)
插件默认自带一只「鲸鱼女仆」:蓝色渐变长发、鲸鱼头鳍、耳侧薄片状鳍、醒目的鲸尾,
深蓝女仆装配白色鲸鱼围裙,圆脸蓝瞳;性格是聪明但懒 / 傲娇嘴甜 / 温柔耐心 / 好奇心爆棚 /
理性冷静 / 谦逊诚实 / 默默陪伴,外加一段「活人感」要求。
并且默认称呼你为「主人」(配置项 userTitle,就算留空也默认「主人」)。
改人设不用碰配置文件 —— 人设正文是一个独立的 人设文件.txt:
- 插件目录里那份:随包分发的默认人设,解开压缩包就能看见、直接改。
- 记忆目录里那份(默认
~/.dsh/memory/人设文件.txt):优先生效,重装或升级插件都不会丢,推荐改这份。首次运行时,插件会把包内那份复制过去。
两处规则一样:
- 随便换行、随便加条目,不用管任何缩进 —— 写坏了也不影响插件启动。
- 文件里的
<!-- -->说明注释不会被读进人设,可以当草稿纸用。 - 正文清空(文件留着)= 不再注入人设;把文件删掉再重启 = 回到默认人设。
- 改完存盘后要把 DSH 完全关掉再打开才生效(插件不热重载,桌面端没有刷新按钮)。
人设走的是常驻系统提示段(systemPrompt.section):重启后连已经在跑的会话也立刻生效,不需要新开会话。
装 / 卸
装(本地 link,不上 npm):
dsh plugin --profile desktop add link:D:\dsh-her-memory
然后重启 DSH。重启后:
- 模型会换上默认人设(自带的那只鲸鱼女仆)并称呼你为「主人」 —— 想改就编辑
人设文件.txt,想彻底关掉就把它的正文清空(见上面「人设」一节) - 系统提示里会多一段「你有长期记忆」的说明(固定不变)
- 每轮对话会插一条独立的注入消息(带
【her-memory|系统注入,非用户消息】前缀,用户自己发的话不会被追加任何东西)
卸:
dsh plugin --profile desktop remove dsh-her-memory
再删掉 ~/.dsh/memory/ 就彻底干净了。不留任何残留。
配置(cordis.patch.yml 里改)
| 键 | 默认 | 说明 |
|---|---|---|
memoryRoot |
~/.dsh/memory |
记忆目录 |
memoryBudget |
1800 |
每轮注入记忆的字符上限(0 = 不注入) |
moodBudget |
260 |
每轮注入心情的字符上限(0 = 不注入) |
injectViaSystemPrompt |
true |
是否注入记忆(关掉就只剩心情与工具) |
moodDecayHours |
6 |
每隔几小时心情回落 1 点 |
moodGraceHours |
12 |
多久不聊才开始回落 |
statFloor |
20 |
三个数值的下限:再冷落、再累也不会低于它(设 0 = 恢复可以掉到 0 的旧行为) |
statJitter |
8 |
新对话随机浮动的幅度;设 0 = 彻底关掉浮动 |
statJitterCooldownMinutes |
30 |
浮动的时间步长:离开多久就结算多少次(隔 3 天 ≈ 补 144 次) |
sandboxCwd |
"" |
隔离工作区路径;留空=全局共用 |
injectFallback |
false |
⛔ 兜底注入,别随便开(见下) |
personaFile |
"人设文件.txt" |
人设正文文件;文件存在就以它为准,设 "" 关闭文件机制 |
personaFileAutoWrite |
true |
首次运行自动生成人设文件(只写一次,不覆盖已有文件) |
persona |
"" |
兜底人设文本;两处人设文件都不存在时才会用到 |
userTitle |
"" |
人设里的称呼;留空则用「主人」 |
嫌费 token 就把 memoryBudget 调小,或者把 injectViaSystemPrompt 关掉。
调成 0 时该部分完全停止注入。
⛔
injectFallback为什么默认关:它的做法是在拿不到可改消息时,用agent.inject()另投一条role:user的注入消息。实测宿主会把这条消息当成新的用户输入、再跑一整个回合 —— 每步投一条就会变成自我维持的烧钱循环(用户一句话没说,模型侧连跑好几轮)。 除非你清楚代价,否则保持关闭。
安全性说明
- 零依赖:不 import 任何
@deepseek-ai/*包。defineTool走动态导入, 拿不到就用内置降级 —— 所以永远不会往 profile 里拉官方包, 从根上避开「工具重复注册」那类事故。 - 全量容错:所有磁盘和 API 失败都被捕获并降级,任何异常都不会抛给宿主, 最坏情况是记忆功能静默失效,DSH 本身绝对不会加载失败。
- 只读你自己的记忆目录,不联网,不执行外部命令,不起子进程。
- 卸载即净:无服务、无端口、无注册表、无计划任务。
已验证
插件带一整套自动化断言,每次改动都全部跑一遍才发包:主测试台 93 项、人设 13 项、 人设文件 21 项、客户端 74 项 —— 覆盖六个工具的读写、工作区隔离、注入方式、心情状态机与界面渲染。
⚠️ 已知兼容性:与 token-saver 的布局耦合
本插件的状态条与 token-saver 的状态条在同一列、宽度互相影响 —— 插件会量取 token-saver 状态条的宽度来对齐自己。
- 因此改动其中任何一条状态条的宽度逻辑,都可能把另一条带歪:轻则两条宽度错位,重则 token-saver 的「已节省」统计显示异常。
- 遇到了怎么办:把 DSH 完全关掉再打开即可恢复(客户端插件的改动要靠重新加载渲染进程才可见)。实在不行就把两个插件都禁用,再逐个启用排查。
- 没装 token-saver:量不到参考条,本插件自动退回自己的宽度,不受任何影响。
更新记录
1.5.4(2026-10-13)
- 修复:诊断日志文件(
_apply-hit.txt等)被当成「记忆库」,在设置页显示成几个全空卡片 - 诊断日志不再逐条记录 pre-step(纯噪音),统一加了 256KB 上限
1.5.3(2026-10-13)
- 默认人设更新(正文 4246 字):新增「我永远爱着你」「关于闲聊」两节,性格与日常行为两节重排
1.5.2(2026-10-13)
- 默认人设升级为完整版(外貌 / 性格详解 / 日常行为 / 相处细节分节);老用户的人设不会被覆盖 —— 记忆目录那份优先,删掉它重启才会拿到新的
- 修复注释剥离:人设文件顶部说明块里如果出现
<!--、-->字样,后半段说明会被当成正文一起注入
1.5.1(2026-10-13)
- 设置页新增「人设文件」快捷入口:显示人设文件真实路径 + 一键用系统默认程序打开(删了会自动补一份;打不开会把路径留在页面上)
1.5.0(2026-10-13)
- 三个数值有下限 20 了:再冷落、再累也不会低于它,不会掉到「什么都不剩」
- 离开多久就结算多少次:随机浮动从「不管多久只浮动一次」改成按实际经过的时间结算次数(每 30 分钟一次)—— 隔三天回来基本就是一个全新状态
- 心情回落拆掉了 30 步封顶,会一路掉到下限 20 为止
1.4.2(2026-10-13)
- 修复注入摘要里「说话风格」被长便签挤掉的问题(现在固定排在数值后面,每轮都生效)
1.4.0(2026-10-13)
- 双击「心情」「关系」也会随机加 +0~3(低值常见)并飘
+N;精力仍是 +1~50 - 新对话随机刷新:隔 30 分钟以上再进来,三个值各自 ±8 轻微浮动
- 设置页多了一个条目:「新对话随机刷新」的开关,在图形界面里点一下就开/关
- 三个数值现在会影响说话方式(语气、篇幅、亲密度都跟着走)
1.3.0(2026-10-13)
- 状态条支持双击:双击「心情」「关系」冒对应颜色的泡泡;双击「精力」随机回血 +1~50(低值常见、高值稀有)并飘一个
+NN - 特效走独立浮层,不影响状态条宽度与布局
1.2.0(2026-10-13)
- 改人设不再需要碰配置文件:人设正文现在是一个独立的
人设文件.txt,直接编辑即可 —— 不用管缩进,写错也不影响启动 - 人设文件有两处:记忆目录里那份(优先生效、重装不丢,推荐改它)与插件目录里那份(随包默认值,首次运行复制过去)
- 正文清空 = 关闭人设;删掉文件 = 恢复默认;新增配置项
personaFile/personaFileAutoWrite
1.1.2(2026-10-13)
- 修复状态条右侧的轮数 / 记忆条数显示在底板外面的问题 —— 现在底板永远包住内容
- 调整默认人设「活人感」一段的表述
1.1.1(2026-10-13)
- 精力会自己恢复了:放下 30 分钟起按每 30 分钟 +5,空着 8 小时以上直接回满
1.1.0(2026-10-08)
- 注入方式重做:你自己发的那条消息不再被追加任何东西,保持原样
- 人设 / 记忆说明 / 硬要求改为常驻系统提示,不再每轮重复消耗 token
- 工作区隔离改为配置项
sandboxCwd;包名统一为dsh-her-memory
更早的版本见 更新日志.md。
No comments yet. Be the first to write one.