dsh-plastic-memory

简体中文 | English
「愿你有一天,能与珍爱之人再次相逢。」——《可塑性记忆》
互动产生轨迹,轨迹沉淀为记忆。记忆是历经提炼的认知结晶,贯穿生命周期,持续塑形,直至最后一刻。
💡 灵感来源
插件取名灵感源自动画《可塑性记忆》(Plastic Memories)。在原作中,拥有独立心智的 Giftia 寿命被严格限制在 81,920 小时(约 9 年 4 个月)。若记忆容量超载且缺乏妥善管理与回收,Giftia 的人格便会发生不可逆的崩溃,异化为失去理智的**「徘徊者(Wanderer)」**。
在 LLM 时代,智能体(Agent)的长期记忆系统同样面临着类似的工程挑战:过期、矛盾、冗余与孤立的记忆不断堆积,导致 Agent 认知漂移、产生幻觉与决策冲突,造成 Token 浪费与输出质量退化。
为此,dsh-plastic-memory 作为一款基于 DeepSeek Harness 的 Agent 记忆插件,提供记忆的存储、分类、检索与治理,赋予 Agent 记忆可塑性(Plasticity)与生命周期(Lifecycle):既能提炼沉淀、精准唤起,也能诊断健康、判定事实冲突、适时遗忘。让有价值的共识历久弥新,让失效的信息有序退场。
🎬 设定对照
| 《可塑性记忆》世界观设定 | dsh-plastic-memory 功能对应 |
作用价值 |
|---|---|---|
| 艾拉的日记 | 对话中沉淀记忆(memory_save) |
从日常对话与任务中提炼记忆点,自动写入保存 |
| Giftia 的灵魂载体 Alma OS | 文件即记忆(Markdown) | 每条记忆为一个标准 Markdown 文件,透明、可编辑、便于维护管理 |
| Giftia 的心智寿命 | 记忆保质与衰退机制 (decayDays) |
引入基于时间维度的记忆新鲜度 |
| 徘徊者(Wanderer) | 记忆矛盾与事实冲突(Memory Rot) | 陈旧与相互矛盾的记忆会干扰上下文,支持针对性扫描并处置 |
| 第 1 终端服务(回收业务) | 记忆治理层(Governance) |
全库记忆体检、置信度刷新、清理问题记忆与孤立节点 |
| 人机搭档协作制 | 用户与 Agent 协同提权(memory_promote) |
Global 全局记忆与跨作用域提升必须由用户显式确认 |
| 最初相遇的节点 | 记忆溯源(memory_source) |
每条记忆均锚定原始对话切片,出处可查可追溯 |
✨ 核心特性
- 🗂️ 记忆分类与可扩展
内置profile/preference/knowledge/project/reference五类,覆盖身份、习惯、知识、项目决策与资源指南,分类保存、按需召回。还能自定义类型,按场景组合要记哪几类。 - 🛡️ 严格的工作区隔离与写入保护
工作区(Workspace)记忆相互物理隔离,互不可见;全局(Global)记忆跨项目只读共享。模型无权直接写入全局域,任何项目记忆提升到全局必须由用户确认,避免全局规则无序扩张与污染。 - 🩺 内建多层治理体系(Governance)
配备记忆体检机制,阻断高危信息写入(如 API 密钥),治理规则冲突,防止长期运行带来的认知退化。 - 🔍 精确的因果溯源(Traceability)
每条记忆沉淀时均锚定原始会话轨迹切片。深入分析时,模型可调用memory_source回溯对话原始背景。
🏗️ 架构概览
工作流简述: 对话中模型触发 memory_save 提炼有效记忆节点,写入前通过安全管线去重并拦截密钥泄露。记忆保存为 Markdown 文件,在会话启动或上下文压缩时以只读快照形式精准注入。存储层之上叠加治理层,持续读取并处置记忆库,抑制上下文退化与规则漂移。
📦 安装
0.2.0 即将发布,含破坏性更新:要求最低 DeepSeek Harness v0.2.1-rc.2。建议等 0.2.0 发布后再正式使用;目前只能安装旧版本,旧版本提供记忆保存、检索、自动注入、健康体检等功能的基础体验。之后升级到 0.2.0 时,已有记忆原地沿用,待处理事项自动迁移。
旧版本 0.1.1-beta.5:
dsh plugin --profile web add dsh-plastic-memory@0.1.1-beta.5
把
web换成你的目标 Profile 名即可(若该 Profile 不存在则自动创建)。安装后插件声明将自动写入该 Profile 的cordis.patch.yml,重启该 Profile 后生效。插件以预构建产物发布到 npm,安装不需要构建授权。
桌面版:先打开一次 DeepSeek Harness 桌面版,让它建好自己的 Profile,然后完全退出,在终端运行下面这条,再重新打开桌面版。dsh命令用 npm 装的或桌面版自带的都可以。dsh plugin --profile desktop add dsh-plastic-memory@0.1.1-beta.5运行环境要求:Node.js
^22.19.0 || >=24,DeepSeek Harness v0.2.1-rc.2 及以上。 中文分词:可选依赖@node-rs/jieba(带各平台预编译二进制)随 npm 安装自动带上,中文检索按词匹配;当前平台装不上时插件照常安装,中文检索退回二字切分,其他功能不受影响。 (DeepSeek Harness 仍在预发布阶段,之后还可能出现破坏性更新;升级宿主前请留意本插件当前支持的版本范围,见顶部徽章和 CHANGELOG。)当前为 beta 阶段,安装命令直接写明版本号;发布稳定版后可直接
dsh plugin --profile web add dsh-plastic-memory。
🚀 快速上手
- 保存记忆:对话中告诉模型需要记住的内容,模型自动识别并写入;下次开启新会话时,已保存的记忆随上下文快照自动注入,无需手动操作。
- 检索记忆:需要回顾时,让模型搜索相关记忆,支持按类型、作用域过滤。
- 查看健康度:让模型检查记忆库整体健康评分,了解当前记忆质量状况。
- 整理记忆:让模型扫描全库,自动检出冲突、冗余、过期等问题并给出处置建议,确认后一键优化。
🖥️ 界面
装好后不用碰 yaml,三处界面都在宿主的 web UI 里:
- 左栏「记忆」页:四个 tab。「待处理」列出等你拍板的事——体检发现的冲突、适合提升为全局的记忆、超出上限的提醒、密钥、读不出的文件,每一项就地处理(以哪条为准、撤销、提升或留在本项目、彻底删除密钥);「全部记忆」按项目 / 全局浏览、打开文件或在访达中显示、删除;「健康」看每一层的分数和问题,右上「体检当前项目」随时体检;「最近删除」找回 14 天内删掉的记忆,被裁决删掉的会标明以哪条为准。页面不要求正在对话,它借用当前项目的一个空闲会话执行命令;一个会话都没有时只显示空态。
- 右侧栏「记忆」tab:这次对话带入了哪些记忆、占了多少上下文、模型新记了什么;带入的记忆之间有冲突可以就地裁决。
- 插件设置页(宿主插件管理里的本插件详情):场景(选当前场景,新建、编辑、删除场景)、记忆类型(查看基础 5 类,改、删、恢复预设类型,增删改自定义类型)、带入上限与超出上限的模式、溯源记忆出处、体检开关与灵敏度、全局记忆的去向,外加一张状态卡。保存即写回 profile 的
cordis.patch.yml,不用重启。
对话里每次记住东西都有一张可删的卡;左栏图标上的圆点只在有事等你决定时亮(琥珀),发现密钥时变红。
🧠 记忆体系
系统内置 5 类基础记忆类型,适用于所有交互场景:
类型 (Type) |
说明 |
|---|---|
profile |
用户的身份、背景、所在地、兴趣与能力画像 |
preference |
用户提出、纠正或确认过的做事要求与习惯 |
knowledge |
经过确认、以后还会用到的事实、规则与经验 |
project |
进行中的项目或个人事项的当前状态与安排 |
reference |
资料、文件与资源该去哪里找 |
场景
场景决定模型能新增哪几类记忆,从类型池里挑选。类型池包括基础 5 类、两个预设类型(procedure 可复用的标准操作流程、decision 决定与承诺:谁定了什么、谁答应了谁什么),以及你自定义的类型。
- 通用(
custom):固定基础 5 类,不能编辑、删除。 - 编码(
coding,默认):基础 5 类 +procedure。 - 办公(
office):基础 5 类 +decision。 - 自己建的场景:在设置页新建,默认勾上基础 5 类,可以去掉。
编码、办公可以增减类型,也可以删除。每个场景 1 到 8 类,通用以外最多建 5 个场景。同一时间只有一个当前场景,整个 profile 共用。切换场景只影响新增:类型池里所有类型的已有记忆照常带入、能搜到。
基础 5 类固定,设置页里只能查看定义。两个预设类型可以改定义(英文名不变),也可以删除:删掉的不再新增,已有记忆照常读取,之后能在设置页恢复。改过的预设存成 customTypes 里的同名一项,删掉的列在 removedPresetTypes 里。
旧版办公模板的 commitment(承诺)并进了 decision,person(人物)已移除。这两类已有的记忆照常读取,但不能再新增。
召回注入模式 (recall)
控制不同记忆类型在上下文中的呈现形式:
| 模式 | 注入行为 | 适用场景 |
|---|---|---|
core |
全文注入:常驻系统上下文 | 高频核心偏好与人设画像 |
search |
索引注入:进入概览索引,模型按需调取 | 详细流程规范与业务知识 |
passive |
静默索引:仅在索引中呈现名称,最大化节约 Token | 低频调用的参考信息 |
自定义类型定义
在设置页的场景弹层里新建,或在配置项 customTypes 中声明(名称不能与内置 5 类冲突)。自定义类型进入类型池,勾进某个场景后才用来新增记忆。在设置页里改英文名时,已存过的记忆可以跟着改名或移到最近删除;删除类型时可以保留这些记忆,或移到最近删除:
customTypes:
ritual:
label: 团队仪式
description: 定期执行的团队流程与规范
whenToSave: 用户提到固定周期执行的流程或仪式时
howToUse: 安排相关工作时按记下的周期和规范来
recall: search
governancePriority: low
decayDays: 90
scenes:
scene-mh2k9x:
label: 团队协作
types: [profile, preference, knowledge, project, reference, decision, ritual]
template: scene-mh2k9x
description、whenToSave 写给模型看:保存记忆时,模型按它们判断这条该归哪一类、怎么写。howToUse 选填,写这类记忆带入对话后怎么用,和记忆一起交给模型。decayDays 是衰退天数:超过这个天数没确认的记忆只标为可能过时,不会失效;null 表示不衰退。
子 agent 写的记忆
DeepSeek Harness 派出的子 agent(包括子 agent 再往下派的)也能用 memory_save 存记忆。这些记忆先是待确认:只落当前项目,不带入主会话,检索时排在其他记忆之后,索引行和检索结果里标「(子 agent 写入,未确认)」。子 agent 存完会在回复里报出来,由主会话决定去留:
- 接受:
memory_confirm的accept-subagent动作,之后和本项目其他记忆一样带入、检索; - 改写:
memory_save update,改完同样算接受; - 丢弃:
memory_forget。
主会话不处理的,一直待确认。你不用逐条过目:主会话觉得某条该进全局时,它照常出现在「待处理」的提升候选里;记忆卡上也会显示「子 agent 写入 · 第 N 层 · 待确认」(接受后是「主会话已接受」或「用户已改」),在记忆页直接改或提升一条待确认记忆也算接受。
子 agent 只能写 knowledge、project 两类(还要在当前场景里),依据(sourceMode)只能是观察或推断,不能用 supersedes、force,只能改自己这个会话存下、还没被接受的。每个子 agent 会话最多新建 subagent.maxSavesPerSession 条(默认 10)。子 agent 写入跟着治理开关走:governance.enabled 为 false 时,子 agent 会话照旧只读。
已知限制:这些规则只约束工具调用。子 agent 带文件工具、直接改记忆目录里的文件时,不受这些规则约束;用 DeepSeek Harness SDK 启动的子进程如果也装了本插件,会被当成主会话。
🛠️ 工具集一览
1. 日常交互工具
| 工具 | 用途与特性 |
|---|---|
memory_save |
沉淀或更新记忆。内置重复性校验与密钥嗅探,遇到近似内容时主动引导 update 或 force |
memory_search |
按相关性检索记忆,中英文查询都可用:同时含全部关键词的记忆排在只含部分关键词的之前,关键词作为整词出现的又排在只作为长词一部分出现的之前(如 scope 之于 readScope);中文和英文写法分开匹配;没有记忆含全部关键词时,结果开头会说明,排第一的那条对上一半以上、但有关键词没对上时,列出各关键词命中几条;排第一的对上的查询内容不到一半、或只有子串命中时,还会提示命中弱、建议换词再搜。这些说明只是提示,搜几次由模型自己判断。不是全命中的那条,头行会标出它完整对上了哪些关键词,或只对上一部分、只以子串出现。match 缺省为 any,按上面的档位返回全部命中;设为 all 只返回同时含全部关键词的记忆,没有这样的记忆时会说明各关键词命中几条,可改用 any 看部分命中。types 按类型(Type)筛选:不填查全部类型;query 留空、只填 types 时列出这几类的记忆;填的类型在范围内没有记忆时,结果会说明范围内有哪些类型、各几条。每条命中带记忆文件的绝对路径,要看全文直接读。支持按作用域(Scope)过滤,默认返回 10 条(上限 50) |
memory_forget |
记忆批量移除:文件搬进 .archive/,删除前自动快照,14 天内可恢复。含密钥的记忆例外:立即物理删除、所有快照里的副本一并脱敏,不可恢复 |
memory_snapshot |
快照管理:手动打标、差异比对(Diff)、历史版本回滚与误删恢复 |
memory_source |
因果溯源:回溯记忆提炼时的原始会话轨迹切片,校验记忆产生的原始意图与上下文背景,防范幻觉 |
2. 记忆健康治理工具(governance.enabled = true)
| 工具 | 用途与特性 |
|---|---|
memory_health |
健康度评分(0–100):评估全库记忆质量;同时列出解析不了被隔离的文件和目录问题(重复 id、缺 .workspace 标记等) |
memory_scan |
全库深度体检:规则层(密钥泄露、超长、孤立引用、破损文件);语义层(冲突、冗余)按需调用 LLM |
memory_confirm |
保质期刷新与处置决策:确认陈旧记忆的置信度以延长生命周期,或对冲突扫描结果进行人工仲裁,或接受子 agent 存的待确认记忆 |
memory_promote |
记忆提权流转:将验证过的项目专属记忆提升至全局(Global)或同步至 AGENTS.md,必须由用户明确指令确认 |
治理工具默认只处理全局和当前项目的记忆,要动其他项目的记忆需带 allowCrossWorkspace: true(用户明确要做全局整理时)。子 agent 会话里,memory_search、memory_health 照常可用,memory_source 只能回查出处在本会话的记忆,memory_save 按「子 agent 写的记忆」一节的规则写入,其余写工具(含 memory_scan、memory_confirm)一律拒绝;记忆照常注入。
📂 存储结构与目录规范
记忆就是文件:磁盘上的 Markdown 是唯一真相,插件不在内存里另存一份。你用编辑器新建、修改、删除文件,下一次工具调用和新会话注入立即反映,不用重启。
<memoryRoot>/
global/ # 全局记忆(跨项目共享)
<name 的 slug>.md # 一条记忆一个文件(YAML Frontmatter + 正文)
MEMORY.md # 生成的索引:列出当前有效的记忆,手改会被覆盖
.archive/ # 已遗忘、已取代的记忆;遗忘 14 天后自动清理
<项目slug>-<hash>/ # 项目记忆(按工作区隔离)
.workspace # 一行:该项目的本地绝对路径
<name 的 slug>.md
MEMORY.md
.archive/
.state/ # 插件自用:快照、待决冲突、扫描缓存、召回统计
索引行末尾带文件名,模型拿到就能直接读原文;.archive/ 是隐藏目录,宿主的 grep 搜不到里面已遗忘的内容。
手动编辑规范
- 新建:一个
.md文件,Frontmatter 最少只要name和type,正文就是记忆内容。id、时间戳、tags、summary、confidence都可以省,插件在下一次写入或会话启动时补齐(id按文件路径派生,之后跟着文件走)。 - 时间戳:接受
2026-09-01、2026-09-01T08:30:00Z、带时区偏移等常见写法;缺省取文件修改时间。 - 修改:改正文或字段后记忆带「已手编」标注,
memory_source会提示出处可能不再对应;用memory_save更新后标注清除。 - 过期:文件里的有效期
validFrom/validTo是本机时间,如2026-11-05 18:00,手改照这个写;只写日期时取文件修改时间的时分。旧版本写的 UTC 时间在下一次写入或会话启动时自动改成这种写法。validTo已过的记忆留在原位,不注入、不检索;memory_health会提醒延长有效期或遗忘。 - 恢复:误删的记忆在
.archive/里,用memory_snapshot恢复,或把文件搬回上一层并把status改成active。 - 格式错误:解析不了的文件单独隔离,不影响其他记忆;
memory_health和memory_scan会列出来,修好即生效。 MEMORY.md是生成物,不要手改。
⚙️ 核心配置参考
在 Profile 对应的 cordis.patch.yml 中调整 plastic-memory 配置:
| 配置项 | 默认值 | 说明 |
|---|---|---|
writeMode |
'proactive' |
写入模式(目前唯一值,后续会扩展更多模式) |
snapshotTokenBudget |
4000 |
每次对话自动带入记忆的 token 上限,对话中检索到的不计入 |
snapshotOverflow |
'relax' |
超出上限时:relax 全部带入并按 25% 一档提醒 / strict 截断索引行并提示漏掉几条 |
evidenceLookup |
'strict' |
证据溯源模式:off(关闭) / strict(仅强信号提示) / active(主动引导) |
template |
'coding' |
当前场景:custom(通用)/ coding / office / 自己建的场景 id |
customTypes |
{} |
自定义记忆类型定义字典,进入类型池 |
scenes |
编码、办公两项 | 场景定义:label 场景名、types 包含的类型(1 到 8 类)。通用场景固定,不写在这里 |
removedPresetTypes |
[] |
删掉的预设类型(procedure、decision):不再新增,已有记忆照常读取 |
governance.enabled |
true |
是否启用主动治理层(体检、健康分、提权) |
governance.health.sensitivity |
'normal' |
健康警报灵敏度:conservative / normal / proactive |
governance.globalPromoteTarget |
'plugin-global' |
提权目标:plugin-global(插件全局域)或 agents-md(~/.dsh/AGENTS.md) |
subagent.maxSavesPerSession |
10 |
每个子 agent 会话最多新建几条记忆(只能在配置文件里改),改了下一次保存生效 |
accent |
'ella' |
界面主题色:ella(艾拉主题色)/ blue-whale(大肥鱼主题色,跟随 DeepSeek Harness 品牌蓝) |
memoryRoot |
'' |
存储根路径,缺省为 ${DSH_HOME:-~/.dsh}/memories |
search.userDictionaryPath |
不设 | 用户词典路径(只能在配置文件里改):追加在内置词典之上,改了下一次搜索生效。要填绝对路径;每行「词 词频 词性」,词频必填,不带词频的词条不生效,例如 插件记忆 10 n。没装 @node-rs/jieba 时不生效 |
🧪 开发与测试
pnpm install --frozen-lockfile
pnpm typecheck && pnpm lint && pnpm test && pnpm build
pnpm host:smoke # 把打包产物装进全新的 dsh 宿主,验证安装与加载(无需 API Key)
pnpm host:contract # 在该宿主里驱动九个工具,验证宿主契约(无需 API Key;提供 Key 时额外运行语义层两项)
开发流程、测试说明与提交规范见 CONTRIBUTING.md;变更记录见 CHANGELOG.md。
📄 License
如果这个项目对你有帮助,欢迎点个 ⭐ 支持一下,十分感谢。
No comments yet. Be the first to write one.