🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI
广告☁️ 云服务器特惠阿里云首购 8 折 · 腾讯云合作特惠
DeepSeek Harness Hub
← 返回列表

lpf20200901/dsh-memory-delta

DeepSeek Harnessspec-screened扫描:低风险在 GitHub 查看 ↗
未验证

给 AI 编码助手的跨会话长期记忆:自动注入、只推变化。DSH 插件 + 零依赖 CLI。

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/20 · 已提供中文文档
综合分
29.4
GitHub 分
29.4
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add lpf20200901/dsh-memory-delta
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
信任档位:已验证本站已于 0 天前真实安装成功
是什么
dsh 原生插件 · browser
装得上吗
本站已真实安装成功(非静态推断)
安全吗
本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
还在维护吗
活跃:最近一次提交在 5 天前

档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →

🟢实装验证通过· 2026/9/25
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/25(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-llm@deepseek-ai/dsh-tools@deepseek-ai/schemastery
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

由 DeepSeek 最新模型翻译生成
dsh-memory-delta

给 AI 编码助手的、分层自动注入的跨会话记忆。
一个 DSH 插件 + 一个零依赖的独立 CLI。借鉴 OpenSpec 的
规格 / 变更 / 归档 纪律 —— 但走推送而不是拉取。

主仓库:GitHub ·
Gitee 是只读镜像 ——
issue / PR 请提到 GitHub,提到镜像站会丢。

状态:M1–M3 已完成并在真实 DSH 上实机验证(差分注入 / 两个工具 / 蒸馏提醒)。
实机验证矩阵见下方「验证」。

为什么需要它

AI 编码助手有两个反复出现的毛病:

1. 新会话不记得任何事 —— 每个会话都要重新交代背景、偏好、结论。
2. 记住了也管不好 —— 全塞进一两个 Markdown,越写越大、越写越贵,而且结论过时了没人删。

已有的规格驱动工具(OpenSpec 等)解决的是"代码不跑偏",但它们是拉取式:靠指令要求 AI 去读,
新会话不会主动想起来。dsh-memory-delta 走推送:会话一开始就把该知道的塞进上下文,但只推最精炼的部分,
而且只推变化的部分,细节按需检索。

设计要点

┌─ PUSH:会话开始自动注入(字节预算硬约束)
│    T0 身份与约定   用户偏好 / 机器环境 / 账号约定
│    T1 索引与待办   接着办什么
库 ─────┤
└─ PULL:按需检索(不占常驻预算)
inbox/      候选条目 —— 模型默认只能写这里
facts/      当前真相(只有 status=active 参与注入)
decisions/  决策与理由(只增不改)
archive/    被取代条目的归档
journal.md  流水(永不注入)

目录名要分两个轴看(这一点以前没写清,容易被 facts 这个词误导):

| 目录 | 在流程哪一步 | 记什么 | 谁能写 | 参与注入 |
| --- | --- | --- | --- | --- |
| inbox/ | 候选(还没确认) | 模型觉得值得长期留住的结论 | 只有模型(memory_write) | ❌ 从不 |
| facts/ | 常驻 | 踩过的坑 + 怎么绕开:环境限制、工具行为、真实的失败与解法 | 只有人(promote) | ✅ 每轮 |
| decisions/ | 常驻 | 你定下的约定:业务 / 流程 / 口味上的决定 —— 防止重复问你 | 只有人(promote) | ✅ 每轮 |
| archive/ | 归档 | 退场的旧结论:被取代(supersede)或不再适用(archive) | 取代/归档时自动搬 | ❌ 永不(但仍搜得到、能取回) |

主流程:模型只能写 inbox/ → 人确认后 promote 进 facts/ 或 decisions/ → 退场的进 archive/。
拿不准放哪边就问:"明天世界变了,这条会不会失效?" 会 → facts/;只有你改主意才失效 → decisions/。

两条写起来的诀窍:facts/ 里写清"什么情况下适用"(坑的价值是"下次别再踩",不是"曾经踩过");
decisions/ 里写清"为什么这么定"(有了理由,下回它就能自己判断,不会再问你第二遍)。

这四个目录名(以及 journal.md / index.md / memory.config.json)的完整说明,mem init
会写进库自己的 README.md —— 打开记忆库目录就能看到,不用回来翻项目文档。

七条纪律:

- 推送的东西必须极小:注入层里的内容每次会话都要花 token。所以流水、设计文档都不进注入层。
实测一个 6 条目的真实记忆库:注入文本 953 字节,其中 68% 是条目行本身、约 300 字节是框架说明,
平均 159 字节/条 → 3 KB 默认预算装得下约 19 条。条目 id 故意不写进正文(它随消息的
结构化 source.entries 一起走),因为把 id 内联进正文曾吃掉 34% 的预算。
- 只推变化的部分:每条条目带 12 位内容 hash,插件记住上一轮的状态,下一轮只推新增/已更新/已失效;
完全没变化时一个字都不注入。(上游 dsh-agent-instructions 没有差分:文件一变就整篇重注入,
实测一个会话里改 15 次某个 8.5 KB 的文件 ≈ 白烧 58k tokens。)
- 状态从会话历史恢复:不存旁路状态文件,而是从自己发过的消息里读回 {id: hash} ——
所以会话恢复 / 回放 / 压缩之后依然正确。
- 模型只写收件箱:错误结论若静默进入常驻层,会被反复注入。提升需要显式 promote。
- 一个 key 一个真相:事实/决策带语义键 key,同一个 scope+key 上只能有一条 active。
新结论要进来,必须显式 --supersedes 旧的 —— 这是把"记忆腐化"挡在常驻层外的闸门。
- 结论有状态:active / superseded / expired。被取代的打双向链接并归档,而不是无限追加。
- 纯 Markdown + frontmatter:人可读、可 git diff、可 review、能像代码一样提交。

安装(作为 DSH 插件)

⚠️ 这段是实机踩出来的,两条弯路都别再走:

❌ 往 package.json 的 dsh.profile.bundles 里加
→ DSH 启动时按市场注册表(.generations/desired.json)重新生成,未知条目被清掉

❌ 在 cordis.patch.yml 里写一个裸条目
→ 被静默忽略(patch 对不存在的 id 只做 config 覆盖/禁用)

✅ 在 cordis.patch.yml 里用 - insert: 包起来

步骤(DSH_HOME 通常是 %APPDATA%\dsh-desktop\harness):

1. 把本包放进 profile 的 node_modules:

\profiles\web\node_modules\dsh-memory-delta\
package.json
bin\mem.mjs
src\plugin.mjs  src\hook.mjs  src\planner.mjs

2. 在 \profiles\web\cordis.patch.yml 末尾追加:

- insert:
- id: dsh-memory-delta
name: dsh-memory-delta
config:
root: ''             # 留空 = 会话工作目录下的 memory/
maxBytes: 3072       # baseline 注入的字节预算
enabled: true
dueWithin: 0         # verify_when 提前几天提醒复核(0 = 只在已到期时)
panel: true          # 侧边栏「记忆」页签的数据/动作路由
allowWrite: true     # 允许面板按钮写记忆库(收件箱提升 / 整理文件名)

3. 保存即可 —— patch 层有 watchUserPatches,会热加载,不需要重启。

卸载:删掉 patch 里那段 - insert:,再删掉 node_modules\dsh-memory-delta 目录。

官方分发渠道(插件市场)的发布流程我还没摸;目前是本机安装方式。

插件提供什么

| 能力 | 说明 |
| --- | --- |
| 差分注入 | 首次注入全部 active 条目(baseline);之后每轮只推「新增 / 已更新 / 已失效」;无变化时零注入 |
| memory_search | 按相关度排序的检索,覆盖 facts / decisions / inbox / archive / journal / 会话索引。字段有权重(key/id > tags > 结论 > 正文)、整串短语有加成;中文按 bigram 匹配,所以 沙箱禁管道 能命中 沙箱禁止命名管道,不用手动加空格。每条结果带 score 与"命中最多的那一行"的片段 |
| memory_write | 把候选条目写进 inbox —— 模型不允许直接改事实层 |
| 蒸馏提醒 | 会话跑过若干轮而记忆已是最新时,提醒模型把本次结论落到 inbox;每会话只提醒一次,且提醒消息不带状态,不污染差分基线 |
| 到期复核提醒 | verify_when 不再是死字段:条目到了当初约定的复核期,会话里会提醒一次"这条结论可能过时了,请复核",并给出该用哪条命令取代/标过期。写成人话的值(等换机器时)永远不会触发它(否则每个会话都弹一次、怎么改都消不掉);只在"本轮本来不注入任何记忆"时才提醒,同样不带状态 |
| 侧边栏「记忆」页签 | 装了 dsh-better-sidebar 后,侧边栏多一个记忆页:按流程阶段分组(待你确认 → 已在用 → 已归档,每组一句人话 + 顶部一条流程条)、可折叠(自绘箭头)、搜索框(搜条目 + 流水,中文连写也行 —— 与 mem recall、模型用的 memory_search 是同一套打分)。「已在用」可按三个维度看:类型(事实/决策,回答"该放哪边")/ 标签(按主题)/ 日期(什么时候记的,带"今天/昨天/周几"人话标注)。点某条记忆 = 打开它那个 .md(走 better-sidebar 的官方 openFile,在侧边栏编辑器里预览/编辑)。双向迁移:候选「提升到 facts/ decisions/」⇄ 常驻「撤回」,常驻还能「归档」、归档能「取回」,候选可「删除」——危险动作一律走行内确认条(不用会阻塞无头截图的浏览器原生 confirm)。「已在用」里还会显示全局规范(~/.dsh/AGENTS.md:DSH 注入、每个工作区都生效,只读预览 + 默认折叠)与工作区规范(AGENTS.md / AGENTS.local.md,可直接点「编辑」进侧边栏编辑器 —— 它们在工作区内,编辑器允许打开)。客户端半边是手写的零构建浏览器 bundle(window.__ModuleLoader__.load({id, factory}) 包装,不引入任何打包器);数据来自本插件自己的只读路由 POST /dsh-memory-delta/state 与 POST /dsh-memory-delta/search —— 仅回环、JSON 进 JSON 出、不碰别的文件。唯一会写的路由是 POST /dsh-memory-delta/action(提升 / 撤回 / 归档 / 取回 / 删除候选 / 安全改名),可用 allowWrite: false 关掉 |
| 为什么不把"编辑/删除记忆"做进面板 | 侧边栏本来就有编辑器(点条目即打开)和文件树(重命名/删除带确认)。在面板里再造一套完整增删改 = 重复实现 + 长期维护负担,所以面板只做入口加几个真正需要判断的动作:打开文件、候选提升、常驻撤回、候选删除、整理文件名(mem rename:id + 文件名 + 引用一起改)。"跳到目录"这类纯跳转按钮不做 —— 折叠箭头看内容 + 点条目打开详情已经够,多一个按钮只多一份噪音和一条会启动外部进程的路由。⚠️ 不要用文件树直接给记忆条目改名 —— id 写在 frontmatter 里且必须与文件名一致,mem validate 会报 id 与文件名不一致;这正是不做自由改名、只做"安全改名"的原因。常驻条目不能直接删(那等于静默消失)—— 它的出路是「撤回」或取代/标过期 |

为什么插件不去 spawn CLI:DSH 沙箱禁止命名管道,捕获子进程输出会 EPERM;而且没必要 ——
插件直接 import 同一份 store 逻辑(bin/mem.mjs 只在被直接执行时才跑 CLI)。
它也不强依赖侧边栏:webServer 是通过 ctx.get('webServer') 读的可选能力,
所以 headless / 纯 CLI 组合下插件照常加载,只是不注册面板路由。

侧边栏里的「记忆」页签

从侧边栏的 + 菜单打开的「记忆」页签:可折叠分组(标题后的等宽字是磁盘上的目录名)、
常驻条目与其语义键/标签/日期/文件名、待复核区、收件箱候选,以及当前记忆库每轮会话要花多少字节。
点条目就在编辑器里打开它(面板本身从不写记忆库;写操作只有收件箱的提升与整理文件名两个按钮)。

CLI 用法

初始化(默认 /memory,可用 --root 或 $DSH_MEMORY_ROOT 改)
mem init --root ./memory --scope "workspace:/path/to/project"

记一条候选(落在 inbox,不注入)
--id  推荐显式给短 id;不给则从结论派生(压到 20 字符,撞车自动加序号)
--key 语义键:一个 scope+key 上只能有一个 active 真相
mem new --type fact --id win-update-cache --key disk-cleanup \
--conclusion "清更新缓存实测收益为零" \
--reason "目录删空但可用空间未变" --tags windows,disk --source session-abc
只给 --key 不给 --id 时,key 就是 id(也就是文件名):sandbox-no-pipe.md
不给 key 才退回「日期 + 截断的结论」派生 id(中文结论会被截在词中间,尽量给 key)

确认后提升到事实层;同 key 已有 active 时必须显式说明谁取代谁
mem promote win-update-cache
mem promote win-update-cache-v2 --supersedes win-update-cache

mem demote              # 撤回:facts/decisions → inbox("先不当真",不改 status,还能再 promote 回去)
mem archive             # 归档:不再适用又没有替代 → archive/(status=expired;仍可搜、可 restore)
mem restore             # 取回:archive/ → inbox(status 复位 active,再 promote 一次才重新生效)
mem rm                  # 删除候选(只允许 inbox/);常驻条目的出路是 demote / archive / 取代,不直接删

mem set  --key k --tags a,b --conclusion "…"   # 改已有条目(补 key / 改措辞 / 标 expired)
mem rename      # 安全改名:frontmatter 的 id、文件名、别处的 supersedes 引用一起改
(别用文件树手动改名 —— id 与文件名必须一致)
mem list --status active --tag windows
mem show
mem validate [--fix]       # 格式/id/双向链接/环/同 key 冲突/索引/注入预算
mem index                  # 重建 index.md
mem inject [--json] [--budget 3072]   # 渲染应注入内容;--json 出带 hash 的差分载荷
mem recall  [--where all|facts|decisions|inbox|archive|journal|sessions|index] [--limit N] [--json]
按相关度排序;中文按 bigram 匹配,不用手动加空格
mem due [--within N] [--json]   # 到了 verify_when 复核期的条目(--within N 提前 N 天也算)
mem journal add "流水一行"

verify_when 可以写日期(2027-03-01),也可以写相对条目自身日期的说法
(3个月后 / 2周后 / 立即);其它写法按"人话"处理,不会被自动提醒。

验证(实机)

在真实 DSH 会话里逐项确认过:

| 能力 | 实机证据 |
| --- | --- |
| baseline 注入 | 会话收到全部 active 条目 |
| 无变化 → 零注入 | 下一步没有重复注入,只补了一次蒸馏提醒 |
| delta·新增 | "新增:",并注明"其余 N 条未变化" |
| delta·已更新 | 改一条后只推"已更新:" |
| 到期复核提醒 | 加一条 verify_when 已过期 16 天的条目 → 下一个"无变化"的步骤弹出一次 form='due' 提醒,再下一步零注入(提醒没污染差分基线) |
| 侧边栏记忆页签 | 真机打开后显示真实库路径、"常驻 12 条"、"注入 1792 / 3072 字节"、事实/决策分组,以及(空的)收件箱 |
| memory_search / memory_write | 真机调用成功 |
| 写入只落 inbox | 写进去的候选确实没进注入载荷,promote 后才以 delta 出现 |

开发

npm test        # 825 个断言,零依赖

| 套件 | 断言 | 覆盖 |
| --- | --- | --- |
| test/run-tests.mjs | 180 | CLI 端到端(含非 ASCII 路径回归、相关度检索、mem due、mem rename 与引用同步、key 当文件名) |
| test/planner-tests.mjs | 43 | 差分算法(纯逻辑) |
| test/search-tests.mjs | 51 | 分词 / 打分 / 片段选择(纯逻辑) |
| test/due-tests.mjs | 93 | verify_when 解析(日期、相对说法、人话)与到期收集(纯逻辑) |
| test/hook-tests.mjs | 63 | 插件接线(假 agent / decision):差分注入、蒸馏提醒、到期提醒 |
| test/plugin-tests.mjs | 217 | 插件集成(桩 DSH 模块,真 apply + 两个工具 + 两条面板路由 + promote/rename 真的写库 + 白名单/来源校验) |
| test/client-tests.mjs | 178 | 侧边栏面板 bundle(假 React + 假 fetch:分组/折叠、点条目调 openFile、提升/整理文件名、失败态) |

test/plugin-tests.mjs 用 test/stubs/ 下的桩模块替换 4 个 @deepseek-ai/ 包,
通过 test/stub-loader.mjs 真正 apply() 这个插件并驱动它,所以即使没有 DSH 也能验证插件行为。
另有 test/preflight-import.mjs:把包放进 profile 后用真实 @deepseek-ai/ 模块跑一遍
(真实 defineTool 是否接受工具定义、真实 schemastery 是否接受配置 schema)。

几条从真实踩坑固化来的回归测试:

- 路径含非 ASCII 字符时,Node 的 fs.rmSync 会静默失败(配 recursive 时甚至崩进程),
必须用 unlinkSync;
- DSH 沙箱禁止命名管道,spawnSync 默认的 stdio:'pipe' 会 EPERM,测试要把输出重定向到文件;
- 工具写出的条目 scope 必须跟随会话工作区,不能落到 harness 进程的 cwd;
- new URL(import.meta.url).pathname 会把非 ASCII 用户名百分号编码
(C:\Users\李鹏飞 → C:\Users\%E6%9D%8E%E9%B9%8F%E9%A3%9E),"往插件目录里写"就变成
"往一个根本不存在的路径里写" —— 一律用 fileURLToPath;
- 内部函数只给部分 return 路径补字段(due),解构出来就是 undefined,每一步都抛错、
又被外层 try/catch 包装成"加载记忆失败" —— 于是有了防御式取值 + "零告警"断言。

路线图

- M1 ✅ CLI + 结构化条目 + validate + 索引/注入预算
- M2 ✅ 显式短 id、语义键与「一个 key 一个真相」、inject --json 差分载荷、validate --fix、mem set
- M3 ✅ DSH 插件:差分注入 + 两个工具 + 蒸馏提醒(已实机验证)
- M4 ✅ 发布(GitHub 主 / Gitee 镜像)
- M5 ✅ 让记忆"规模上真的可用":注入改索引式(正文不写 id,平均约 159 字节/条)、
按相关度排序的检索(中文 bigram)、verify_when 落地成到期复核提醒
- 下一步 条目变多时保持注入体积可控;发布到 npm

借鉴与致谢

「规格 / 变更 / 归档」这套纪律 —— 一份人可读的当前真相,加上一份待生效的变更集,落地后归档 ——
借鉴自 OpenSpec(MIT)。

dsh-memory-delta 是独立实现:不包含、也不调用 OpenSpec 的任何代码,存储格式与 CLI 都是自研的;
而且方向是反的 —— 记忆是被推进会话,而不是等 agent 来拉。

「OpenSpec」是其作者的项目名/商标;本文只作来源说明,不表示与该项目的关联或背书。

许可

MIT

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入社群

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

DPharness QQ 群二维码,QQ 扫码进群
QQ 扫码进群
DPharness 飞书群二维码,飞书扫码进群
飞书扫码进群