项目状态:早期开发版本(v0.1.0)
当前版本已经跑通基础记忆链路,适合本地试用和继续开发,但接口、数据格式与安装方式都可能发生变化。
dsh-memory 是一个面向 DeepSeek Harness(DSH) 的本地记忆插件。
它希望为 agent 提供一种轻量、透明、可读可编辑的跨会话记忆能力,并针对个人学习、编程和研究场景继续扩展。这里的目标不是无限保存聊天记录,而是维护一组有边界、能被检查、与当前上下文有关的记忆。
长期使用 agent 时,经常会遇到几类重复问题:
- 新会话不知道用户长期稳定的偏好、习惯和约束;
- 不同会话之间的近期进展彼此割裂;
- agent 需要反复了解本机开发环境;
- 项目的工程约定、架构决策和禁止事项散落在对话与文件中;
- 上下文越积越多,但真正应该长期保留的信息反而不清晰。
dsh-memory 目前先从“长期角色约束 + 有预算的近期会话记忆”开始。后续会逐步加入环境记忆、项目记忆和自改进能力,让 agent 在合适的范围内记住合适的信息。
插件会在新会话开始时读取 memory-docs/SOUL.md,并把它作为第一段模型可见上下文注入。
SOUL.md 适合保存相对稳定的内容,例如:
- 用户的长期目标、偏好与沟通习惯;
- agent 的角色定位;
- 跨项目都成立的原则和根本约束。
为了避免重复注入,已经包含真实对话或压缩摘要的会话不会再次自动注入。修改 SOUL.md 后,会从下一个新会话自动开始生效,或者使用斜杠命令/soul-injection手动注入。
每个主会话都会维护一个持续型记忆子代理。主会话每轮结束后,插件把本轮对话交给记忆子代理,由它生成一条有长度限制的压缩记忆,并写入 memory-docs/handles.json。
新一轮开始前,插件会检查其他会话是否产生了当前会话尚未见过的新记忆,并只把缺失的部分追加到本轮请求中。这让不同会话可以交换近期上下文,同时减少重复注入。
当前实现还包括:
- 每个主会话对应一条可持续更新的 handle;
- 记忆按最近更新时间排序;
- 按总字符数、单条字符数和会话数限制记忆规模;
- 超出预算后从最旧的记忆开始淘汰;
- 使用哈希记录已经注入过的记忆,避免无意义重复;
- 记忆子代理按需读取工具结果原文,普通情况下只接收工具结果占位符;
- 文件写入采用串行与原子替换,降低并发写坏数据的风险。
设置页的“记忆”卡片可以调整记忆子代理所使用的模型和三项预算。会话输入区底部会显示记忆子代理的运行状态。
当前提供两个命令:
/soul-injection:手动把当前SOUL.md注入正在使用的会话;/memory-restart:重启当前会话的记忆子代理,并根据现有会话历史重新生成记忆。
memory-docs/SOUL.md
│
└── 新会话开始时注入长期角色与根本约束
主会话每轮对话
│
▼
持续型记忆子代理 ── 压缩与更新 ──> memory-docs/handles.json
│
└── 在其他会话需要时差量注入
记忆默认保存在项目根目录的 memory-docs/ 中。也可以通过绝对路径环境变量 DSH_MEMORY_DOCS_DIR 把记忆放到其他位置。
dsh-memory/
├─ plugin/ # DSH 插件代码
│ ├─ host.js # Host 入口、SOUL 注入、命令与 RPC
│ ├─ client.js # 设置卡片与底部状态读数
│ ├─ memory.js # 记忆子代理、对话喂食与跨会话注入
│ ├─ store.js # handles.json 存储与预算淘汰
│ ├─ settings.js # settings.json 读写与校验
│ └─ package.json
├─ memory-docs/ # 本地记忆数据,不提交到 Git
│ ├─ SOUL.md
│ ├─ handles.json
│ └─ settings.json
├─ memory-docs-example/ # 可提交的 SOUL.md 示例
├─ smoke-test.mjs # 不依赖运行中 DSH 的冒烟测试
└─ README.md
memory-docs/ 已加入 .gitignore。其中可能包含个人信息、项目上下文和会话摘要,推送前仍建议自行检查一次仓库内容。
当前版本采用本地静态插件的方式挂载,下面以 Windows PowerShell 为例。
在仓库根目录执行:
Copy-Item -Recurse .\memory-docs-example .\memory-docs然后按自己的需要编辑 memory-docs/SOUL.md。
在仓库根目录执行:
$DshMemoryRoot = (Resolve-Path .).Path
New-Item -ItemType Junction `
-Path "$env:USERPROFILE\.dsh\profiles\node_modules\dsh-memory" `
-Target "$DshMemoryRoot\plugin"如果目标位置已经存在,请先确认它是否指向当前仓库,再决定如何处理。
在 %USERPROFILE%\.dsh\profiles\web\cordis.patch.yml 中加入:
- insert:
- id: memory
name: dsh-memory保存后,运行中的 dsh web 通常会通过 HMR 挂载插件。需要停用时,可以给该条目添加 disabled: true。
打开一个新会话,检查下面任一项:
- 会话上下文开头出现由
SOUL.md生成的角色与根本约束; - 设置页的插件区域出现“记忆”卡片;
- 主会话完成一轮后,输入区底部出现记忆子代理状态。
默认设置如下:
| 字段 | 默认值 | 说明 |
|---|---|---|
model |
deepseek-v4-flash |
记忆子代理模型;当前 provider 固定为 deepseek-official |
budget-char |
4000 |
所有 handle 内容的总字符预算 |
budget-single-char |
600 |
单条 handle 内容的字符预算 |
budget-session |
100 |
最多保留的会话记忆条数 |
设置保存到 memory-docs/settings.json。预算会在后续记忆更新时立即生效;模型变更从下一个新建的记忆子代理开始生效。
这个项目计划逐步形成一套分层记忆:
- 长期角色与稳定偏好:由
SOUL.md承载,当前已实现; - 近期跨会话上下文:由 handles 记忆承载,当前已有早期实现;
- 本机编程环境记忆:追踪本机实际可用的语言、运行时、包管理器、工具链、重要路径、常用命令与环境变化;
- 项目约束记忆:把记忆绑定到仓库、文件夹或工作区,只在进入相关项目时加载对应的工程约束;
- 更细粒度的记忆管理:逐步探索结构化条目、检索、人工确认和可视化编辑。
目标是让 agent 持续了解“这台机器上实际上有什么”,减少每次会话重新检查环境的成本。计划追踪的内容包括运行时与工具版本、包管理器、常用开发命令、本地服务、关键路径,以及环境发生过的变化。
这个模块需要特别处理信息过期、敏感环境变量和扫描范围,默认设计会继续坚持本地存储、可见和可编辑。
目标是为不同项目维护彼此隔离的工程记忆。记忆可以与仓库根目录、普通文件夹或工作区关联,记录该项目的技术栈、架构约定、构建与测试命令、代码风格、重要决策和明确禁止事项。
进入某个项目时只加载相关约束,离开后不把它们带到无关项目,避免不同项目的规则互相污染。
- 这是早期版本,DSH 接口变化可能直接导致插件失效;
- 当前主要面向单机、单用户和本地开发场景;
- 记忆以 Markdown 和 JSON 明文保存在本地,尚无加密与多设备同步;
- handles 是模型生成的压缩摘要,可能遗漏信息或产生不准确概括;
- 目前没有独立的记忆浏览、编辑和审核界面;
- 本机编程环境追踪和项目约束记忆尚未实现;
- 安装仍依赖手动链接目录和修改 DSH profile 配置。
插件是纯 ESM 静态包,目前没有第三方运行时依赖。
node .\smoke-test.mjs冒烟测试使用 mock 上下文验证 SOUL 注入、会话喂食、handles 读写、预算淘汰、设置与恢复等核心路径,不需要启动 DSH。
v0.1.0 更像是一个可以工作的设计草稿:基础路径已经连通,但许多设计仍会随着真实使用继续调整。这个仓库现阶段主要用于保存实现、记录方向和尽早获得反馈。