DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

@huai_xin/dsh-memory

Memory

Cross-session long-term memory and per-session presets for DeepSeek Harness: YAML memory notebooks injected into the prompt, read and edited by the model, kept in sync across sessions, plus Markdown presets that replace the harness identity.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add @huai_xin/dsh-memory@0.4.0
READMECompatibilityVersions

Compatibility and provenance

Memory is published as @huai_xin/dsh-memory and currently resolves to version 0.4.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
11/4/2026

Versions

0.4.0stable
11/4/2026
0.3.7stable
11/2/2026
0.3.5stable
11/1/2026
Show 6 more versionsCollapse versions
0.3.1stable
11/1/2026
0.3.0stable
11/1/2026
0.2.0stable
10/31/2026
0.1.4stable
10/30/2026
0.1.3stable
10/30/2026
0.1.2stable
10/29/2026

Related plugins

Loading related plugins…

Latest
0.4.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
606.9 kB
Files
58
Surface
web
License
MIT
Source
npm
GitHub
★ 1
Weekly downloads
0
Last push
11/4/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in memory-context.

Experimental Session Search@deepseek-ai/dsh-experimental-session-searchGive Agents tools to search and read earlier sessions from the current workspace.Hindsight Coding Agents@vectorize-io/hindsight-coding-agentsReflect-only Hindsight long-term memory for coding agents (harness-pluggable: opencode, …), with automatic background ingestion (no setup CLI).Contextdsh-contextA DeepSeek Harness plugin for context insight and management, with context dashboard and context command, for understanding how the context is made of, and how it evolves.Memory Plugin@openviking/dsh-memory-pluginOpenViking memory and context bundle for DeepSeek Harness

README

dsh-memory

给 DeepSeek Harness 用的跨会话长期记忆插件。

记忆就是磁盘上的 YAML 文件,按标题树组织。插件把这些文件注入提示词,给模型三个工具去读写,并在别的会话改动之后给本会话发合并后的、不唤醒变更通知。空闲会话在你发来下一条消息时检查累积变更;正在运行的会话每 5 秒检查一次,也就是最多每 5 秒收到一条提醒。另有一份日志(短期记忆):一天一个文件,一条一句话,用来记"今天发生了什么"。还有一份预设:一段纯文本,选中后整体替换提示词最开头的 harness identity,人设卡、行为准则这类开场文本放这里。

  • 记忆在会话之间共享,重启、换窗口、换工作区都还在。
  • 模型改记忆前必须先读,写的时候校验版本,不会覆盖掉别人的改动。
  • 别的会话动了记忆,这边只收到"哪几个标题变了",要细节时再自己读。
  • 注入的文本和 memory_edit 的工具描述按会话冻结:会话开着的时候记忆文件再怎么变,这个会话拼出来的提示词前缀都不动,供应商的前缀缓存才能一直命中;变化走通知。闲过一个保留窗口(默认 60 分钟)才算另起一段,重新生成。

定位

主要给聊天、扮演、轻量编程当跨会话长期记忆用。它有两个有意为之的取舍:

没有自动召回。 每次组装提示词就把记忆文件整份注入,不检索、不算相关性、不排序。原因有两条:一是没找到足够好的召回方案,召回错了比不召回更糟,模型会被一段"看起来相关其实是别的场景"的记忆带偏;二是记忆存量本来就不大,塞得进提示词就没有先筛一遍的必要。

以后也许会加基于关键词的轻量召回(近期目标第一条),但那只是存量变大之后的兜底,不改变"整份注入"这条主路径。

真正想做的是可自定义的记忆结构。 插件不规定你该建哪些文件、该有哪些标题:file_name、desc、format、标题树、inject_ignore 全都写在文件自己身上,所以调整结构不用改插件、也不用动配置。

几种常见的搭法:

想记什么大概长这样
长短期记忆一个 长期记忆 存稳定的事实和偏好;当天的事先记日志,隔几天再摘要进长期
行为准则一个 行为准则,一级标题就是场景(回答风格、拒绝什么、扮演谁),正文写具体要求
角色设定一个 角色,或每个角色一份文件;format 里写清"只记这个角色说过做过什么,别混进别的角色"
学习感悟一个 感悟,一条一个二级标题,keyword 打标签,以后按标签翻
备忘录一个 待办,inject_ignore 跳过 update_at 和 keyword,只留正文

有个经验:一个文件当一份用途。因为注入顺序(fileOrder,面板里拖动)和 inject_ignore 都是按文件走的——"每轮都必须看到"的准则单独一个文件放在最前,"偶尔翻一眼"的备忘录另起一个,互不干扰。同一个文件里再按标题树分章节。


安装

npm install @huai_xin/dsh-memory

插件以 bundle 形式挂到 profile 上。装好之后,在 profile 的配置里加载它的 cordis.patch.yml:

# cordis.patch.yml —— 只挂载插件,不写配置值
- insert:
    - id: memory
      name: '@huai_xin/dsh-memory'

想跟着仓库源码走,就把 node_modules 里那份换成指到本地的链接(npm install ../dsh-memory 或 link: 依赖都行),改动不用重新发版。

运行时依赖 yaml 和 @deepseek-ai/schemastery(配置 schema 用)。

首次安装

安装包里带了一份默认记忆内容和一份出生清单,第一次启动时写进数据目录:

  • defaults/memory/*.yaml → ~/.dsh/dsh-memory/.memory/:六份起步的记忆文件(SOUL / ME / HIM / MEMORY / ENVIR / SKILL),里面填的是占位((暂无))和几条基本规则。已经有同名的文件就不覆盖——升级一份用了一阵的安装时,这些默认文件只补空缺。
  • defaults/BOOTSTRAP.md → ~/.dsh/dsh-memory/BOOTSTRAP.md:一份出生清单,写着"先跟用户把灵魂、身份、关系聊出来,再一项项写回记忆"。它在的时候,每一轮组装都放在提示词最前面(连着文件路径一起给,模型可以直接改它);文件不在就什么都不加。

清单的完成状态写在它自己的 frontmatter 里:全部写回之后把 status: pending 改成 status: complete,插件读到就把它删掉,提示词里也就不再有它。删掉之后不会被重新播种:哪个默认文件已经给过,记在 state/defaults-seeded.json 里,所以自己删掉的文件不会在下次启动时冒出来。

配置

配置写在插件的数据目录里,和它配置的东西挨着:

~/.dsh/dsh-memory/config.yaml         # 配置,在面板里改当场生效;手改文件要重启 Harness
~/.dsh/dsh-memory/.memory/*.yaml      # Global 记忆文件
~/.dsh/dsh-memory/preset/*.md         # 预设(纯文本,一个文件一份)
~/.dsh/dsh-memory/state/sessions/     # 会话快照
~/.dsh/dsh-memory/state/preset/       # 每个会话选了哪一份预设
<workspace>/.memory/*.yaml            # Workspace 记忆文件

优先级:config.yaml > profile 里的插件配置 > 内置默认值。文件不存在就用默认值,YAML 写坏了整份忽略并打一条 warning。

键默认说明
snapshotTtlMinutes10080会话快照保留分钟数(7 天);闲这么久就丢掉,下次发消息重新生成。前缀缓存一般 5–60 分钟,按供应商的规则调;0 关闭清理
logSummaryMaxChars60一条日志摘要(写在标题里)的字数上限
injectLogtrue把最近几天的日志也放进提示词
logInjectEntries0注入时每天最多带多少条日志;0 表示不限
logInjectGlobalDays3全局日志带最近几天
logInjectGlobalDetailDays1其中最新几天带正文,其余只剩标题
logInjectWorkspaceDays2工作区日志带最近几天
logInjectWorkspaceDetailDays1其中最新几天带正文,其余只剩标题
fileOrder[]注入时记忆文件的先后;列出的按给的顺序在前,没列出的按文件名跟在后面。只影响注入。不在设置页里填——在面板左侧拖动文件即可
defaultPreset''新建会话自动使用的预设(名字要对应 preset/ 下的一份文件;'' 表示不使用)。设置页里是一个下拉框,不用手写

目录不可配置:Global 记忆固定在 <DSH_HOME 或 ~/.dsh>/dsh-memory/.memory,工作区记忆固定在 <workspace>/.memory,想换位置就改 DSH_HOME。这样一个写错的路径不会让插件安静地读到别处去。

面板

对话区顶部标签页里点「记忆」,里面有「预设」「全局」「工作区」「设置」四个标签。

  • 「预设」是开场身份:左边列着 ~/.dsh/dsh-memory/preset/*.md 里的每一份,点一份在右边「修改」栏里编辑,另一栏「预览」跟着草稿走。清单上方单独一块是「DSH 默认身份」——不用预设时,提示词开头保留宿主原生那一句。正在用的那一份在编辑栏头显示「使用中」,别的显示「使用」按钮——点下去会在表头亮一条警告(「可能破坏前缀缓存」+ 确认切换 + 取消),按确认后这份预设才整体替换提示词最开头的 harness identity。清单上方那块「DSH 默认身份」不亮警告:它右边的「使用」自己就地变成红色的「确认切换」,再点这一下才切过去,点窗口别处(或按 Esc)就撤回。人设卡、行为准则这类一整段的开头文本放这里,不用挤进记忆文件。详见下文。
  • 「全局」「工作区」是浏览器:左边一列是该作用域现有的记忆文件(顶上分「记忆文件」和「日志」两个货架),点一个,右边分成「原文」和「注入效果」两栏。
  • 「原文」把文件画成卡片,不是丢一整段 YAML 给人看:顶上一张元数据卡(文件名、描述、更新格式、不注入的值),下面是标题树,一级标题一张卡片,卡里是「更新时间 / 关键词」、正文、以及缩进排开的子标题。卡片标题可以点开收起。
  • 卡片上的字就是编辑器:描述、更新格式、每个标题的正文和关键词都能直接改,改完按卡片右上角的「保存」落盘(没改过按钮是灰的,update_at 由插件维护、不给改)。元数据卡和内容卡各有一个「保存」,只保存各自那一半。
  • 标题卡左边的抓手可以拖动改顺序:同一层里把一张卡拖到另一张上,就换了这层的先后(注入和 memory_read 里的顺序都跟着变);跨层拖不动,拖动只是重排兄弟。改动先在面板里,按内容卡的「保存」才落盘。日志文件不能拖——日期和时分是插件按规则排的。
  • **「不注入的值」**后面跟一个 +,展开一个两层菜单(顶层 / 一级标题 / 二级标题 … × 更新时间 / 关键词 / 正文),点一个加一个。关键词是自由词,+ 点开直接打字回车。
  • **「注入效果」**是它出现在提示词里的样子,右上角能在原始文本和预览(Markdown 渲染)之间切。
  • 左边每一行右边的 × 删整份文件:点下去这一行的 × 变成红色的「删除」和「取消」,再点「删除」才真的删;记忆货架下方还有一个虚线按钮新建文件(预设页签在清单上方)。都在栏内完成,不弹系统对话框——新建失败时输入框不关、名字不清,改个名字再回车即可。日志货架只有删除,没有新建:日志的一天由写入产生。
  • 按住一行拖到别的位置,就改了注入顺序(列表里的先后就是注入的先后;日志那一栏按日期排,不参与)。
  • 「工作区」跟着当前对话走:换一个会话,它显示的就是那个会话的工作区。
  • **「设置」**把可见的每个键做成一栏,填好保存即可;写回同一个 config.yaml(只改那几行,注释不动),当场生效,不用重启。fileOrder 不在这里(在左侧拖动排序),defaultPreset 在最上面单独一栏用下拉框选,两者都不画通用输入框。

数据放在哪

~/.dsh/dsh-memory/.memory/*.yaml        Global 记忆文件(所有工作区可见)
~/.dsh/dsh-memory/.memory/log/*.yaml    Global 日志(一天一个)
~/.dsh/dsh-memory/BOOTSTRAP.md          出生清单(装好就有,做完自动删)
~/.dsh/dsh-memory/preset/*.md           预设(文件名就是预设名)
~/.dsh/dsh-memory/state/sessions/*.json 每个会话一份快照
~/.dsh/dsh-memory/state/preset/*.json   每个会话选了哪一份预设
~/.dsh/dsh-memory/state/defaults-seeded.json  已经给过哪些默认文件
<workspace>/.memory/*.yaml              Workspace 记忆文件(只对当前工作区可见)
<workspace>/.memory/log/*.yaml          Workspace 日志

目录在第一次用到时自动创建。记忆文件是普通 YAML,可以直接用编辑器改——插件会重新加载并合并变更:空闲会话在你下一次发消息时检查,正在运行的会话每 5 秒检查一次(最多每 5 秒一条提醒)。

预设

预设是一段纯文本,用来替换提示词最开头的 harness identity(原生那句 You are an AI agent powered by DeepSeek Harness.)。记忆负责把 persona 换成记忆本身,预设再把 identity 换掉——一段长的人设、开场白或行为准则放这里,不用挤进记忆文件。

  • 插件不自带预设:装好之后 ~/.dsh/dsh-memory/preset/ 是空的,面板里只有「DSH 默认身份」一块。用预设就自己写一份放进去,或者点「+ 新建预设」。升级插件不会往这个目录里塞任何东西。
  • 新建一份预设:往 ~/.dsh/dsh-memory/preset/ 里放一个 .md(文件名去掉扩展名就是预设名),或者点左栏「DSH 默认身份」下面那个「+ 新建预设」建一份空文件。在右边改完点保存就是改这份文件。名字不能含 \ / : * ? " < > |,不能以句点开头,不能以空格或句点结尾,最长 64 个字符。改文件、删文件约 200ms 后自动重载,不用重启。
  • 一个会话用哪一份:左栏点名字只是打开它来编辑;编辑栏头有「使用」按钮,点了会先在表头亮一条警告(「可能破坏前缀缓存」),按「确认切换」才真正生效——切换会作废一次前缀缓存,所以要先确认。不想用预设时,点上方「DSH 默认身份」那一块右边的「使用」:那块不亮警告,按钮自己就地变成红色的「确认切换」,再点一下才切过去,点窗口别处或按 Esc 就撤回;它正被使用时显示「使用中」。后端接口是 runtime.setPreset(agent, name),传 '' 表示不用预设。
  • 没用预设就保留 DSH 默认身份(宿主原生那句 harness identity),正用着的预设文件被删掉也回到它:没有东西可替换时不动宿主。
  • 新建会话那一行(输入框上方、工作区和「创造模式」右边)也有一个「预设」下拉框:开口之前就选好,选完直接生效,不用确认——会话还没开始,打断不了任何上下文。
  • 想每次新建会话都从同一份预设开始:设置页签最上面「预设」那一栏选一份,选「不使用预设」就不带。它只影响之后新开的会话;已经选过预设的会话不会被改动,默认预设文件被删掉也会安静地回到 DSH 默认身份。删掉正被设为默认的那份预设时,这里的默认值会跟着回到「不使用预设」,不会留一个指不到文件的名字。
  • 预设不按会话冻结:切预设或改预设文件,下一次组装就生效——这会作废一次前缀缓存,是有意的。
  • 预设里写 {{…}} 不会被当成宿主变量,原样进入提示词。
  • 别的插件若关掉了 harness identity(includeHarnessIdentity: false),预设会补在最前面;不选预设就什么都不补。
  • 预设不是记忆:不受 inject_ignore、日志规则或三个工具影响,也不参与通知。

记忆文件长什么样

meta_data:
  file_name: 我的记忆
  desc: 记录我和用户之间的一些回忆,以及我想要记住的事
  format: |
    写这个文件放什么、什么时候该更新、更新成什么样。
    这段只出现在 memory_edit 的工具描述里,不进提示词。
  scope: Global
  inject_ignore:           # 不写就是全都注入;下面两项是新建时预填的默认省法
    - update_at
    - keyword

data:
  我们经历过的一些事:
    update_at: 2026-10-27T03:18:36+08:00
    desc: 一级标题的正文
    keyword: [回忆]
    我们之间的互动:
      desc: 二级标题的正文

字段说明:

  • file_name — 模型用它寻址,同一会话能看到的目录里必须唯一。
  • desc — 这个文件放什么。会注入提示词。
  • format — 怎么写这个文件的说明。不注入提示词,只进 memory_edit 的工具描述。
  • scope — Global 或 Workspace。
  • inject_ignore — 注入时跳过哪些内容。可选 t1 t2 t3 t4、desc keyword update_at,以及 t2.desc 这种组合。新建文件不给这项时,落的默认就是 update_at、keyword 两条;想注入回来就把对应那行删掉,写 [] 就是全都注入。已有文件里不写就是全都注入。读取不受它影响。跳过标题时会连同子标题一起跳过,比如跳过 t1 就是跳过一级标题,以及其下所有内容。一份文件只要什么都没剩下(列了 t1,或者里面根本没有标题),整个文件都不出现,连文件头也没有——但 memory_read 照旧读得到,memory_edit 的描述里也照旧列着它的 format。
  • update_at — 工具自动写,不要手填。落盘是本地时间带时区偏移(2026-10-27T03:18:36+08:00)。

正文里不能出现标题行:任何一行(第一行,或者换行之后的某一行)以 # 开头都会被读成标题,写进去就成了一条不存在的标题,之后的编辑会指着错的地方。要建标题就把层级写在 heading_path 里(# 标题 > ## 子标题),正文别用 # 打头。标题最多 4 级,同级不能重名。

落盘的完整形状见 docs/记忆文件格式.md。

日志长什么样

一天一个文件,放在 log/ 下,文件名就是日期。meta_data 只有 file_name 和写死的 desc,其余规则是固定的,写在 memory_edit 的工具描述里:

meta_data:
  file_name: 2026-10-27
  desc: 用来记录和“他”之间的互动       # 全局;工作区是「用来记录项目相关操作」

data:
  2026-10-27:                               # 一级标题固定是当天日期,和 file_name 相同
    update_at: 2026-10-27T12:35:10+08:00
    12:35 讨论了日志设计:                     # 二级标题是「时分 + 摘要」
      update_at: 2026-10-27T12:35:10+08:00
      desc: 用户否掉了自动生成时间标题,说让模型自己写;正文就是不限长度的细节。
  • desc 由插件按 scope 写死,模型改不了(memory_manage 拒绝改日志的元数据)。
  • 一级标题只有一个,固定是当天日期;写的时候 heading_path 必须写全 # yyyy-mm-dd > ## hh:mm 摘要 这一种形状。
  • 二级标题是 HH:MM 摘要(本地时间,09:05 不是 9-5),摘要受 logSummaryMaxChars 限制,条目的 desc 就是不限长度的细节。上限只在新写一条、或改动摘要本身时校验:把上限调低之后,之前超长的旧条目照样能改正文、改关键词、只改时分,不用为了绕过检查去改摘要。
  • 条目按时间排序,改名换了时分也会自动挪到新位置。
  • 二级条目可以改名:old_string 填 ## 12:35 旧摘要、new_string 填 ## 09:10 新摘要,正文和关键词不动。一级标题(当天日期)改不了——它就是 file_name。
  • 正文里不能出现标题行:任何一行以 # 开头都会被读成标题。要改条目的时分或摘要就走改名(见上一条),别把标题行写进正文。
  • 当天文件在启动和零点自动创建;只写得了当天,不能删除。
  • 关键词挂在二级标题上(一级标题没有),可以和写正文放在同一次调用里。
  • 日志默认也进提示词(injectLog: true),按上面的天数规则带最近几天;关掉之后就只能按日期主动读。
  • 落盘的完整形状见 docs/日志文件格式.md,读出来的样子见 docs/日志返回格式.md。

三个工具

memory_read — 读。scope 决定查哪个目录(Global 或 Workspace):传了 file_name 就必须给 scope;只看清单时可以不给,给了就只列那一层,不给就列全部。省略 file_name 返回文件清单(解析失败的坏文件也会列出来,标明「解析失败,改好之前不能读写」并带上错误原因),省略 heading_path 返回整个文件。读取结果不受 inject_ignore 影响。file_name 写成日期就是读日志:2026-10-27 读一天,2026-10-26..2026-10-27 读连续几天;heading_path 用 12:00..14:00 在选中的每一天里按时间收窄。范围用 ..,路径用 >,两种符号不混用。读出来的形状见 docs/通用返回格式.md 和 docs/日志返回格式.md。

memory_edit — 改正文、关键词;改标题名;删标题子树。scope 必填,指定改全局那份还是工作区那份。调用前必须先 memory_read,插件会校验读到的版本。file_name 写成日期就是写日志:heading_path 必须写成 # 2026-10-27 > ## 12:35 讨论了日志设计,new_string 就是这条的正文;关键词也挂在这一级上。日志条目要改时分或摘要,就把 old_string / new_string 都写成标题行(## 12:35 旧摘要 → ## 09:10 新摘要);一级的日期改不了。返回一行摘要,开头带 [Global] 或 [Workspace],后面是改到的标题路径,# 的个数和层级一致,例如 [Global] 已更新 我的记忆 > # 沟通方式。返回值只报路径,不回显正文——写进去多少字,答案都只有这一行;要确认内容就再 memory_read 一次。日志的路径不重复日期(一级标题就是文件名),剩下的那级照旧带 ##:[Global] 已新建 2026-10-27 > ## 12:35 讨论了日志设计。

memory_manage — 新建记忆文件、改文件的 desc / format / inject_ignore、改名,或删掉整份文件。新建时省略 file_name、只给 new_file_name;给了 file_name 再给一个不同的 new_file_name 就是改名(旧文件删掉,不会留两份);new_file_name 传空字符串就是删除整份文件。返回 [Global] 已保存记忆文件 <文件名> / [Global] 已将记忆文件 <旧文件名> 改名为 <新文件名> / [Global] 已删除记忆文件 <文件名>。日志的元数据由插件管理,这里改不了也删不了。

子 agent 只能 memory_read,不能改记忆。

近期目标

按优先级从高到低。下面的都还没有做完,写在这儿是为了先把形状和难点定下来。

1. 基于关键词的自动召回。 现在是把记忆文件整份注入,存量真的变大就塞不下了。目标是用关键词先筛一遍,只注入相关的那部分——keyword 字段、标题里的词、desc 里的词都可以作为匹配依据。

难点不在匹配,在它和前缀冻结天然打架:召回结果随话题变化,一召回注入文本就变,前缀缓存立刻失效。所以真做的时候大概率是「会话开始(或快照重建)时按当时的话题召一次,结果跟快照一起冻结」,而不是每轮重新召回。每轮召回省下的 token 与打掉缓存多花的钱要先算清楚,可能并不划算。

2. 固定频率注入的自定义消息。 按条数或按时间间隔,往对话里固定插入一条内容:一句话,或某个记忆文件的全部内容。可以做定时提醒,也可以做"心情随时间变化"这类效果。

实现上倾向追加到对话里(像变更通知那样发一条、不唤醒),而不是改系统提示词——改提示词就是改前缀,而且一条提醒本来也不该常驻。

文档

docs/ 下是形状参照,不参与运行:记忆文件格式、日志文件格式、通用返回格式、日志返回格式。

开发、架构与改动指南见 AGENTS.md。

许可

MIT,见 LICENSE。