dsh-tool-user-memory
Verifieddsh-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 秒启用。
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(
dshCLI;已在 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 里说:"记住:我喜欢简洁的中文回答"
- 开一个全新会话,直接问:"我的语言偏好是什么?"
- 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) |
整理做什么:
- 合并重复:值归一化后相同的条目只留最新一条,其余软失效(附"与 X 相同"原因);
- 锚定相对时间:含「今天/明天/下周」等相对时间的条目追加一行绝对记录日期(只加一次,不改写你的原话);
- 老化:超过
staleAfterDays的条目进入运行记录,超过autoInvalidateAfterDays的条目自动软失效; - 模型辅助(可选):用一次独立模型调用提出
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