dsh-memory
Verified@bangbang-03/dsh-memory · v0.6.8 · MIT · Web UI
DSH 工作区记忆画像:有证据、有版本、能解释变化;索引简报省 token、轮末本地召回、红线 / 审批队列 / 版本链 / 注入审计;零依赖、不出站。
Install
dsh plugin add @bangbang-03/dsh-memory Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Readme
Memory Portrait · 记忆画像
DSH 的记忆画像:不是记住更多,而是让你看见它怎么理解你。
Long-term memory for DeepSeek Harness, with a portrait you can inspect.

仓库名已改为
dsh-memory-portrait;npm 包名仍是@bangbang-03/dsh-memory,安装命令不变。
Memory Portrait 把记忆按工作区落库:会话开始时注入一份索引简报(一行一条,正文按需用 memory 工具取,省 token),
轮次结束后用本地检索把相关记忆召回到下一轮,可选地把对话自动提炼成结构化记忆。
它把「画像」放在首页:模型现在怎么理解你、每段判断来自哪条记忆、这一版和上一版差在哪里——有证据、有版本、能解释变化。
和「自动多记一点」的插件不同,它把重点放在记错了怎么办:红线、审批队列、版本链、注入审计、派生链,全部能在 设置 → 记忆 里看到。
- 画像是主视图:每段挂证据,改了什么可 diff,源失效沿派生链标脏。
- 省 token:索引模式同样预算多装约 3 倍条目;简报字节稳定,不破坏 prompt 前缀缓存。
- 可控:自动提炼可先进审批队列;红线逐字置顶,模型不能删改;改稿留历史,可回滚。
- 可审计:每次注入都记录正文 hash、命中的记忆 id、被预算挤掉的条目;画像与
AGENTS.md有派生链。 - 零依赖:
dependencies为空,只要 fs + 回环 HTTP;不 shell、不 env、不启子进程、不出站、不加载动态代码。
English — Long-term workspace memory for DeepSeek Harness, with an inspectable portrait: every section carries evidence, versions, and diffs. Redlines, an approval queue, a version chain, and an injection audit are included. Zero dependencies; no shell, env, or outbound requests. Jump to English.
安装
DSH ≥ 0.2.0-rc.2,web / 桌面。headless / TUI profile 尚未做端到端验证,暂不声明。
一条命令(推荐,web profile)
dsh plugin --profile web add "https://github.com/BangBang-03/dsh-memory-portrait/releases/latest/download/dsh-memory-latest.tgz"
/latest/ 永远取最新稳定版,不需要 clone,也不需要 npm。
npm(web profile)
dsh plugin --profile web add @bangbang-03/dsh-memory
npm 源与 Releases 同源;如果
npm view @bangbang-03/dsh-memory version低于 Releases,用上面的「一条命令」。
桌面端
把 install.ps1 下载到任意目录,然后:
pwsh -File install.ps1 -FromRelease -Channel stable
脚本会下载最新稳定版 tarball、解包到 ~/.dsh/plugins/dsh-memory,再完成垫片 / profile 清单 / junction 三步;更新就是重跑同一条命令。-Channel lab 是兼容别名,等同 stable。
源码
git clone https://github.com/BangBang-03/dsh-memory-portrait.git
cd dsh-memory-portrait
pwsh -File install.ps1 -DryRun # 先看一遍要改什么
pwsh -File install.ps1 # 真装
# 重启 DSH 桌面端
dsh plugin --profile desktop …会被拒绝:desktop profile 由 Electron 独占。桌面端用上面的install.ps1。 改 profile 前脚本会自动备份(秒级时间戳,不覆盖旧备份)。回滚:pwsh -File uninstall.ps1(记忆数据保留);-PurgeStorage才会删~/.dsh/storages/dsh-memory。
装好后打开 设置 → 记忆。宿主路由是 /memory/api,只监听回环地址;客户端用 new URL("memory/api/…", document.baseURI) 解析,反代前缀 / dsh-app:// 外壳下也能到达。
兼容性
| DSH 版本 | 状态 |
|---|---|
0.2.0-rc.2 |
compatible(已测试) |
0.2.1-rc.3 |
compatible(已测试) |
0.2.1-rc.4 |
unknown(范围覆盖,未单独测试) |
0.2.1-rc.5 |
compatible(当前桌面版,已测试) |
0.2.2-alpha.2 |
unknown(范围覆盖,未测试) |
Node ^22.19.0 || >=24.0.0;DSH 范围 >=0.2.0-rc.2 <0.3.0-0。范围按 0.2 版本线整体声明,避免 DSH 每发一个 nightly 就在宿主启动时被跳过;逐版本测试结论仍记在 dsh.compatibility.dshReleases,未测试的版本标 unknown,不冒充 compatible。
DSH 0.2.1 起,宿主在启动 / 重新组合时按
engines.dsh判定组合包:不匹配的 bundle 会被静默跳过(列进skippedBundles),市场卡片显示“已安装,与当前 dsh 不兼容”,插件功能整体不生效。升级 DSH 后若看到这行字,先确认上表的范围覆盖当前版本。
兼容口径不是手写三份:
node tools/check-compat.mjs会核对package.json与 README 表格;--npm再核对 npmjs 上已发布的同一版本。CI 在发版时跑后者。
它怎么工作
| 通路 | 触发 | 做什么 |
|---|---|---|
| 简报 | 会话开始 | briefMode: index 一行一条;正文按需 memory get/search |
memory 工具 |
任何时候 | save/search/sessions/promote/list/get/update/forget/stats |
| 轮末召回 | turn/end |
当轮用户消息本地检索,命中项下一轮尾部注入;纯本地 0 token |
| 路径 JIT | 工具触达 files |
相关记忆在下一步尾部注入;全路径 > 目录后缀 > 同名 |
| 自动提炼 | 轮次结束(可选) | 结构化记忆;captureMode: draft 先进审批队列 |
| Dream / 画像 | 启动 + 轮末到期检查 | 合并重复簇、报告矛盾、报告过期;画像按 6 小时自动刷新 |
| 前台会话卡 | 对话中常驻(可收起) | 右下角悬浮卡:本会话诉求 + 本会话已沉淀记忆,草稿不可见;每次内容变化刷新「更新于 HH:MM」;可拖拽,位置本地记住;设置 → 记忆可用「该对话记忆」单独关闭本对话 |
简报的排序不读 useCount / 当前时间,日期戳只用 createdAt,并且会话级冻结。这样同一会话的系统提示不会逐轮变化,前缀缓存不会因为记忆更新而整段作废。
从别的工具搬过来
设置 → 记忆 → 从本机既有记忆导入:扫描 WorkBuddy / Qoder / Claude Code / Codex / Windsurf 的既有记忆文件,只读扫描、按来源打标签;也可以直接粘 /export 的 JSON 或 Markdown。导入有新增时会后台触发一次画像重写(feedPortrait: false 可关)。
画像与账本
画像不是一句总结:每段有证据、版本和 diff;下面的机制保证它不会变成模型随手写的小抄。
| 机制 | 作用 |
|---|---|
| 红线 | 绝对禁令逐字置顶;模型不能删 / 归档;改稿留 20 版历史,可回滚;保存前查冲突 |
| 审批队列 | captureMode: draft 时草稿四不可见(简报 / 检索 / 镜像 / 导出),批准才生效 |
| 版本链 | supersedes 旧条归档不删除,新旧互指;一键回滚 |
| 注入审计 | 每次进 prompt 的正文 hash + 记忆 id + 被挤掉的条目;append-only |
| 派生链 | 记忆 → 画像 → AGENTS.md 每层记源快照;源失效沿链标脏 |
| 整库快照 | 每天首次写入 + 每次 Dream 前备份,轮转 7 份;恢复 = 手工拷回库目录 |
| 写入安全 | 密钥脱敏 + 注入模式 taint;非 user 来源 taint 隔离成草稿 |
为什么是「画像」
如果你要的是「模型自动多记一点」,很多插件都能做。Memory Portrait 把重点放在它现在怎么理解你:画像的每段有证据、有版本、能解释变化;写错了有红线、审批、版本链、注入审计。它不追求记住一切,而是让每一条被记住的东西有来源、有版本、能解释、能撤回。
几个明确的取舍:
| 选择 | 取舍 |
|---|---|
| 本地 BM25F + 精确短语 + 同义词 + 路径召回 | 不引入向量服务 / 后端,零依赖;语义泛化弱于 embedding |
| 索引简报 + 按需取正文 | 省 token;模型需要多一步 get |
| 启动 / 轮末到期检查,无常驻定时器 | 不占后台;整理不是实时 |
| Dream 只报告矛盾,不自动归档 | 避免词法误报;需要人确认 |
配置
面板里能改的都落在 ~/.dsh/storages/dsh-memory/settings.json;cordis.patch.yml 里的 config 只是初值。
| 键 | 默认 | 说明 |
|---|---|---|
enabled |
true |
总开关 |
autoInject |
true |
注入总闸:关掉后简报 / 轮末召回 / 路径召回都不再进上下文,memory 工具照常读写(「只用工具」档) |
directory |
"" |
数据库位置,空 = ~/.dsh/storages/dsh-memory |
disabledWorkspaces |
[] |
停用自动记忆的工作区(绝对路径,归一后精确匹配):不注入、不自动提炼;工具仍可手动读写。事故排查时也用它把一次性工作区摘出去 |
mirror |
true |
在工作区写 .dsh-memory/MEMORY.md |
briefing |
true |
会话开始注入记忆简报 |
briefMode |
"index" |
index 一行一条索引(省 token);full 标题+正文摘录;portrait 全局画像全量(工作区画像已撤)+ 索引清单 |
briefingLimit |
12 |
注入条数上限(1–50) |
briefingMaxChars |
2000 |
注入字数上限(200–20000) |
portraitMaxChars |
1400 |
画像注入的字数预算(工作区 + 全局合计;仅 briefMode=portrait 生效,200–8000) |
discipline |
true |
注入「记忆纪律」一段(何时写什么、对话内指令触发规则) |
rewriteMode |
"direct" |
画像重写写入方式:direct 直接落库;draft 先存待审稿,面板批准后才生效 |
journalDays |
14 |
画像重写时读取最近多少天的日志作为原料(1–90) |
turnRecall |
true |
轮末按当轮内容召回相关记忆进下一轮 |
turnRecallLimit |
3 |
每轮召回条数(1–10) |
sectionOrder |
550 |
注入段落在系统提示里的位置 |
autoCapture |
false |
轮次结束自动提炼 |
autoDreamDays |
7 |
启动整理:启动时与轮末检查当前(最近使用的)工作区,距上次(自动或手动)整理满 N 天就在后台整理一次;0 关闭(0–365)。没有常驻定时器 |
autoDreamPortrait |
false |
自动整理(启动时)是否顺带重写画像;默认关——画像由 autoPortraitHours 自动刷新负责。手动 Dream 仍会刷新一版进待审 |
autoPortraitHours |
6 |
自动刷新全局画像:每 N 小时检查一次,有新素材时调用模型重写;0 关闭(0–168)。面板「立即刷新」只是兜底 |
captureMode |
"direct" |
direct 直接落库;draft 先进待审队列 |
staleDays |
60 |
体检里「过期未用」的判定天数 |
autoCaptureMinChars |
600 |
太短的轮次不提炼 |
captureCooldownMs |
60000 |
两次提炼的最小间隔 |
minConfidence |
0.4 |
提炼结果的最低置信度 |
maxPerTurn |
5 |
每次最多落库条数 |
maxTranscriptChars |
6000 |
送给模型的对白摘录上限 |
dedupe |
true |
保存时合并相似记忆 |
qualityGate |
true |
质量闸门:自动提炼 / agent 主动写入的低分条目(<30)直接归档,不进简报 |
redactSecrets |
true |
写入安全:密钥扫描与脱敏(命中替换为 [REDACTED:*] 并记 redactions) |
quarantineTainted |
true |
写入安全:非 user 来源命中注入模式(taint)时自动隔离成草稿 |
pathRecall |
true |
路径 JIT:工具触达 files 挂靠的文件时,相关记忆在下一步尾部注入 |
pathRecallLimit |
3 |
每次路径召回最多注入几条(1–10) |
sessionSearch |
true |
会话索引:每轮用户发言原文落 sessions.jsonl,action=sessions 溯源 |
compactionSalvage |
true |
压缩协同:宿主压缩上下文时把摘要照录进当天工作日志 |
captureSubagents |
false |
子代理会话(origin=subagent)是否也参与自动提炼;默认否,避免把派活的中间过程写成记忆 |
falsifierReviewDays |
90 |
复审周期(天):带失效条件的记忆默认多少天后进复审队列(1–3650) |
HTTP 契约
/memory/api 前缀,JSON 信封成功 {ok:true,…} / 失败 {ok:false,error,detail?}。
请求体超 4MB 回 413 payload_too_large;显式传入的 workspace 必须是已注册工作区
(当前活动工作区或落过库的工作区),否则回 400 invalid_workspace。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /state |
版本、工作区、统计、设置、类别、工作区列表、标签、最近提炼、最近简报计量 |
| GET | /briefing-preview |
简报预览:按当前设置算「下次会话会注入哪些记忆」,含画像计量与预算挤掉的条目 |
| GET | /list |
列表;q/category/scope/tag/archived/sort/limit/offset(不含草稿) |
| GET | /record |
读单条(含归档,不含草稿):id;画像依据下钻用 |
| POST | /save |
新建或合并;带 supersedes 走版本链(旧条归档、可回滚) |
| POST | /update |
改一条(含 related / keywords) |
| POST | /bulk |
delete / archive / unarchive / pin / unpin |
| POST | /delete |
删一条(红线需带 overrideRedline: true,面板确认后才会带;否则 403 redline_protected) |
| POST | /redline/check |
红线保存前冲突检查:与现有红线做疑似矛盾词法判定(只读) |
| POST | /redline/update |
红线改稿(必须 confirm: true;旧措辞写入历史) |
| GET | /redline/history |
红线当前版本 + 旧版本列表 |
| POST | /redline/rollback |
红线回滚(必须 confirm: true;当前版本先写回历史) |
| POST | /settings |
写设置 |
| GET | /health |
体检:重复簇、过期未用、断链、待审草稿数、待确认矛盾对(词法线索;Dream 只报告,逐对确认后才归档)、files 引用失效、overBudget 超预算信号(只报告);另含 maintenance(启动整理间隔 / 上次 / 下次 / 摘要、autoPortraitHours 与全局画像 updatedAt、运行态) |
| POST | /health/resolve |
一键处理:merge(合并簇,可带 title/category/tags/content 覆盖合并稿;红线与矛盾对会被拒绝)/ time-order(对一对矛盾按时序归档旧条,红线 / 置顶 / 用户旧条 / 外部新条会被拒绝)/ archive(归档过期)/ unlink(摘除断链) |
| GET | /timeline |
全部记忆(含归档、不含草稿)按更新时间倒序 |
| GET | /portrait |
当前画像(工作区 + 全局)、版本列表、段落定义 |
| POST | /portrait/save |
保存画像(版本 +1,旧版留档) |
| GET | /portrait/history |
画像版本列表(降序) |
| GET | /portrait/export |
画像导出(轻量):全局画像(含版本历史)+ 全部红线;POST /import 识别该载荷自动回灌(导入即入画像) |
| GET | /portrait/diff |
两个版本的逐段 diff(from=previous 默认,返回 +/− 行与摘要) |
| POST | /portrait/rewrite |
触发画像重写(scope=global 为面板默认;captureMode/rewriteMode 决定直写或进待审) |
| POST | /portrait/migrate |
跨 App 迁移画像:粘贴其它应用 AI 按提示词总结的画像 JSON,与全局画像整合(LLM 整合,失败降级段落合并) |
| GET | /portrait/draft |
读取待审重写稿(默认全局;scope=workspace 读工作区旧稿) |
| POST | /portrait/draft/approve |
批准重写稿:落库、旧版留档、清待审文件 |
| POST | /portrait/draft/discard |
丢弃重写稿 |
| GET | /queue |
待审草稿队列 |
| POST | /queue/approve |
批准草稿(可带编辑字段;草稿带 supersedes 时兑现版本链) |
| POST | /queue/reject |
拒绝草稿(默认删除,mode: archive 归档留底) |
| POST | /supersede/rollback |
版本链回滚:传新条 id 恢复旧条,或传旧条 id 撤销推翻 |
| GET | /export |
导出当前工作区与全局条目(字段齐全,含 falsifier / reviewAt);?full=1 连画像 / 派生链 / 最近 30 天日志一起导出,/import 自动识别回灌 |
| POST | /import |
导入(备份载荷、纯文本、画像导出载荷,或 path/paths 指到本机既有记忆文件)。导入有新增时后台自动触发一次画像重写(「导入即入画像」;feedPortrait: false 关闭,响应 portraitRewrite 标记是否触发) |
| GET | /journal |
读最近 N 天工作日志(days,1-30,默认 3) |
| POST | /journal |
写一条工作日志(date 可指定,默认当天) |
| GET | /import-scan |
扫描本机既有记忆来源(WorkBuddy / Qoder / Claude Code / Codex / Windsurf / 本插件镜像),只读 |
| POST | /import-scan |
按来源 id 或路径导入,用户级来源自动进全局库 |
| GET | /mirror |
取当前工作区镜像的 Markdown |
| POST | /capture |
立刻提炼一次(captureMode 决定落库还是进队列) |
| POST | /dream |
Dream 整理(手动补跑;与「启动整理」同一管线):合并重复簇(红线不参与、置顶结果保持置顶)+ 按词法线索报告矛盾(不自动归档,逐对确认走 /health/resolve time-order)+ 报告过期未用 + 画像重写进待审 |
| GET | /sessions |
会话检索(溯源):按词重叠搜回当轮用户发言原文 + sessionId/turn |
| GET | /session-brief |
前台会话卡:本会话的用户诉求 + 本会话沉淀的记忆(草稿与归档不可见);按 session 精确过滤,不传时用最近活动会话兜底 |
| GET | /injections |
注入审计:最近真正进 prompt 的内容(正文预览 + sha256 前 16 位 + id 列表 + 被挤掉的条目;full=1 给原文,kind 可过滤) |
| GET | /derivations |
跨层派生链:每层派生了什么、源现在还成不成立(state 为 fresh / dirty,带失效原因) |
| GET | /reviews |
复审队列:带失效条件、到期该复查的记忆(due / soon) |
| POST | /review |
复审一条:记「看过,还成立」,到期时间推后一个周期 |
| POST | /tags/merge |
标签归并:把大小写等写法变体合并成目标写法(含全局库与草稿) |
| POST | /promote |
程序记忆晋升:把一条记忆写进工作区 AGENTS.md 托管块(幂等);带 from=portrait 则改写画像的某一段 |
| POST | /distill |
只返回候选,不落库 |
| GET | /backups |
整库快照清单(新的在前,带文件数与字节数)与备份目录路径;没有备份时返回空数组 |
| POST | /backup |
立刻做一次整库快照(reason 可选);返回快照名、文件数、字节数与轮转掉的旧快照 |
| POST | /security/scan |
写入安全:扫描任意文本的密钥与注入模式,只报告不落库 |
| GET | /ping |
存活探测 |
数据与隐私
~/.dsh/storages/dsh-memory/
index.json 工作区索引
settings.json 面板里改的设置
workspaces/<目录名>-<hash>/memories.json 每个工作区一个库
workspaces/<目录名>-<hash>/MEMORY.md 人读旁车
workspaces/<目录名>-<hash>/portrait.json 工作区画像
workspaces/<目录名>-<hash>/derivations.json 跨层派生链
workspaces/<目录名>-<hash>/journal/ 每天一个只追加的工作日志
workspaces/_global/memories.json 跨工作区共享的全局记忆
backups/<时间戳>-<原因>/ 整库快照(每天一次 + 每次 Dream 前)
- 主库只落
~/.dsh/storages/dsh-memory,默认不进仓库。 - 打开
mirror才在<工作区>/.dsh-memory/MEMORY.md写人读副本;关掉会撤回。 - 每条写入路径都过
lib/security.js:密钥脱敏 + 注入模式 taint;非 user 来源 taint 隔离成草稿。 - 非回环来源访问
/memory/api一律 403。
测试
npm test # 14 个套件 / 591 项断言
- 检索:54 条记忆 × 60 条查询硬评测,Recall@5 1.000、MRR@10 0.930(自测口径,见 评测说明)。
- 安全:100 条密钥样本全部脱敏;20 条注入样本全部命中;20 条正常文本零误报。
- 简报稳定性:会话级冻结、确定性排序、轮末召回尾部注入去重。
- 客户端:把设置页真的渲染出来,接到真实
store+api上驱动交互。
维护与发布
- 分支:
main是唯一长期分支;推main只跑测试,正式版用v*标签发布;完整流程与验收见skills/release/SKILL.md。 - 发版:
node tools/release.mjs,然后node tools/release-watch.mjs。 - 完整规格、历史章节、导入格式、测试明细与边界讨论:
docs/REFERENCE.md。
文档
| 想了解 | 读 |
|---|---|
| 完整规格(旧版 README 存档) | docs/REFERENCE.md |
| 版本变更日志 | CHANGELOG.md |
| 项目主页(安装 / 看点 / 链接) | bangbang-03.github.io/dsh-memory-portrait |
| 检索方案与基线 | docs/retrieval-eval-2026-10-20.md |
| 简报为什么必须字节稳定 | docs/briefing-cache-safety.md |
| 与 WorkBuddy 个人记忆的差距 | docs/personal-memory-parity.md |
| 市场扫描与竞品 | docs/market-scan-2026-10.md |
| 发版流程 | skills/release/SKILL.md |
参与
- 安装 / 使用问题:用 issue 模板
- 想法与用法:Discussions
- 贡献代码:CONTRIBUTING.md
English
Memory Portrait is a long-term workspace memory plugin for DeepSeek Harness (npm package: @bangbang-03/dsh-memory). It injects a compact index at session start, fetches bodies on demand, recalls relevant memories at turn end with a purely local search, and can distill conversations into structured memories that wait in an approval queue.
What makes it different: the portrait is the main view. Every section carries evidence, versions, and diffs, so you can see how the agent understands the project and why that changed. Memory is treated as a governed artifact: redlines are injected verbatim and cannot be silently edited; every rewrite has a version chain; every injection is audited. dependencies is empty — no shell, no env, no outbound requests.
dsh plugin --profile web add @bangbang-03/dsh-memory
If it saves you from re-explaining your project, a ⭐ helps others find it. Bugs and install issues: open an issue.
License
MIT