自动沉淀对话要点,按需检索注入历史记忆
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
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 14 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
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预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
xying-lm/dsh-memory-vault
自动沉淀对话要点,按需检索注入历史记忆
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,489已汉化DSH
73.1
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,918已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,453已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
Download DS Bot for Windows 10/11 64-bit / 下载 Windows…
★ 5,293已汉化DSH
71.2
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,797已汉化DSH
71.1
这是你的仓库?认领条目