DSH Hermes Memory
面向本机 DeepSeek Harness 的轻量级长期记忆插件。借用 Hermes 的分层与可追溯思想,但不启动数据库、向量服务或独立进程。
层次
默认数据目录是 $DSH_HOME/memories-hermes;未设置 DSH_HOME 时,使用当前用户目录下的 .dsh/memories-hermes。也可以通过插件配置中的 memoryDir 指定其他目录。
| 文件 | 作用 | 进入每轮提示词 |
|---|---|---|
USER.md |
稳定的用户偏好,最多 1,375 字符 | 是 |
MEMORY.md |
跨项目环境与经验,最多 2,200 字符 | 是 |
projects/<项目哈希>.md |
当前 Git 项目(无 Git 时为工作目录)的事实,最多 1,600 字符 | 是 |
PROCEDURES.md |
可复用流程,最多 1,800 字符;只注入简短入口提示 | 按需通过工具读取 |
sessions/*.jsonl |
已遮盖常见敏感值并加密的会话片段 | 否 |
rollups*.jsonl |
压缩加密的每轮提炼及候选事实 | 否 |
withdrawals.jsonl |
加密保存的撤回标记,在对应日志保留期内防止旧内容重新出现 | 否 |
archive/{sessions,rollups}/ |
达到大小或时间阈值后的分段归档 | 否 |
memory.key |
本地日志加密密钥,备份时必须与日志一起保存 | 否 |
history/*.md |
自动整理前的旧版本 | 否 |
state.json |
会话与整理游标 | 否 |
自动流程
- 根会话每轮结束后异步保存新出现的用户与助手文本。不保存工具输出。常见敏感值先遮盖,日志再经 gzip 压缩和 AES-256-GCM 加密。
- 使用 DSH 当前配置的模型提炼一次,提取稳定事实;无可复用事实时长期文件不变。
- 收到 3 条提炼记录,或空闲约 90 秒后,批量合并、去重、纠错和压缩四层长期记忆。程序重启后会继续处理未合并的记录;同一批次连续失败 3 次后会隔离该批次并继续处理后续项目,原加密记录保留以便手动重试。
- 每次组装提示词时重新读取前三层文件;若过程记忆有内容,仅注入短索引与读取入口。详细流程和历史来源通过工具按需读取。
- 已处理的日志按大小或闲置时间分段;原文归档默认保留 30 天,提炼归档默认保留 365 天。过期原文的来源查询降级为提炼摘要。
- 启动后、每次合并后及每天后台维护时,检查四层 MD(包括所有项目文件)。若某层达到字符上限的 90%,或至少四条事实中有 20% 的完全重复内容,就尝试自我压缩;合并超限时也会针对相应层尝试。每轮最多处理两层。被拒绝的同一内容不会反复请求模型;模型调用错误六小时后可重试。没有新事实也能触发。
自我压缩通过 DSH 的 llm.stream 接口运行。每次请求先读取 DSH 当前主模型;若宿主暂时无法提供选择,再使用插件配置的 provider / model 作为后备。压缩目标按触发原因计算:接近上限时争取节省上限的 5%(且不少于 48 字符);重复内容争取节省原文的 3%(且不少于 12 字符);合并超限时争取正向缩短。目标用于引导模型,写入只要求安全地缩短至少 1 字符且不能超限,并须返回旧条目到新条目的覆盖映射。程序检查标题、长度、旧条目和新条目的逐条覆盖、全部来源引用,以及反引号标识符、数字、路径、链接和敏感值。校验失败时原 MD 不变,并在 state.json 的 compaction 中记录原因;成功后先将旧版放入 history/ 再写入新版。模型的语义判断仍需人工抽查,覆盖映射无法形式化证明两句话完全等价。
尚未成功提炼或合并的记录会留在活动日志中,不会为控制容量而悄悄丢弃。普通失败会自动重试;连续失败 3 次的批次移入 state.json 隔离清单,原日志保留,错误写入 diagnostics.json。可用 hermes_memory_read({layer:"quarantine"}) 查看,用 hermes_memory_remember({quarantineId:"..."}) 重新排队。
自动整理的新事实行末带 〔s:<会话哈希>:<事件序号>〕 来源引用;用 hermes_memory_source 可展开保留期内的原文片段。
后台使用现有 DSH 模型配额。按每轮一次提炼、每三轮一次合并计费;不使用额外 API key、embedding 或数据库。机器关机前尚未完成的后台请求会留在原文或候选层,下一次 DSH 运行后继续整理。
安装
要求 Node.js 20 或更新版本,以及提供 @deepseek-ai/dsh-llm、@deepseek-ai/dsh-tools 0.2.0-rc.2 API 的 DeepSeek Harness。当前兼容目标是 DSH 0.2.0-rc.2;其它预览版本的兼容性尚未验证。
从 GitHub 安装
dsh plugin --profile web add github:liuyuhao1122/dsh-hermes-memory
安装后重启 dsh web。仓库通过 package.json 的 dsh.bundle 字段声明 bundle,cordis.patch.yml 会自动注册插件,无需复制配置或填写本机绝对路径。
卸载:
dsh plugin --profile web remove @marculiu/dsh-hermes-memory
从源码安装与开发
git clone https://github.com/liuyuhao1122/dsh-hermes-memory.git
cd dsh-hermes-memory
dsh plugin --profile web add .
开发时可运行 npm ci --ignore-scripts 安装依赖。记忆数据默认写入 $DSH_HOME/memories-hermes(未设置时为用户目录下 .dsh/memories-hermes),与源码分离。
数据与权限
- 插件监听根会话中的用户和助手消息,用于本地记忆整理;不会保存工具输出。
- 后台提炼和整理使用 DSH 当前配置的模型及其配额。若当前模型由远程服务提供,对话片段会发送给该服务;本插件不配置额外 API Key,也不启动数据库或独立服务。
- 会话与提炼日志使用本地
memory.key加密,但敏感值遮盖只覆盖常见格式。备份时要保留密钥;forget会屏蔽常规搜索和来源展开,不等同于安全擦除。
源码更新后重启 DeepSeek Harness,才能确保 Node 加载新版本。首次加载会将旧版明文 JSONL 转为加密日志,同时换算已有游标。启动状态与最近的后台错误记录在数据目录的 diagnostics.json;state.json 的 distilledSeq 和 version 分别表示已提炼的会话序号和长期整理次数。
配置项:
memoryDir:自定义数据目录;空值使用上述默认目录。provider/model:后台模型后备路由。正常情况下始终优先读取 DSH 当前主模型,切换主模型后无需改插件配置。consolidateEvery:批量整理阈值,默认 3。consolidateDelayMs:待整理记录的空闲整理延迟,默认 90,000 毫秒。rawRetentionDays:会话原文归档保留天数,默认 30。rollupRetentionDays:提炼归档保留天数,默认 365。
可以直接编辑 Markdown。整理与压缩前会比较文件内容;如编辑与后台写入同时发生,本次写入放弃。模型返回超限内容时拒绝写入,不再截掉 MD 末尾的事实;若旧层达到压缩条件,先安全压缩旧层再重试一次合并。自我压缩仅处理标题加单行列表项的文件;遇到复杂手工 Markdown 会保持原样。
如果某层包含大量互不重复的独有事实,模型可能只能实现很小的安全缩短,甚至完全无法缩短。无法安全缩短时保留原文件和待整理日志,压缩状态记为 rejected;同一内容不会重复调用压缩模型,内容变化或压缩策略升级后才重试。因超限导致的合并失败默认六小时后重试。仍可通过编辑 MD 清理过期事实,再让后台继续处理待整理记录。
工具
hermes_memory_search({query,limit?}):搜索四层记忆与近期会话原文片段。hermes_memory_read({layer}):读取user、global、project、procedure;quarantine查看失败隔离清单。hermes_memory_source({ref}):按来源引用展开原文。hermes_memory_remember({fact,layer}):添加明确事实,并尽快整理;也可传quarantineId重试隔离批次。hermes_memory_forget({fact,layer}):立即移除活动 Markdown 中匹配的条目,并屏蔽常规日志搜索和来源展开。
记忆仍由模型提炼,具体事实应以原始来源和当前用户陈述核对。forget 会让事实不再进入常规上下文、搜索结果和来源展开,但不会立刻擦除加密会话/提炼日志;这些日志仍按 30/365 天保留期清理。撤回标记单独加密保存,在对应日志保留期内持续生效;重新保存同一条事实会解除屏蔽,日常维护会压缩账本并清理过期标记。forget 不会再额外生成含旧内容的明文历史副本;它不是安全擦除功能,已有的 history/*.md 仍是明文历史文件,需要彻底清理时必须另行清理相关历史 Markdown 和日志归档。memory.key 丢失且仍有加密日志时,插件会停止初始化并要求从备份恢复,不会生成新密钥覆盖问题;备份时必须保留原密钥。
当前自我压缩要求每条旧事实都映射到新内容,因此压缩不会主动淘汰独立事实;事实级的自动保留期/优先级淘汰策略尚未实现。遮盖规则只匹配已知令牌格式、带字段名的密钥和常见个人标识,不会把普通长字符串、Git SHA 或项目目录名一概当作秘密。未标注、未知格式的秘密无法靠正则可靠识别;会话日志虽加密,提炼后的事实仍需核查。用 npm test 运行临时目录回归测试;用 npm run audit -- <记忆目录> 只读检查现有日志、游标、隔离批次和历史遮盖标记,审计仅输出计数。
接口参考:DeepSeek Harness 官方插件与 Profile 文档及 dsh-memory 的 DSH 0.2 适配实现。分层记忆和来源回溯的设计说明见本文档。
许可证
本项目采用 MIT 许可证。版权署名使用项目作者的公开名称或 GitHub 用户名。
No comments yet. Be the first to write one.