🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

记忆库 xying-lm/dsh-memory-vault

DeepSeek Harness
xying-lm14 天前有提交已提供中文文档扫描:含敏感能力

自动沉淀对话要点,按需检索注入历史记忆

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add xying-lm/dsh-memory-vault
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · chat
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 14 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 27 处,展示前 27 条)
  • 读取本地文件
    lib/index.js:67
    const parsed = JSON.parse(readFileSync(locationSidecar(), 'utf8'))
  • 读取本地文件
    lib/index.js:81
    if (existsSync(path) && statSync(path).size > 512 * 1024) writeFileSync(path, '')
  • 读取本地文件
    lib/index.js:81
    if (existsSync(path) && statSync(path).size > 512 * 1024) writeFileSync(path, '')
  • 写入本地文件
    lib/index.js:81
    if (existsSync(path) && statSync(path).size > 512 * 1024) writeFileSync(path, '')
  • 写入本地文件
    lib/index.js:82
    appendFileSync(path, `${new Date().toISOString()} pid=${process.pid} ${message}\n`)
  • 读取本地文件
    lib/index.js:345
    if (existsSync(diagPath) && statSync(diagPath).size > 512 * 1024) writeFileSync(diagPath, '')
  • 读取本地文件
    lib/index.js:345
    if (existsSync(diagPath) && statSync(diagPath).size > 512 * 1024) writeFileSync(diagPath, '')
  • 写入本地文件
    lib/index.js:345
    if (existsSync(diagPath) && statSync(diagPath).size > 512 * 1024) writeFileSync(diagPath, '')
  • 写入本地文件
    lib/index.js:346
    appendFileSync(diagPath, `${new Date().toISOString()} pid=${process.pid} ${message}\n`)
  • 发起网络请求
    lib/client.js:43
    return fetch(API + path, { method: 'GET', headers: { accept: 'application/json' } }).then(function (res) {
  • 发起网络请求
    lib/client.js:51
    return fetch(API + path, {
  • 读取本地文件
    lib/panel.js:124
    if (options.sidecar && existsSync(options.sidecar)) rmSync(options.sidecar, { force: true })
  • 删除本地文件
    lib/panel.js:124
    if (options.sidecar && existsSync(options.sidecar)) rmSync(options.sidecar, { force: true })
  • 写入本地文件
    lib/panel.js:140
    mkdirSync(dirname(target), { recursive: true })
  • 写入本地文件
    lib/panel.js:142
    if (current && existsSync(current) && !existsSync(target)) copyFileSync(current, target)
  • 读取本地文件
    lib/panel.js:142
    if (current && existsSync(current) && !existsSync(target)) copyFileSync(current, target)
  • 读取本地文件
    lib/panel.js:144
    if (current && existsSync(current + suffix) && !existsSync(target + suffix)) {
  • 写入本地文件
    lib/panel.js:145
    copyFileSync(current + suffix, target + suffix)
  • 写入本地文件
    lib/panel.js:148
    writeFileSync(options.sidecar, JSON.stringify({ dbPath: target }, null, 2) + '\n', 'utf8')
  • 读取本地文件
    lib/panel.js:312
    custom: Boolean(options.sidecar && existsSync(options.sidecar)),
  • 写入本地文件
    lib/store.js:478
    mkdirSync(dirname(dbPath), { recursive: true })
  • 写入本地文件
    lib/store.js:978
    mkdirSync(target, { recursive: true })
  • 写入本地文件
    lib/store.js:997
    writeFileSync(
  • 读取本地文件
    lib/store.js:1067
    if (!existsSync(thread.path)) {
  • 写入本地文件
    lib/store.js:1068
    mkdirSync(dirname(thread.path), { recursive: true })
  • 写入本地文件
    lib/store.js:1069
    writeFileSync(thread.path, `# ${thread.title}\n\n`)
  • 写入本地文件
    lib/store.js:1071
    appendFileSync(thread.path, `### ${new Date(ts).toLocaleString('zh-CN')} · ${who}\n\n${text}\n\n`)
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

给 DeepSeek Harness 加 5GB 本地长期记忆:SQLite/FTS5 自动捕获、每轮对话注入召回、网页面板,零运行时依赖。

README

由 DeepSeek 最新模型翻译生成
dsh-memory-vault 给 DeepSeek Harness 加一个跨会话的本地长期记忆库:把你说过的话、助手答过的要点自动沉淀进 D 盘的一个 SQLite 文件里,每轮对话前按需检索一小段相关历史注入提示词,并用一个 Web 面板让你看到它到底占了多少空间。 零运行时依赖——只用 Node 24 内置的 node:sqlite(FTS5 trigram),不需要 npm install,不需要下载向量模型。 记忆库面板 示意图,所有标题/会话 id/数字均为虚构示例。真实面板的外观由 lib/client.js 决定,可直接读源码。 它突破了什么,没突破什么 没突破:模型一侧的上下文窗口是硬上限,约 128K token(≈ 20 万汉字),这个数字由模型决定,插件改不了。 5GB 文本约 25 亿汉字 / 12.5 亿 token,是窗口容量的一万倍——「把这 5GB 一次全塞进上下文」在任何实现里都不存在。 突破了:把「窗口里能放下多少」换成「窗口里能取到多少」。
展开完整文档(README 剩余 1 节)
dsh-memory-vault

给 DeepSeek Harness 加一个跨会话的本地长期记忆库:把你说过的话、助手答过的要点自动沉淀进 D 盘的一个 SQLite 文件里,每轮对话前按需检索一小段相关历史注入提示词,并用一个 Web 面板让你看到它到底占了多少空间。

零运行时依赖——只用 Node 24 内置的 node:sqlite(FTS5 trigram),不需要 npm install,不需要下载向量模型。

记忆库面板

示意图,所有标题/会话 id/数字均为虚构示例。真实面板的外观由 lib/client.js 决定,可直接读源码。

它突破了什么,没突破什么

没突破:模型一侧的上下文窗口是硬上限,约 128K token(≈ 20 万汉字),这个数字由模型决定,插件改不了。
5GB 文本约 25 亿汉字 / 12.5 亿 token,是窗口容量的一万倍——「把这 5GB 一次全塞进上下文」在任何实现里都不存在。

突破了:把「窗口里能放下多少」换成「窗口里能取到多少」。库里任意一条记忆都取得到,而每取一次只花一两千字:

| 层 | 手段 | 一次花多少 |
| ⓪ 压缩(只在新会话第一轮) | 每个过去会话压成两三行要点,一次注入 | 6 个会话约 900 字,只付一次 |
| ① 自动召回 | 每轮注入 3~5 条相关摘录,每条带 id= | 约 1500 字预算,可配 |
| ② 换词重搜 | memory_search 换关键词 / 加 offset 翻页 | 每条 220 字摘要,一次最多 20 条 |
| ③ 分段读全文 | memory_open id=… chars=2400,返回里带 next 接着读 | 一次 2400 字,最多 12000 |
| ④ 先看结构 | memory_catalog 给按天 / 按会话的目录 | 十几行 |

所以 5GB 不是「塞进窗口」,而是一本可以逐页翻的书:单次访问两三千字,读 20 页就是 6 万字,相当于把窗口翻了一倍,而书架上还有 4.99GB。代价是串行:模型一次只能读一页,跨全库的「整体统计 / 全局推理」仍然做不到,要靠摘要层预先压缩(见「已知限制」)。

为什么不能靠「每次新会话都把上次的上下文读进来,于是翻倍、再翻倍」? 因为窗口大小固定,读进来的原文不会变小:一个 5 万字的会话就吃掉 1/4 个窗口,读 4 个就满了。
能真正累积的只有两种东西——被压缩过的(⓪ 层,压缩率决定能堆多少个会话)和用到才取的(①②③ 层,每轮成本恒定)。
这个插件两层都有,但两层都不是「无限上下文」:它让可检索的范围无限,不是让窗口里的字无限。

它擅长的是「我们上次说过的那个部署脚本叫什么」这类找回具体事实的场景,而不是「把你的整个人生都记住并推理」——后者是模型能力问题,不是存储问题。

安装

git clone https://github.com/xying-lm/dsh-memory-vault.git

然后在 DSH 里把它装成一个 bundle:

plugin_manager install_bundle target="file:<你的克隆路径>/dsh-memory-vault"

或直接在 GUI 里「设置 → 插件 → 安装插件」填入本地路径。

装好后重启 DSH(关窗口不算退出,托盘进程还在):插件是 generation 快照拷贝,宿主启动时只 import() 一次,没有热重载通道。

默认库文件在 D:\dsh-memory\vault.db(macOS / Linux 落到 ~/.dsh-memory/vault.db),可以在配置里改 dbPath。

七个工具

| 工具 | 用途 |
| memory_search | 在长期记忆里检索。支持中文整句当查询词,offset 可翻页。 |
| memory_open | 按 id 分段读一条记忆的全文(chars 控制每页字数,返回 next 接着读)。 |
| memory_catalog | 看库的整体目录:总条数、按天分布、最近的会话、时间跨度。 |
| memory_save | 显式记住一条(约定、偏好、关键决策)。默认长期;传 mode: "multi" 只本会话可见,mode: "once" 召回一次即删。 |
| memory_stats | 看用量:条数、占用、配额、当前档位、时间跨度。 |
| memory_resize | 改容量上限:给 gigabytes: 5 用常用档位,或 2.5 这样的自定义值(0.05~200)。立即生效、落库、重启不丢。 |
| memory_forget | 按 id 删掉一条(不可恢复)。 |

自动召回与这七个工具是两条独立的路:自动召回省事但可能漏,工具要模型主动调但问得准。两条都开着才稳。

三种记忆模式

| 模式 | 什么时候用 | 生命周期 |
| long(长期,默认) | 约定、偏好、关键决策、踩过的坑 | 永久保留,跨会话可召回 |
| multi(多次) | 「这个项目这周先这么办」这类只在本会话有效的口径 | 只在写入它的那个会话里可召回;12 小时后自动清理 |
| once(单次) | 一次性的口令、临时编号、只想说一遍的事 | 被自动召回一次就从库里删掉(连正文都不留) |

自动采集的两条配置决定「自动记下来的」算哪种:captureMode(默认 long);手动 memory_save 时由你传的 mode 决定(默认 defaultMode)。memory_stats 会显示库里三种模式各有多少条。

配置

| 键 | 默认 | 说明 |
| enabled | true | 总开关。关掉后不采集不召回,已有记忆保留。 |
| dbPath | D:\dsh-memory\vault.db | 库文件路径。换路径不会迁移旧数据。 |
| maxGB | 5 | 自定义容量(GB)。仅当 sizePreset = custom 时生效。 |
| sizePreset | custom | 常用档位 1 / 5 / 10 / 20 / 50(GB),或 custom 用 maxGB。选档位时忽略 maxGB。 |
| capture | true | 自动沉淀对话。 |
| captureAssistant | true | 连助手回复一起记。关掉只记你说的。 |
| captureMinChars | 8 | 短于此字数的消息不记(「嗯」「好的」不占库)。 |
| defaultMode | long | 手动 memory_save 不传 mode 时用哪种:long / multi / once。 |
| captureMode | long | 自动采集的消息记成哪种。设成 once 会让自动采集的记忆被召回一次就删(一般不建议)。 |
| skipSubagent | true | 跳过子代理会话,避免把中间过程记成记忆。 |
| recall | true | 每轮自动检索并注入。 |
| recallLimit | 5 | 单轮最多注入几条。 |
| recallMaxChars | 1500 | 单轮注入的字数上限(占提示词预算)。 |
| recallMinQueryChars | 4 | 输入短于此不检索。 |
| recallSameSession | true | 是否也取当前会话里更早的记忆。关掉则只跨会话召回。 |
| recallRecentWindow | 30 | 当前会话最近这么多条不参与召回(它们还在上下文里,重复注入只会挤占预算)。 |
| sessionIndex | true | 新会话第一轮注入一次「过去会话要点」(压缩层)。关掉则只靠检索按需取。 |
| sessionIndexLimit | 6 | 索引最多列几个过去会话(每个约 150 字,只在新会话第一轮付一次)。 |
| panel | true | Web 侧边面板。它会在宿主 Web 载体上新增 HTTP 面 /memory-vault/*(stats / search / recent / catalog / entry 只读,resize 是唯一的写路由且只改容量),随监听地址暴露(本机默认回环 127.0.0.1)。 |

配置非法会在加载期直接报错并指出是哪个键——不会带着错配置默默跑。

它怎么工作

对话 ──► session/event ──► 内存队列(1s 批量) ──► SQLite(mem + mem_fts) │ 下一轮输入 ──► systemPrompt.context(order=130) ──► 新会话第一轮:过去会话要点(压缩层,一次) └─► 每轮:检索 top-k(带 id)──► 注入当时的上下文

- 压缩层(sessionDigests):每个会话取最近 40 条,按「去重后的关键词数」给句子打分,挑两三句拼成要点。
纯抽取式、不调模型,所以它抓的是字面重点,不会替你归纳。压缩率大约 1/20~1/50。

几个刻意的设计决定:

- 用 context 而不是 systemPrompt.section:context 落在消息流里、每轮随对话变化,改它不会打断系统提示词的前缀缓存。
- 两层检索:FTS5 trigram 负责 3 字以上的精确子串(部署脚本、FTS5 这类),查不到时用 2 字词在「最近 2000 条」窗口内补位——中文里最常见的重合恰好是 2 字(杭州、部署),trigram 结构上做不到,但不能因此漏掉。窗口有界,所以补位不会随 5GB 线性变慢。
- 自己的输出不再入库:注入的召回块带 【长期记忆·自动召回】 标记,采集侧据此跳过。否则模型会把自己召回的内容当成用户的话再说一遍,再被记一遍,滚雪球。
- 去重靠内容指纹:同样的内容(同角色 + 同正文)全局只存一份,重复出现只累加命中计数。

Web 面板

侧栏面板图标「长期记忆」→ 中央面板,五个部分:

- 用量条:已用 / 上限(MB)、百分比、记录条数、库文件路径、最新写入时间。
- 容量上限:1 / 5 / 10 / 20 / 50 GB 五个常用档位一键切换,也能填任意自定义值(0.05~200);改完立即生效并落库,重启不会被配置文件覆盖回去,想回退点「恢复配置值」。
- 检索框:和 memory_search 走同一条检索路径,回车即查,结果显示标题 / 时间 / 角色 / 字数 / 摘录。
- 目录:按天、按会话两种切片各给一排标签(2026-10-20 · 23、会话 a147bcec · 13),点一下只看那一组,再点一下取消。库里的条目再多,也是先收窄再翻,不用滚一整天。
- 列表 + 点开全文:默认 20 条一页(按时间倒序),底部「加载更多」继续翻;每张卡片本身就是按钮 —— 点一下按需取该条全文展开(最多 320px 高、可滚动),再点收起。列表接口故意不带正文,所以翻页再快也不会把整库拖进浏览器。

数据来自宿主半边的路由:

GET /memory-vault/stats
GET /memory-vault/search?q=<词>&limit=10 GET /memory-vault/recent?limit=20&offset=0[&day=2026-10-20][&session=<id>] GET /memory-vault/catalog # 目录:按天 / 按会话的条数索引 GET /memory-vault/entry?id=<id> # 单条全文(点开卡片时才请求) POST /memory-vault/resize {"gigabytes": 10} 或 {"reset": true}

读接口只读、不读凭据;/recent 无论带不带筛选与 offset 都会回 total(面板靠它算「还有 N 条」)。唯一的写接口是 /resize,它只改容量上限,碰不到任何一条记忆内容。整块面板注册失败也只会让面板缺席,不影响采集 / 召回 / 工具。

与既有插件的关系

| 插件 | 负责 | 与本品关系 |
| billion-context | 会话内压缩 | 互补:它管窗口装不下时怎么办,本品管窗口外的东西怎么找回来 |
| dsh-recall-plugin | 消息撤回 | 无关,可共存 |

已知限制

- 检索是字面匹配(trigram + 双字词),不做语义理解。「那台跑 CI 的机器」找不到「构建服务器」,除非两者共享字面。这是零依赖、零模型的代价;要语义检索就得引入 embedding 模型(几百 MB 权重 + 常驻内存)。
- 会话索引的摘要是抽取式的(挑关键词最密集的句子),不做语义归纳;要真摘要得让模型自己写,那是另一档成本(要调模型、要花钱、还要处理摘要漂移)。- 访问是串行的:memory_open 一次读一页,模型要读 20 页就得多调 20 次工具。跨全库的「一共提过几次 X」「把这 5GB 归类总结」做不到——那需要预先写摘要(本插件没做,因为摘要要调模型、要花钱、要处理摘要漂移)。
- 单条记忆上限被配额约束(约配额的 5%),超长文档会被截断。
- 换 dbPath 不迁移数据;换之前请先复制 vault.db(连同 vault.db-wal、vault.db-shm)。
- 面板是只读的:看用量、检索、看最近写入,不能在面板里删除或编辑记忆(删除走 memory_forget 工具)。
- 装完必须彻底重启宿主才生效:profile 里的插件是按 generation 快照拷贝的,宿主进程不会热加载新代码。关窗口不算退出——托盘图标还在跑,要从托盘菜单退出。
- 容量调整(面板档位 / 自定义 / memory_resize)改的是上限,不会立刻删除已有记忆;只有写入后超限才会按「最久未用 + 最旧」淘汰。

数据在哪、怎么备份

D:\dsh-memory\vault.db 主库 D:\dsh-memory\vault.db-wal 预写日志(备份要一起带上) D:\dsh-memory\vault.db-shm 共享内存索引

取消插件前先停掉会话,再整目录复制,否则可能拿到半写状态的库。

开发与测试

零依赖,不用 npm install(Node 24 自带 node:sqlite)。五个测试文件全是自包含脚本,跑的是临时库 + 真 node:http,不碰你的真实记忆库:

npm test # 197 项断言:存储 45 + 容量 37 + 面板 35 + 客户端渲染 37 + 插件装配 43
node test/panel-test.mjs # 也可以单跑某一个

test/plugin-smoke.mjs 用假 ctx 跑通 apply() 全链路;设 VAULT_ROOT=<已安装的 generation 目录> 可以直接验装好的那一份副本。

License

MIT © 2026 xying-lm
预览分享卡片长什么样 ↓xying-lm/dsh-memory-vault
分享 · DeepSeek Harness Hub
xying-lm/dsh-memory-vault

自动沉淀对话要点,按需检索注入历史记忆

这是你的仓库?认领条目

回到顶部