dsh-tool-user-memory
Đã xác minhdsh-tool-user-memory · v0.3.0 · MIT
为 DSH 提供跨会话用户偏好与项目记忆。
Cài đặt
dsh plugin add dsh-tool-user-memory Xác nhận layer đã áp bằng dsh --profile default --dump-config — xem hướng dẫn cài plugin.
Mã nguồn
Thẻ
Tác giả
Readme
dsh-tool-user-memory
面向 DeepSeek Harness 的持久化记忆插件,基于 Cordis 插件接口实现。插件将用户偏好和项目背景保存为本地 Markdown 文件,并通过系统提示词与工具调用,为后续会话提供可复用的上下文。
支持全局用户画像、按工作目录组织的项目记忆、关键词检索、软失效和记忆整理。本项目由社区独立开发和维护。
English · npm · 更新日志 · Release v0.3.0
快速开始
在已安装 DeepSeek Harness 的环境中,运行:
dsh plugin --profile web add [email protected]
将 web 替换为实际使用的 profile。安装完成后重启 DSH 会话;web 模式需重启 dsh web。
默认启用记忆工具和提示词注入。自动整理默认关闭,模型辅助整理需要配置 provider 与 model。已有记忆文件升级到 0.3.0 时无需手动迁移。
目录
1. 功能与工作原理
记忆范围
| 范围 | 适用内容 | 读取方式 |
|---|---|---|
| 全局用户画像 | 语言偏好、沟通风格、个人背景、长期目标 | 在预算范围内注入系统提示词;可通过 memory_get 读取 |
| 项目记忆 | 当前项目的背景、约定和操作说明 | 按会话工作目录选择索引;通过 memory_search 检索、memory_topic 读取正文 |
全局用户画像在使用同一存储路径的 profile 和工作区之间共享。项目记忆按会话工作目录定位,目录内的子目录可能对应不同的记忆位置。
主要功能
| 功能 | 说明 |
|---|---|
| 持久化存储 | 以 Markdown 保存条目,支持直接查看和编辑 |
| 提示词注入 | 在提示词组装时读取有效画像与当前项目索引,按字节预算裁剪 |
| 关键词检索 | 对用户画像和当前项目记忆进行关键词匹配,返回评分与摘要 |
| 时间管理 | 记录更新时间,支持陈旧标注和软失效 |
| 记忆整理 | 合并重复条目、补充相对时间的记录日期,并按配置处理过时内容 |
| 审计记录 | 记录整理操作的执行结果、跳过原因及触发来源 |
处理流程
用户提出记忆请求
→ agent 调用 memory_update
→ 插件写入全局画像或当前项目的主题文件
→ 后续提示词组装时读取有效画像与项目索引
→ agent 按需调用记忆工具读取其余内容
写入采用原子替换,并通过进程内串行化与跨进程锁保护读改写操作。整理执行前会校验条目是否与生成方案时一致;已经变更的条目会跳过,避免旧方案覆盖新内容。
2. 安装与验证
环境要求
- 已安装并可运行 DeepSeek Harness 的
dshCLI。 - 0.3.0 已在 DSH 依赖版本
0.1.7-alpha.1和0.2.0-rc.2上分别完成构建与 108 项测试。 dsh plugin负责安装 npm 包,并根据包中的dsh.bundle.patch声明将插件加入 profile 的 bundle 配置。
安装与升级
快速开始中的命令同时适用于安装和升级。其他 profile 使用相同语法,例如:
dsh plugin --profile headless add [email protected]
从源码安装
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 plugin --profile web add ./dsh-tool-user-memory-0.3.0.tgz
验证安装
- 检查 profile 的
package.json,确认dsh.profile.bundles包含dsh-tool-user-memory。 - 重启会话后,询问 agent 可用的记忆工具。0.3.0 提供下文列出的七个工具。
- 请求保存一条偏好,确认工具返回成功,再检查画像文件是否包含对应条目。
profile 配置示例:
{
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"dsh-tool-user-memory"
]
}
}
}
默认画像路径为 $DSH_HOME/user-memory/user.md。Windows 默认位置为 C:\Users\<用户名>\.dsh\user-memory\user.md;自定义 DSH_HOME 或 path 时以实际配置为准。
3. 配置
插件可使用默认配置运行。如需调整,在 profile 的 cordis.patch.yml 中覆盖 id 为 tool-user-memory 的配置项。
下表中的存储路径为未设置自定义路径时的有效默认值。
| 配置项 | 默认值 | 说明 |
|---|---|---|
path |
$DSH_HOME/user-memory/user.md |
全局用户画像路径 |
maxBytes |
8192 |
画像文件的字节上限;超限时优先淘汰失效条目,再按更新时间从旧到新淘汰 |
promptMaxBytes |
2048 |
注入的画像正文预算;优先保留较新的条目,过长条目会标注截断;0 表示注入完整有效画像 |
includeInPrompt |
true |
是否启用记忆提示词注入;关闭时同时停止画像与项目索引注入 |
staleAfterDays |
0 |
超过指定天数未更新的条目显示 [stale: last updated Nd ago];仅作标注,0 表示关闭 |
workspacePromptMaxBytes |
512 |
注入的项目索引正文预算;0 表示关闭项目索引注入 |
workspaceBase |
$DSH_HOME/user-memory/workspace |
项目记忆根目录 |
autoConsolidate |
false |
是否在回合边界异步触发自动整理 |
consolidateMinIntervalMs |
600000 |
自动整理的最小间隔,单位为毫秒;0 表示不设置间隔限制 |
autoInvalidateAfterDays |
0 |
整理时软失效超过指定天数未更新的条目;0 表示关闭 |
consolidateProvider |
'' |
模型辅助整理使用的 provider;留空时使用确定性规则 |
consolidateModel |
'' |
模型辅助整理使用的 model id |
consolidateMaxTokens |
1024 |
单次整理模型调用的输出 token 上限 |
consolidationLogPath |
$DSH_HOME/user-memory/consolidation-log.md |
整理审计日志路径 |
容量与预算
promptMaxBytes与workspacePromptMaxBytes限制注入的记忆正文,提示词说明文字另计;字节数与 token 数不等价。- 超出注入预算的画像内容可通过
memory_get读取,项目正文通过memory_topic按需读取。 - 单个项目主题的正文上限为 16 KiB,包括追加后的总内容。超限追加会被拒绝并保留原内容。
maxBytes限制全局画像文件,不是全部项目记忆与日志的总容量限制。- 主题名不能使用
MEMORY、Windows 保留设备名或包含文件名保留字符;名称长度最多 64 个字符。
4. 使用示例
以下示例说明如何向 agent 表达操作意图。实际工具调用取决于模型;保存或修改后,可检查工具结果及本地文件。
保存与查询偏好
记住:我偏好简洁的中文回答。
预期调用为 memory_update,默认写入全局画像。适合保存长期偏好、个人背景和长期目标。一次性任务以及密钥、密码、令牌不应作为记忆内容。
查看已保存的语言和沟通风格偏好。
可通过 memory_get 查询用户画像,或通过 memory_search 检索画像与当前项目记忆。
更新、失效与删除
| 意图 | 示例 | 对应操作 |
|---|---|---|
| 更新内容 | 将语言偏好改为英文 | memory_update,mode=set |
| 保留历史并停止使用 | 将旧项目背景标记为已失效,原因是项目迁移 | memory_update,mode=invalidate,填写 reason |
| 移除记录 | 删除已保存的语言偏好 | memory_update,mode=remove |
软失效保留历史记录,并将条目排除在提示词和默认检索结果之外。删除会移除记录。
保存项目约定
在目标项目目录打开会话后,提出:
将以下约定保存到当前项目记忆:使用 pnpm 管理依赖,提交前运行 pnpm test。
对应调用为 memory_update,scope=workspace。在其他工作目录打开的会话会读取该目录对应的项目记忆。
整理记忆
先生成记忆整理方案,列出计划执行的操作。
使用 memory_consolidate 的 mode=plan 查看方案。需要执行时,使用 mode=apply;执行结果写入审计日志。模型辅助整理需配置 provider 与 model,并使用 useModel=true。
验证跨会话读取
- 保存一条语言偏好,并确认写入成功。
- 在启用同一插件配置的新会话中询问已记录的语言偏好。
- 检查回答是否与记录一致;必要时调用
memory_get核验。
在默认配置下,有效画像会在预算范围内注入系统提示词,因此模型无需先调用工具即可读取这部分内容。实际回答是否正确仍取决于模型行为。
换电脑:导出与导入记忆
0.3.0 提供 memory_export / memory_import 和独立命令 dsh-memory。导出包含全局画像、全部已存储项目、更新时间及失效状态;仅读取记忆文件,不读取整理日志、插件配置、缓存或账号凭证文件。导入根据新项目目录重新生成索引,默认保留本机同名内容。未映射的项目会明确列出并跳过。
旧电脑无需升级插件。 在 PowerShell 中运行下面的命令,将导出文件保存到用户目录,再通过 U 盘或你选择的方式传到新电脑:
npx --yes [email protected] dsh-memory export --file "$env:USERPROFILE\dsh-memory.json"
已有文件不会被覆盖;再次导出时请换一个文件名。DSH 可以保持打开,导出对每份记忆加锁读取;各项目快照可能来自不同时间,导出期间暂停修改记忆可取得更一致的快照。原项目目录已经删除也能导出其已存储记忆。
在新电脑升级插件并重启会话后,对 agent 说:
使用 memory_import 预览导入
C:\Users\你的用户名\dsh-memory.json,默认保留本机内容。列出未匹配的项目,先不要执行导入。
如需项目记忆,告诉 agent 哪个旧项目对应哪个本机目录。确认新增、冲突和未匹配数量后,再让 agent 执行该预览。导入必须携带 previewToken;文件、配置或目标记忆已变化时,需要重新预览。
也可完全使用命令行。以下示例里的项目 ID 来自导出结果或导入预览;新项目目录必须存在:
npx --yes [email protected] dsh-memory import --file "$env:USERPROFILE\dsh-memory.json" --map "项目ID=C:\projects\demo"
# 确认预览后,保留相同选项并加入执行标志与返回的 token:
npx --yes [email protected] dsh-memory import --file "$env:USERPROFILE\dsh-memory.json" --map "项目ID=C:\projects\demo" --apply --token "返回的previewToken"
--policy use-imported 明确替换同名内容;--skip-profile 只导入映射的项目;多个项目使用多个 --map。导入超出全局容量或单主题容量时会拒绝操作,不自动淘汰记忆。导出包和单次导入备份均限制为 16 MiB。
CLI 默认读取 $DSH_HOME/user-memory(未设置 DSH_HOME 时为 ~/.dsh/user-memory),不会读取 DSH 插件配置。自定义存储或容量时,传入 --profile <user.md路径>、--workspace-base <目录>、--max-bytes <字节数>;DSH 工具直接使用插件配置。
导入先备份所有待修改文件,再写入记忆;发生可处理的写入错误时自动回滚。进程被强制终止时可能只写入一部分,恢复记录保存在画像目录的 migration-backups/*.json。工具返回 backupPath 后,可使用相同存储选项恢复:
npx --yes [email protected] dsh-memory rollback --file "backupPath对应的文件"
导入后又被修改的文件会阻止回滚,以免覆盖新内容。导出 JSON 和备份包含完整记忆正文,请按个人资料保存;导出过程不会上传文件。
5. 数据存储与生命周期
默认文件布局
$DSH_HOME/user-memory/
├── user.md # 全局用户画像
├── consolidation-log.md # 整理审计日志
└── workspace/
└── <hash16>/ # 会话工作目录对应的存储目录
├── MEMORY.md # 有效主题的索引
└── <topic>.md # 主题正文与元数据
项目目录标识取会话工作目录 realpath 转为小写后的 SHA-256 前 16 位。索引包含主题名与一行摘要,在主题写入后重建。
默认存储位置在 $DSH_HOME 下,不写入项目仓库。自定义 path 或 workspaceBase 后,存储位置由配置决定。
条目状态
| 状态或操作 | 行为 |
|---|---|
| 有效 | 可参与提示词注入和默认检索 |
| 陈旧标注 | 达到 staleAfterDays 阈值时添加提示;条目仍有效 |
| 软失效 | 保留正文、失效时间与原因;停止注入,默认检索隐藏 |
| 恢复有效 | 对同一个键执行 set 或 append |
| 淘汰 | 全局画像超出容量上限时移除条目,优先处理失效及较旧的条目 |
| 删除 | 执行 remove 后移除对应记录 |
手动编辑
画像是普通 Markdown 文件,可保留其标题和元数据格式直接编辑。插件在后续读取与提示词组装时使用文件内容。
# User Memory
## language
<!-- ts: 2026-10-10T01:15:38.092Z -->
简洁的中文回答
## old-project
<!-- ts: 2026-08-14T00:00:00.000Z -->
<!-- invalid: 2026-10-10T02:00:00.000Z | 项目已迁移 -->
旧项目说明
6. 工具参考
memory_get
读取全局用户画像。
| 参数 | 必填 | 说明 |
|---|---|---|
query |
否 | 按键或内容进行关键词过滤 |
limit |
否 | 最大返回条数,默认 50,上限 100 |
includeStale |
否 | true 时包含软失效条目及其失效时间与原因,默认 false |
返回 { ok, total, invalidated, rendered }。rendered 为供模型读取的文本;启用 staleAfterDays 后可包含陈旧标注。
memory_update
写入、追加、软失效或删除记忆。
| 参数 | 必填 | 说明 |
|---|---|---|
key |
是 | 记忆键,例如 language 或 communication-style |
value |
是 | 正文;invalidate 和 remove 时可传空字符串 |
mode |
否 | set 覆盖并恢复有效;append 追加并恢复有效;remove 删除;invalidate 软失效 |
reason |
否 | 软失效原因,与条目一起保存 |
scope |
否 | global 写入用户画像;workspace 写入当前项目记忆,默认 global |
返回 { ok, scope, key, mode, bytes, error? }。读取失效记录时,在 memory_get 或 memory_search 中设置 includeStale=true。
memory_search
对全局画像和当前项目记忆执行关键词检索。
| 参数 | 必填 | 说明 |
|---|---|---|
query |
否 | 空格分隔的关键词,支持中文子串;留空按更新时间返回记录 |
limit |
否 | 最大返回条数,默认 10,上限 20 |
includeStale |
否 | 是否包含软失效条目,默认 false |
返回 { ok, total, results }。结果包含 scope、topic、score、updatedAt、snippet。
评分规则:主题名匹配记 3 分,正文每次匹配记 1 分且上限 5 分,全部关键词匹配额外加 4 分。画像与项目结果统一排序。
memory_topic
读取一个项目记忆主题的完整正文。
| 参数 | 必填 | 说明 |
|---|---|---|
topic |
是 | 主题名,可从项目索引或检索结果获取 |
返回 { ok, topic, updatedAt, invalidated, invalidReason, body }。主题正文通过工具按需读取,不直接注入每轮提示词。
memory_consolidate
生成或执行整理方案。
| 参数 | 必填 | 说明 |
|---|---|---|
mode |
否 | plan 返回方案;apply 执行操作并记录结果 |
useModel |
否 | 是否请求模型辅助整理;需要配置 provider 与 model |
整理包括以下处理:
- 重复合并:保留归一化内容相同的最新记录,其余记录软失效。
- 时间标注:为包含相对时间的记录补充绝对记录日期,不改写原文中的日期含义。
- 过时处理:报告达到陈旧阈值的记录,并按
autoInvalidateAfterDays执行软失效。 - 模型提案:校验并处理
add、merge、rewrite、invalidate、topic-add和topic-invalidate;模型不可用或响应不合法时使用确定性规则结果。
审计日志记录触发来源、时间、已执行和已跳过的操作及原因。执行时发现条目已变更或合并目标不再有效,会跳过相关操作。
memory_export
参数:destination(必填,本机 JSON 路径)、scope(all 或 global,默认 all)。返回文件路径、全局条目数及项目 ID、原目录和主题数。拒绝覆盖已有文件或写入活动记忆文件。
memory_import
参数:source(必填)、includeProfile(默认 true)、projectMap([{id, path}])、policy(默认 keep-local)、dryRun(默认 true)、previewToken。预览不写入记忆;dryRun=false 必须传入已确认的预览 token。执行返回实际数量及 backupPath,重复导入相同内容不会重复创建条目。
7. 限制与故障排查
行为与安全边界
- 提示词将记忆标注为参考数据,并要求模型避免执行其中的指令。这是提示词约束,不能保证所有模型都遵守。
- 工具说明要求模型不保存凭据,但插件没有覆盖所有敏感内容的自动过滤器。记忆文件不应包含密钥、密码或令牌。
- 默认记忆存储、检索和规则整理在本地执行。模型辅助整理会将待整理的记忆提交给配置的 provider,并产生相应模型调用费用。
- 测试验证存储行为和工具集成;尚未评估真实模型的记忆提取、使用及长期准确性。
新会话未使用已保存的记忆
检查以下项目:
- profile 的
dsh.profile.bundles是否包含插件,安装后是否已重启会话。 - 画像是否已写入,条目是否有效,
includeInPrompt是否开启。 - 内容是否因注入预算被省略或截断;可使用
memory_get读取完整画像。 - 项目记忆对应的会话工作目录是否一致且可访问。
工作目录不可用
项目记忆依赖会话的工作目录。目录缺失或不可访问时,项目写入和主题读取会返回错误;仍可使用 scope=global 保存个人偏好。
清除数据
全局画像、项目记忆和审计日志分别保存。清除画像需删除实际配置的 user.md;清除项目记忆需删除对应的项目存储目录;清除整理历史需删除审计日志。仅删除画像文件不会移除项目记忆或日志。
8. 开发与验证
pnpm install --frozen-lockfile
pnpm test
pnpm run build
0.3.0 的验证结果:
| DSH 依赖版本 | 测试 | TypeScript 构建 |
|---|---|---|
0.1.7-alpha.1 |
108/108 通过 | 通过 |
0.2.0-rc.2 |
108/108 通过 | 通过 |
测试覆盖文档解析、并发锁、存储、项目记忆、整理、Harness 集成和 AgentLoop 工具调用。循环测试使用固定模型响应。
代码结构
| 文件 | 职责 |
|---|---|
src/index.ts |
插件配置、服务装配与回合边界触发 |
src/profile.ts |
画像解析、序列化、合并、淘汰与渲染 |
src/store.ts |
全局画像的原子写入与并发保护 |
src/lock.ts |
进程内串行化与跨进程锁 |
src/workspace.ts |
项目主题存储、索引重建与检索 |
src/consolidate.ts |
整理方案、模型提案校验、执行与审计 |
src/tools.ts |
核心记忆工具与迁移工具注册 |
src/migration.ts |
导出格式校验、导入预览、备份与恢复 |
src/migrate-cli.ts |
独立记忆迁移命令 |
src/prompt.ts |
用户画像与项目索引的提示词注入 |
存储层使用 node:fs 管理插件自身的持久化状态。
9. 版本演进与规划
已发布版本
| 版本 | 主要变化 |
|---|---|
0.1.x |
提供全局用户画像与跨会话提示词注入 |
0.2.0 |
增加项目记忆、关键词检索、软失效、时间标注与整理 |
0.2.1 |
修复并发写入丢失及日期改写重置记忆年龄的问题 |
0.2.2 |
修复旧整理方案覆盖新内容、失效记录意外恢复、保留主题名冲突及字节限制问题 |
0.2.3 |
将插件列表描述改为简洁中文,并更新中英文 README 的结构与表述 |
0.3.0 |
增加跨电脑记忆导出、导入预览、项目目录映射、冲突策略、自动备份和回滚命令 |
完整变更记录见 CHANGELOG。
后续规划
- 基于会话摘要的语义整理,并设置运行频率和预算限制。
- 增加会话空闲、上下文压缩和定时整理触发方式。
- 为条目单独记录首次创建时间。
- 按会话身份区分多用户画像。
以上功能尚未实现,进度与验收条件见 issue #1。