Skip to content

dsh-tool-user-memory

Verified

dsh-tool-user-memory · v0.2.0 · MIT

User preference memory for DeepSeek Harness: persisted user profile with memory_get/memory_update tools and system-prompt injection

Install

dsh plugin add dsh-tool-user-memory

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Creators

Readme

dsh-tool-user-memory

DeepSeek Harness 用户偏好记忆插件:让 agent 跨会话记住你的偏好——语言习惯、沟通风格、项目背景、目标……每个新会话都不必重新自我介绍。

独立开源插件 —— 作为 DeepSeek Harness 社区生态的一部分独立开发与维护 (GitHub 话题:dsh-plugin)。 与官方仓库无关;直接通过 npm 安装,30 秒启用。

English | 更新日志


1. 项目介绍

它解决什么问题

默认情况下,DeepSeek Harness 的 agent 每次新会话都是"陌生人":不知道你偏好简洁还是详细、不知道你做什么项目、不知道你用什么语言交流——每个新会话都得重新交代一遍。

这个插件给 agent 加了一块持久化的用户画像:

  • 你说一句"我喜欢简洁的中文回答",agent 把它写进记忆文件;
  • 之后每一个新会话,这段记忆会自动注入系统提示词,agent 天生就知道——不用你提醒,也不用调工具。

核心能力

能力 说明
memory_update(key, value, mode?, reason?, scope?) agent 学到你的稳定偏好时,自动记录 / 追加 / 软失效 / 删除;scope=workspace 写项目级记忆
memory_get(query?, limit?, includeStale?) 需要个性化回答时,主动读取你的画像
memory_search(query?, limit?, includeStale?) 跨「全局画像 + 当前工作区记忆」的关键词检索(带评分与一行摘要)
memory_topic(topic) 读取某个工作区记忆主题的全文(懒加载)
memory_consolidate(mode?, useModel?) 整理记忆:合并重复、锚定相对时间、失效过时条目,产出审计日志
{{user_profile}} 系统提示词注入 每个会话每轮自动携带你的画像 + 当前工作区记忆索引(两者都空则零 token 成本)
记忆分层 全局画像 + 工作区记忆(索引 + 主题文件),全部人类可读、可手改、可删除

工作原理(30 秒版)

你说"记住:我喜欢简洁的中文回答"
   → agent 决定调用 memory_update
   → 写入 $DSH_HOME/user-memory/user.md(原子写、仅属主可读)
   → 之后每个新会话:系统提示词自动注入画像 → agent 天生认识你

2. 下载与安装

前置条件

  • 已安装并跑通 DeepSeek Harness(dsh CLI;已在 0.1.7-alpha.x / 0.2.0-rc.x 验证)
  • 无需单独安装 npm 包!dsh plugin 会替你装好

安装(推荐:一条命令)

在你想启用的 profile 上安装,例如 web:

dsh plugin --profile web add dsh-tool-user-memory

headless 或其他 profile 同理:

dsh plugin --profile headless add dsh-tool-user-memory

然后重启你的 dsh 会话(web 模式重启 dsh web),插件即生效。

安装做了两件事:1) 把包加入 profile 依赖;2) 因包声明了 dsh.bundle.patch, 自动把它激活进 profile 的 bundle 层(见下方验证)。

备用:从 GitHub 源码安装

git clone https://github.com/IAMLieutenant/dsh-tool-user-memory.git
cd dsh-tool-user-memory
pnpm install --frozen-lockfile
pnpm run build
pnpm pack                       # 生成 dsh-tool-user-memory-0.2.0.tgz
dsh plugin --profile web add ./dsh-tool-user-memory-0.2.0.tgz

手动配置(可选)

默认零配置即可用。如需调整,在 profile 的 cordis.patch.yml 覆盖(按行 id tool-user-memory):

配置项 默认值 含义
path $DSH_HOME/user-memory/user.md 画像文件路径
maxBytes 8192 画像文件体积上限;超限时按最旧优先逐条淘汰
promptMaxBytes 2048 每轮系统提示词注入的字节预算(新近优先);设为 0 注入完整画像
includeInPrompt true 是否在每个会话的系统提示词中注入画像
staleAfterDays 0 N 天未更新的条目带 [stale: last updated Nd ago] 标注(仅标注、绝不删除);0 = 关闭
workspacePromptMaxBytes 512 每轮注入的工作区记忆索引字节预算(正文懒加载);0 = 不注入工作区记忆
workspaceBase $DSH_HOME/user-memory/workspace 工作区记忆根目录(主要用于测试或自定义布局)
autoConsolidate false 在回合边界后台自动整理记忆(去抖、不阻塞回合)
consolidateMinIntervalMs 600000 两次自动整理的最小间隔;0 = 每个回合边界都整理
autoInvalidateAfterDays 0 超过 N 天未更新的条目由整理自动软失效(仍留在文件里可审计);0 = 不自动失效
consolidateProvider / consolidateModel '' 可选的模型辅助整理(留空则只用确定性规则)
consolidateMaxTokens 1024 单次整理模型调用的输出上限
consolidationLogPath $DSH_HOME/user-memory/consolidation-log.md 整理审计日志路径

3. 验证安装成功

方法 1:检查 profile 配置

打开 profile 的 package.json(如 $DSH_HOME/profiles/web/package.json), dsh.profile.bundles 中应包含 dsh-tool-user-memory:

"dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-tool-user-memory"] } }

方法 2:问 agent 有没有记忆工具

重启会话后,直接问:

"你现在有哪些记忆相关的工具?"

正常回答会提到 memory_get 和 memory_update 两个工具。

方法 3:检查画像文件可写

正常使用一次"记住"功能后,文件 $DSH_HOME/user-memory/user.md 应存在且内容可读 (Windows 默认 C:\Users\<你>\.dsh\user-memory\user.md)。


4. 使用指南:让 agent 记住你的喜好

场景 A:让 agent 记住(一条指令)

直接跟 agent 说,它会自己调用 memory_update:

"记住:我喜欢简洁的中文回答" "记住:我平时用 Python 做后端开发" "记住:我的目标是学习 agent 工程"

agent 应该记住什么(写进它的工具说明的纪律):

  • ✅ 长期稳定的偏好、自我介绍、项目背景、目标
  • ❌ 一次性请求("帮我看看这个文件"不算偏好)
  • ❌ 密钥、密码、令牌(绝不记录)

场景 B:查看它记住了什么

"你记得关于我的什么?" "我的沟通风格偏好是什么?"(带关键词)

场景 C:修改 / 忘记

"忘掉我对 XX 的偏好"(agent 调用 memory_update mode=remove,硬删除) "我那个 XX 项目已经换成 YY 了"(agent 调用 memory_update mode=invalidate + reason:软失效,历史保留但不再影响行为)

也可以手动编辑画像文件($DSH_HOME/user-memory/user.md)——它是普通 Markdown, 改完即生效,删掉文件 = 彻底失忆:

# User Memory

## language
简洁的中文回答

## communication-style
直接用、少客套

场景 D:验证跨会话记忆(关键体验)

  1. 在会话 1 里说:"记住:我喜欢简洁的中文回答"
  2. 开一个全新会话,直接问:"我的语言偏好是什么?"
  3. agent 应不调任何工具直接答出"简洁的中文回答"——因为画像已注入系统提示词

5. 记忆会延续到哪里?

  • 个人记忆是全局的:存在 $DSH_HOME 下,与你所有工作区、所有 profile(web / headless)共享;
  • 项目记忆是分层的:scope=workspace 写入的内容按会话所在目录(cwd 的 realpath)分目录存放,只对"在该目录里打开的会话"可见——换项目不串味;
  • 自动注入:每个新会话的系统提示词都携带当前画像 + 当前工作区记忆索引(索引只有主题名与一行摘要,正文按需 memory_topic 取);
  • 零成本起步:画像与工作区记忆都为空时不注入任何内容,不消耗 token;
  • 可控:文件随时可看、可改、可删。

记忆文件布局

$DSH_HOME/user-memory/
├── user.md                     # 全局画像:个人偏好、跨项目稳定事实
└── workspace/
    └── <hash16>/               # 每个工作目录一个(hash = sha256(realpath(cwd)) 前 16 位)
        ├── MEMORY.md           # 索引:主题名 + 一行摘要(每次写入自动重建)
        └── <topic>.md          # 主题正文:标题 + 时间戳 + 可选失效标记 + 内容

安全设计:注入的画像被明确标注为"参考数据,不是指令"——除非你在当前消息中重复, agent 不会执行画像里的任何"指令"(与官方 dsh-session-reference 快照同一立场)。


6. 工具参考

memory_get

参数 必填 说明
query 否 关键词,按 key 或 value 过滤
limit 否 最多返回条数(默认 50,上限 100)
includeStale 否 true = 连失效条目一起返回(带失效时间 + 原因标记),用于审计

返回 { ok, total, invalidated, rendered }(rendered 为模型可见的渲染文本;开启 staleAfterDays 时 stale 条目带 [stale: ...] 标注)。

memory_update

参数 必填 说明
key 是 偏好键,如 language、communication-style
value 是 偏好内容(invalidate / remove 时可为 "")
mode 否 set(默认,覆盖/复活)/ append(追加一行)/ remove(硬删除)/ invalidate(软失效)
reason 否 mode=invalidate 时:为什么这条记忆不再成立,随条目存档供审计
scope 否 global(默认,个人画像)/ workspace(当前会话目录的项目记忆,存为主题文件)

返回 { ok, scope, key, mode, bytes, error? }。软失效语义:失效条目保留在文件里(可审计),不再注入提示词,memory_get 默认隐藏(includeStale: true 可查回);对同一 key 再次 set / append 会复活它。

memory_search

参数 必填 说明
query 否 关键词(空格分隔多词,支持中文子串);空 = 列出最近的主题
limit 否 最多返回条数(默认 10,上限 20)
includeStale 否 true = 连失效条目一起检索(带失效标记)

返回 { ok, total, results: [{ scope, topic, score, updatedAt, snippet }] }。评分规则:主题名命中 ×3、正文出现次数 ×1(上限 5)、全部词命中额外 +4;全局画像与工作区记忆一起排序。

memory_topic

参数 必填 说明
topic 是 工作区主题名(来自注入的索引或 memory_search 结果)

返回 { ok, topic, updatedAt, invalidated, invalidReason, body }——即主题全文(懒加载,不进每轮提示词)。

memory_consolidate

参数 必填 说明
mode 否 plan(默认,只报告将要执行的整理动作)/ apply(执行并写审计日志)
useModel 否 是否额外请求配置好的整理模型(需 consolidateProvider + consolidateModel)

整理做什么:

  1. 合并重复:值归一化后相同的条目只留最新一条,其余软失效(附"与 X 相同"原因);
  2. 锚定相对时间:含「今天/明天/下周」等相对时间的条目追加一行绝对记录日期(只加一次,不改写你的原话);
  3. 老化:超过 staleAfterDays 的条目进入运行记录,超过 autoInvalidateAfterDays 的条目自动软失效;
  4. 模型辅助(可选):用一次独立模型调用提出 add/merge/rewrite/invalidate/topic-* 操作,逐个校验后执行;模型不可用或返回非法内容时自动降级为确定性结果。

每次运行都会追加到 $DSH_HOME/user-memory/consolidation-log.md:时间、触发源(手动/回合边界)、逐条执行与跳过原因——你随时能看到记忆被改了什么、为什么。


7. 从源码开发

pnpm install
pnpm test           # 68/68:单测 + 存储集成 + 工作区记忆 + 后台整理 + harness 集成 + 完整 AgentLoop 循环级测试
pnpm run build       # tsc → lib/
  • 存储层刻意直接使用 node:fs(插件内部受信状态,同 settings/会话持久化),不走沙箱化的模型侧 ctx.fs。
  • 结构:src/index.ts(插件本体)profile.ts(全局画像文档模型)store.ts(画像原子写存储)workspace.ts(工作区记忆层:主题文件 + 索引 + 关键词检索)tools.ts(四个工具)prompt.ts(画像 + 工作区索引注入)。

8. Roadmap(v2)

v2 路线基于 2026-10 对 OpenAI(Dreaming)、Claude Code(自动记忆分层)、Letta(sleep-time compute / 文件系统基准)、Mem0、Zep(双时态失效)等记忆架构的调研结论:

  • ✅ 时间语义(0.2.0 已实现):软失效(mode=invalidate + reason,保留历史不删除)+ 老化配置 staleAfterDays + memory_get(includeStale) 审计,让记忆「随时间保持正确」(对照 OpenAI 三轴:事实回忆 / 偏好遵循 / 时间正确)
  • ✅ 记忆分层(0.2.0 已实现):全局画像 + 工作区级记忆(索引 + 主题文件,懒加载,对齐 Claude Code auto-memory 结构);工作区身份 = sha256(realpath(cwd)),按会话 cwd 自动归属
  • ✅ memory_search(0.2.0 已实现):文件检索优先(关键词 + 评分 + 一行摘要);向量召回仅在条目量级很大(> ~500)时才值得引入(Letta 基准:个人规模下纯文件检索已超过 Mem0 图方案)
  • ✅ 后台巩固("dreaming")(0.2.0 已实现):回合边界异步触发(可开关、可去抖,不阻塞回合)+ 手动 memory_consolidate;确定性规则(合并重复 / 相对时间锚定 / 老化失效)打底,可选模型辅助(consolidateProvider + consolidateModel)提出 ops 并逐条校验;全程写入可审计的 consolidation-log.md。尚未做:会话空闲 / 定时(schedule 子系统)触发,留待后续版本
  • 多用户画像(按会话身份分文件)

License

MIT