@restregular/dsh-memory
All-in-one local memory: JSONL files per scope (session, project, global, or a custom name) with per-scope dedup, five model tools (memory_save, memory_search, memory_list, memory_get, memory_forget), automatic recall and hard rules injected into the agent pre-step, and a settings panel. Retrieval c
Install
dsh plugin --profile web add @restregular/dsh-memory
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | — |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
<p align="center">
<img src="https://raw.githubusercontent.com/RestRegular/dsh-memory/main/preview/icon-128.png" width="84" alt="记忆系统">
</p>
记忆系统
本地优先的长期记忆,让每次对话都接得上。
JSONL 落盘 · 本机向量检索 · 五个模型工具 · 自动召回 · 硬性规则 · 可视化管理面板





它解决的不是「存一段文本」,而是「让模型在该记的时候记住、该用的时候用上」。
记忆默认只落在本机;没有向量服务也能工作——检索自动退化为词法,不产生任何网络请求。
它解决什么
常遇到的问题 · 记忆系统怎么做
新会话从零开始,换个窗口就问不出上次的结论 · 结论落成记忆;新会话第一步注入摘要,之后每轮按问题召回
同一个坑反复踩,上次查到的命令又要再查一遍 · 发布 / 部署 / 工具失败等行为会触发定向召回;查到的做法直接复用
写了规则没人执行,改过的规则旧会话不知道 · kind: rule 进系统提示常驻段;新增或编辑会补一条提醒
临时状态被当成永久事实 · kind: state 带默认 7 天 TTL 和「使用前验证」前缀;过期后默认隐藏,但不会自动删除
云端记忆不可控,敏感内容不敢写 · 全部本地 JSONL;写入前过凭据扫描;检索默认不联网
它也不是「把聊天记录整段塞给模型」:每条记忆是一句自洽的话,按作用域、类型和重要度管理;
召回有 token 预算与去重;旧结论可以用 supersedes 标注修正,被修正的旧版本默认不再参与
检索 / 摘要 / 召回(历史仍可用 memory_get 和面板查看),而不是悄悄覆盖。
功能
能力 · 说明
六个工具 · memory_save / memory_search / memory_list / memory_get / memory_forget / memory_scopes。memory_search 只回印象(8 位 id / 作用域 / 类型 / 标签 / 短摘要),正文和元数据用 memory_get 的 fields 按需取;同一会话里已出现过的条目只回 id。范围外命中默认只给作用域清单(outOfScope 字段:名字 / 条数 / 用途,0.28.0 起不再带条目摘要),确认后带 requestApproval: true 重发才弹审批。description 字段在普通限制下必填,审批卡会展示它。memory_scopes 管目录:action="list" 给作用域名字 / 用途 / 当前可读可写状态,action="edit" 编辑某个作用域的用途 / 别名(0.29.0),action="request" 申请范围外权限;目录本身不返回任何正文。作用域参数传裸名(handbook):0.26.0 起工具输出里的展示名 custom:handbook 粘进参数会被自动归一,project: / session: 本来就直接可用
四种作用域 · 会话 / 项目 / global / 自定义名。默认写进当前会话,读默认合并会话 + 项目 + global;项目作用域可起别名。自定义作用域首次由 Agent 创建时必须带 scopeDescription(一句话用途),可选带 scopeRule 写一条初始规则;元数据存在 <storeDir>/scope-meta/,删光记录也不会丢
作用域目录与绝对隔离 · memory_scopes 列出范围内 / 范围外的名字与用途(action="edit" 可改用途与别名);normal / none 下还带初始化记录正文(每个作用域最多 3 条,方便 Agent 直接读到“这个作用域主要放什么”)。绝对限制下范围外作用域仍可发现,但正文(含初始记录)永不可读、不可写、不可申请(没有任何审批放行路径);普通限制下范围外条目可申请,memory_scopes request 走审批后写入本会话授权(默认只读,写权限必须单独申请),子 Agent 沿父会话继承
会话授权(grants) · Agent 申请、用户批准的例外单独存在 <storeDir>/grants/<session>.json,不并入可见域策略;只读 / 可写独立、可撤销、只在本会话(及子 Agent)生效;absolute 下授权不生效,作用域被删除重建后按创建代次自动失效
双通道检索 · 词法(IDF + 中文 bigram)+ 向量(本机 llama-server 的 OpenAI 兼容 /v1/embeddings)。向量缺席自动降级,不报错、不阻塞
自动召回 · 每轮按用户问题召回;新会话第一步注入项目 / global 摘要;发布、部署、工具失败等行为按标签触发定向召回
印象形态 · 每轮只给每条记忆的短摘要;模型判断相关但需要细节时再 memory_get 取全文,省 token 也不丢信息
硬性规则 · kind: rule 进系统提示常驻段;行首带 8 位 id,注入的是摘要,需要全文时用 memory_get;旧会话会收到新增 / 编辑提醒;超预算有明确警告,不静默丢弃
记忆权限 · 输入框旁的「记忆权限」按钮设置本会话可读的作用域 + 限制等级(绝对 / 普通 / 无限制);每个作用域一行就是一条设置:勾选表示本会话可访问,行内【绑定】/【可读】/【可写】控制工作区默认可见与读写权限——【绑定】点一下立即保存(0.25.13 起),绑定到当前工作区后新会话默认可见,可读 / 可写独立影响工具读写;Agent 通过 memory_scopes request 申请到的范围外授权也用勾选呈现(名称右边挂一个「AI」气泡,样式与你自己勾选的行区分开),取消勾选只是草稿,点「保存」才真正撤销(0.25.4 起),且按钮数字 / 「已选」都把 AI 授权算进去(0.25.5 起)并实时轮询——浮窗关着,Agent 刚拿到的授权也会让按钮数字自己变(0.25.6 起);整张作用域卡片都能点选,点名称 / 计数 / 留白等同点勾选框(0.25.7 起),本会话那一行直接叫「session:当前会话」(0.25.8 起,0.25.10 起带类型前缀);所有作用域名都以 global: / project: / session: / custom: 开头(0.25.10 起);浮窗挂在页面根层,不会被输入框上方的浮动按钮盖住(0.25.8 起);Agent 及其子 Agent 都按它检索、注入与 memory_get
修正版编辑 · 面板里编辑一条记忆 = 新建一条修正版并通过 supersedes 指向旧记录,旧记录不原地修改;记录页「是否被修正」筛选默认隐藏旧版本,可切到全部 / 只看已修正
范围外审批 · 普通限制下,memory_search 撞到可见域外的记忆默认只返回作用域清单(名字 / 条数 / 用途,不含任何条目内容与摘要,0.28.0 起),不自动弹审批;Agent 确认某个作用域的用途确实相关后,带 requestApproval=true 重发查询才会发起审批。另一条路是 memory_scopes request(申请整个作用域的本会话权限)。发起后,审批卡在对应会话的输入框上方出现(样式与系统权限审批一致):展示工具、Agent 说明、查询关键词与范围外记忆摘要,支持逐条勾选 / 全选 / 取消全选(「允许选中的 N 条」或整单「允许一次」)或「拒绝」;点记忆 ID 直接跳到面板「记录」页并展开该条。0.25.14 起审批等待期间还会像系统审批 / ask 工具一样,在该会话的侧边栏行显示黄色圆点与「待审批」(含后台会话;回答或超时后撤销),其它插件也能从宿主 uiSession.sessionStatus 读到这条阻塞
上下文去重 · memory_search / memory_list 返回过的条目记进会话上下文状态;同一版本再次命中只回记忆 ID(memory_search 的裸 ID 与带摘要条目之间空一行),并提示用 memory_get 取全文(内容更新后重新给摘要)
状态记忆 · kind: state 默认 7 天 TTL;注入带「状态,使用前验证」;过期后默认不进检索 / 摘要 / 召回,但 memory_get 与面板仍可取
流程索引 · kind: procedure 的目录进系统提示:按当前工作区 + 触发词(工具名 / 关键词)列 id · 触发词 → 标题,需要时再用 memory_get 取全文
可视化管理 · 记录页分「记忆 / 作用域」两个子标签页:记忆侧浏览 / 搜索 / 新建 / 编辑 / 删除(编辑生成修正版),并可主动做语义检索(与 memory_search 同一套排序)、有「是否被修正」筛选;作用域侧列出每个域的名称、用途、记忆条数与最近更新(与 memory_scopes 目录同源),可直接编辑用途与别名(0.29.0,别名可选、留空即移除),可一键跳到该域的记忆列表;记忆树展示作用域、类型与修正链;设置改完即存;导入导出
一键向量后端 · 面板里下载 llama.cpp 运行时与内置模型,按 CPU / 内存 / 显卡推荐;换模型自动重建向量
跨进程安全 · 每个作用域一把写锁,锁内重新读盘再合并;多个 DSH 实例或 MCP server 共用一个 store 不丢数据
界面
记录页的语义检索
记录页搜索框旁边有「语义检索」开关。开启后,搜索不再按关键词过滤,而是把这句话交给和
memory_search 同一套的召回排序(向量 + 词法,必要时再重排),结果按相关度返回并标出得分。
- 开关只在向量后端已配置时可用;没装后端时保持禁用并说明原因。
- 语义检索是只读浏览:不增加访问计数,不会把
memory_search后续的排序带偏。 - 结果卡上的「得分」是排序分(向量/词法命中 × 重要度 × 时效 × 访问次数),不是概率,
访问次数多时可能大于 1;结果顺序与这个分数一致。
- 结果说明会如实写出这次是「语义排序」还是「关键词回退」:例如记录还没嵌入向量、或向量服务
没有响应时,不会把词法结果冒充成语义结果。嵌入完成后列表会自动刷新成语义结果。
- 作用域下拉与新建 / 编辑 / 删除仍然照常工作;从审计页点记忆 ID 跳过来时会自动回到普通列表并展开该条。
记忆树
按 作用域 → 类型 → 记录 三层展开,根节点显示总数。supersedes 是关系而不是层级,
所以不改树结构:金色虚线从修正版弯到旧版,悬停或选中任意一端,整条修正链一起点亮。
设置
召回、摘要、印象、策略
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::106,最后更新 2026-10-31