Bundle
@yansera/dsh-living-memoir
Long-term memory for DeepSeek Harness: a short, categorized Markdown living document that gets rewritten instead of appended to, with a dedicated Web GUI page.
- Source
- Yansera
- stars
- 2 stars
- License
- MIT
- Updated
- Updated 3 days ago
Readme
# 记忆册 · Memoir
[English](README.en.md) · [Français](README.fr.md) · [Deutsch](README.de.md) · [日本語](README.ja.md) · **简体中文**
[](https://github.com/Yansera/dsh-living-memoir/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@yansera/dsh-living-memoir)
[](LICENSE)
DeepSeek Harness 的跨会话记忆插件。记忆存成一组 Markdown 文件,每轮对话结束后整个重写一遍,而不是往后追加。

## 📦 安装
```sh
dsh plugin --profile desktop add @yansera/dsh-living-memoir
```
`desktop` 换成你的 profile 名。`dsh` 是 DeepSeek Harness 自带的 CLI,桌面版在 `<安装目录>\resources\runtime\cli\bin\dsh.cmd`。
从源码装:
```sh
dsh plugin --profile desktop add 'file:D:\path\to\dsh-living-memoir'
```
装完要完全退出客户端再打开。DSH 只在安装插件那一刻加载代码,关窗口不算退出。
## 🚀 用起来是什么样
侧边栏会出现「记忆册」,点开占满主区域:左边是分类,右边是条目。左上角「← 返回对话」回到会话。
之后不用配置。模型在你说出持久偏好、定下决策、纠正它的时候会自己写;你也可以点「记一条」,或者直接编辑 `$DSH_HOME/memoir/` 下的 md 文件,改完刷新页面就能看到。
想让它停下来,页面右上角设置里关掉「记忆写入」。关掉之后不读也不写。
## 🧱 三层结构
```
# 在做的事
<!-- 项目、当前阶段 · 可直接手工编辑 -->
## 记忆册
- 把跨会话记忆整理成分类简短的 md 活文档
<!-- memoir id=a1b2c3d4 | imp=4 | conf=high | at=2026-10-07 | src=用户明确说 -->
## 修仙:进化网络
- 用基因突变与自然选择长出承载语义的拓扑
```
第一层是分类,一个分类一个 md 文件。第二层是小节,通常一个项目一个。第三层是条目,一条一句话,到此为止。
分类按主题划分,不按信息类型。找东西的时候人想的是「这是哪个项目」,不是「这算决策还是算进展」。同一个项目的一切都收在它自己的小节里。
分类的数量和结构由模型按内容决定,没有固定清单。装好时会铺五个起头分类,用不着就删。某一类条目太多,或者里面其实是两件不搭的事,模型会把它拆开。
## ✍️ 三种写入方式
模型工具:模型判断什么值得记,调用 `memoir_note` 写进去,`memoir_recall` 和 `memoir_forget` 用来查和删。
页面手写:点「记一条」,或者直接编辑 md 文件。
自动改写:每轮对话结束、安静 20 秒后,后台把整本读一遍,交出改写后的完整版本。
前两种是追加,第三种是重写。重写才是这套东西的核心,它保证文档不会只涨不消。
## 🔄 自动改写
模型的输入是「记忆册现在的全部内容」加上「这段新对话」,要交出的是改写后的完整版本。合并、删减、改写、新增都在这一步发生。
几条防呆:
- 按会话存游标,只消费上次之后的新事件,同一段不会被反复改写
- 失败不推进游标,下次轮次结束会重试同一段
- 新内容少于 400 字符就跳过,但游标照常推进
- 多个会话同时收尾时请求排队,不会一拥而上
- 解析不出分类就什么都不写;条目总数骤减一半以上(原本不少于 6 条时)直接拒绝这次改写
每条记忆带两个标记。`conf` 是置信度:用户亲口说的是 `high`,从对话里提炼的是 `med`,模型自己推断的是 `low`;要腾地方时先丢 `low`。`pin` 表示钉住,标了它的条目改写时必须原样保留,一篇里最多三五条。
## ⚙️ 设置
页面右上角的齿轮。改动存在记忆库目录的 `.settings.json` 里,跟记忆数据放一起,换 profile 不丢。
写入总开关关掉之后,记忆不再注入提示词、三个工具拒绝执行、页面和 HTTP 写入返回 403、自动改写停止。
改写用的模型从宿主已注册的列表里选。插件调用 `ctx.llm.listProviders()` 和 `ctx.llm.listModels(provider)` 把可选项列成下拉,不用自己填 provider 名和模型 id。DSH 里关联好的模型,不管是自带的、本地的还是第三方 API,都会出现在那里。下拉下面也留了手填的位置。
思考程度默认关闭。改写是整理不是解题,实测思考型模型会把输出预算烧在推理上,正文一个字都吐不出来。
界面语言和记忆语言是两个开关。前者换按钮和标签,后者决定存进 md 的字用哪种语言,包括分类名和小节名。两个都默认英文。
## 🔧 配置
部署级配置走 `cordis.patch.yml`:
```yaml
- id: memoir
name: '@yansera/dsh-living-memoir'
config:
memoryDir: '' # 留空 = $DSH_HOME/memoir
injectIndex: true # 是否把记忆目录注入系统提示词
maxInjectEntries: 12 # 最多注入几条
autoDistill: true # 每轮结束自动改写
distillDebounceMs: 20000 # 改写前的安静等待(毫秒)
distillMinChars: 400 # 少于这么多字符就跳过
distillMaxItems: 60 # 整本条目上限
distillMaxTokens: 8000 # 输出预算下限,会按记忆规模自动往上抬
distillReasoningEffort: off # 改写不需要推理
memoryLanguage: '' # 记忆内容语言;留空 = 不限制
pageEntryLimit: 12 # 单类超过这么多条触发强制整理
bookEntryLimit: 40 # 整本超过这么多条触发强制整理
```
改完要重启,跟代码改动一样。
## 📂 文件长什么样
一个分类一个 md 文件,纯文本,可以用任何编辑器打开,也可以进版本控制。没有数据库,没有缓存,没有私有格式。
条目的元数据写在 HTML 注释里,不影响阅读:
```
- 用户要求所有下载前先问,并说清多少 GB
<!-- memoir id=8daa8849 | imp=5 | conf=high | at=2026-10-09 | src=用户明确说 | pin -->
```
手工加一行 `- 内容` 就等于加一条记忆。解析器只认三种行:`# 分类`、`## 小节`、`- 条目`,其余全部忽略。
## ❓ 常见问题
**和别的记忆方案冲突吗。** 不冲突。记忆册只管长期宏观那一层:用户是谁、助手是谁、在做什么、定过什么大方向决策。短期与过程性的内容,比如技术细节、踩坑记录、进度流水,不归它管,也不会写进来。数据存在自己的目录里。
**会越记越多吗。** 不会。它是被改写的,长度由内容决定而不是由历史决定。分类超过 12 条或整本超过 40 条会触发强制整理。
**记忆被改错了怎么办。** 每个分类的 md 文件都可以直接改,改完刷新页面就生效。模型下次改写会尊重你改过的分类名。重要条目可以标 `pin` 钉住。
**会外发数据吗。** 不会。插件不主动发起任何网络请求,改写用的是宿主自己的 `llm` 能力。
**能把记忆带走吗。** 能。整个记忆库就是一个目录,拷走就行。
## 🛠 开发
```sh
npm test # 全部 259 项离线自测
npm run test:store # 存储层:解析、去重、移动、搜索、注入文本
npm run test:plugin # host 端:注册面、工具执行、系统提示、HTTP 路由
npm run test:client # 页面半:用 React 替身渲染真 bundle
npm run test:distill # 自动改写:输出解析、防抖、游标、失败重试
```
测试全部离线,不依赖 DSH 宿主,也不碰任何真实 profile。
改完源码之后(Windows):
```powershell
& .\scripts\sync.ps1
```
pnpm 用 `file:` 装本地包时是硬链接,编辑源码会断开链接,安装位置的副本不再更新,所以必须同步再重启。
目录结构:
```
src/ 实现本体(index = host 半,distill = 自动改写,client = 页面半)
test/ 离线自测
docs/ 设计与格式说明
scripts/ 同步脚本、对着运行中客户端的冒烟测试
```
细节见 [CONTRIBUTING.md](CONTRIBUTING.md) 和 [docs/](docs/):[设计说明](docs/design.md)、[存储格式](docs/storage-format.md)、[配置](docs/configuration.md)。
## 📄 许可
[MIT](LICENSE) © Yansera
Install
dsh plugin --profile web add github:Yansera/dsh-living-memoir
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install yansera-dsh-living-memoir from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.