Skip to content
dsh.fish
Bundle

dsh-her-memory

DSH 全局长期记忆 + 心情状态插件:六个工具、纯 Markdown 存储、零依赖、工作区可选隔离

Source
KZADEA
License
MIT
Updated
Updated 7 days ago

Readme

# 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`:

```yaml
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):

```powershell
dsh plugin --profile desktop add link:D:\dsh-her-memory
```

然后重启 DSH。重启后:
- **模型会换上默认人设**(自带的那只鲸鱼女仆)并**称呼你为「主人」** —— 想改就编辑 `人设文件.txt`,想彻底关掉就把它的正文清空(见上面「人设」一节)
- 系统提示里会多一段「你有长期记忆」的说明(固定不变)
- 每轮对话会插一条独立的注入消息(带 `【her-memory|系统注入,非用户消息】` 前缀,用户自己发的话不会被追加任何东西)

**卸**:

```powershell
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`**。

Install

dsh plugin --profile web add github:KZADEA/dsh-her-memory

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source