前言¶
在 DeepSeek Harness(DSH)里做智能体,上下文总会被新一轮对话挤掉:上周定的端口、你的称呼偏好、某次踩坑的修复步骤,往往要靠你自己翻历史或重复交代。社区里不少「记忆」类做法偏重检索——把对话存成流水账,下次用语义搜索捞片段,常驻事实和「这轮刚学到什么」常常还要你手动维护。
下面介绍维护者 Ykls53 发布的 dsh-memory-inject(GitHub:Ykls53/dsh-memory-inject,社区目录:skillhub 插件页)。它在 DSH 里叠三层记忆:短的常驻注入、中的会话摘要、长的全文检索;注入阶段不调用模型,自动写回则用你在 UI 里已选定的模型。
这是什么¶
dsh-memory-inject 是 DSH 的 Cordis 插件(分类:记忆,当前 package 版本 0.4.1,MIT 许可)。定位可以概括成 README 里那句话:三层记忆——常驻事实(USER.md / MEMORY.md)、按会话的摘要、以及跨会话全文召回;注入零模型调用,自动抓取层使用 settings.yaml 中的 agent-default-model(即设置里模型选择器对应的字段)。
记忆默认落在 ~/.dsh/memories/;装完后在客户端「设置」左侧会出现 记忆 页(排在「刷B站」之后),用于开关、编辑条目和重建索引等。
三层记忆怎么分工¶
第 1 层 常驻注入 USER.md + MEMORY.md 每个会话开头自动在场
↓ 一轮结束时可选提炼写回
第 2 层 会话摘要 每段对话 2~3 句,进 index.db 问「上周三聊了啥」先看这里
↓ 命中的会话可下钻
第 3 层 全量原文 所有会话正文 + FTS5 trigram 索引 翻细节时用
| 第 1 层 | 第 2 层 | 第 3 层 | |
|---|---|---|---|
| 存什么 | 提炼过的事实条目 | 每会话摘要 | 对话原文 |
| 花模型吗 | 注入不花;写回才花 | 建索引写摘要时花 | 不花 |
| 谁维护 | 模型自动回填 / 你手动改 | 索引脚本 | 索引脚本 |
| 预算 | USER 1375 / MEMORY 2200 字符(硬上限) | 无 | 无 |
第 1 层每个会话都会整份进上下文,因此超预算会拒绝写入(不截断、不悄悄丢弃)。单次注入还有总预算 maxTotalChars 默认 4000,超出时整份跳过对应文件。
条目格式是硬性约定:一行一条,条目之间单独一行 §,不要标题和段落块——方便按条增删而不是整份重写。
模型可调的两个工具¶
插件向 agent 注册工具,无需你在对话里教用法:
| 工具 | 作用 |
|---|---|
memory_search |
搜过去:关键词 + 可选时间窗(如 7d / 24h / 2w)。按会话聚合返回标题、时间、命中片段和该会话摘要 |
memory_remember |
写常驻记忆:add / remove / replace / batch;batch 在一次调用里可先删后加,预算只按最终结果计算 |
写入规则:replace 必须唯一命中,多条命中则拒绝;每次写入前自动备份到 <memoryDir>/.backup/,只保留最近 20 份。
全自动回填(可选)¶
默认关闭。一轮对话结束(turn/end)后,可把该轮交给 headless 子进程提炼,按 USER: / ENV: 分类写回文件;子进程使用 dsh --profile headless,模型来源与你的 agent-default-model 一致,插件不接触 API key。
开启方式:设置面板里打开「自动总结」,或在 profile 的 cordis.patch.yml 里将 memory-inject 的 autoCapture 设为 true。子进程带环境变量 DSH_MEMORY_INJECT_SUMMARIZE=1 时插件直接退出,避免提炼会话再次被抓取形成循环。
README 对开销有粗算说明(注入 + 自动回填全开、约 100 轮量级):理论合计约 610k tokens 量级,单价随模型与缓存命中变化,应以平台账单为准。
安装与生效¶
插件以当前 DSH 进程权限运行;安装前建议自行查看仓库源码与 MIT 许可证。需要 Node >=22.15.0。
# npm(发布后)
dsh plugin --profile desktop add dsh-memory-inject
# 本地路径(开发时)
dsh plugin --profile desktop add /path/to/dsh-memory-inject
装完后 dsh 会把插件登记进 profile 的 package.json 的 dsh.profile.bundles 并应用自带的 cordis.patch.yml。新开一个会话即可生效,不必重启整个客户端。
回退:
dsh plugin --profile desktop remove dsh-memory-inject
记忆文件仍在 ~/.dsh/memories/,是否手动删除由你决定。
建索引与会话检索(第 2 / 3 层)¶
插件只查询索引,不负责建库。在插件目录下用 scripts/ 中的脚本:
# 1) 把 DSH 所有会话转录解压成 JSONL
node scripts/dsh-memory-dump.mjs
# 2) 建 FTS5 trigram 索引 → ~/.dsh/memories/index.db
python scripts/dsh-memory-index.py build
# 可选:为每个会话写 2~3 句摘要(要模型,较慢)
python scripts/dsh-memory-index.py search "关键词"
索引使用 trigram 而非默认 unicode61,以便中文精确命中。摘要步骤可跳过:第 1 层和第 3 层不依赖摘要,跳过后设置面板里「会话列表」的目录感会弱一些。面板提供「重建索引」按钮,等效于跑 dump + build,无需记命令。
配置要点¶
在 profile 的 cordis.patch.yml 里用 id memory-inject 覆盖;面板写入的开关和字符上限保存在 <memoryDir>/.settings.json,优先级高于 patch。
| 配置 | 默认 | 说明 |
|---|---|---|
memoryDir |
~/.dsh/memories |
记忆目录 |
files[].maxChars |
USER 1375 / MEMORY 2200 | 每文件硬预算 |
maxTotalChars |
4000 | 单次注入总预算 |
turns |
[] |
空表示每轮检查去重;[1] 表示仅第一轮 |
includePreamble |
true |
是否带「这是记忆」说明行 |
autoCapture |
false |
全自动回填 |
captureTimeoutMs |
180000 | 提炼子进程超时 |
设计上有几处值得提前知道:记忆通过 agent/pre-step 以带 plugin:dsh-memory-inject 标记的用户消息注入,而不是改 system prompt;去重依赖 source.kind,上下文被压缩后下一轮会补回;本会话中途写盘的内容要到下次新会话才进入注入快照。
装完自检¶
不打开 DSH 界面也可验证 HTTP 端点:
node selfcheck.mjs
README 写明:用真实插件代码起临时服务,读类端点走你的真实记忆目录,写类只在临时目录执行;预期为 18 通过 / 0 失败。若设置面板顶部出现「后端插件是旧版本」黄条,需要完全退出并重启 DSH 客户端(服务端在进程启动时加载并缓存,改文件不会热重载)。
适用场景与注意¶
适合需要「常驻事实 + 可搜历史 + 可下钻原文」、又希望注入阶段不额外烧模型的 DSH 桌面用户。若你只想要极简备忘,维护好第 1 层两个 md 文件即可;若要问「上周某天聊了什么」,需要建好 index.db 并保留摘要或依赖 FTS 命中。
社区目录 skillhub.cn 与 GitHub 仓库由社区维护,与 DeepSeek / 幻方无官方从属关系;DSH 生态本身是「一切皆插件」的思路,插件选型以你本地 profile 与权限边界为准。
结尾¶
dsh-memory-inject 把常驻记忆、会话摘要和全文检索拆成三层,注入不调用模型,写回与摘要索引按需消耗你选的模型。安装命令见上文;细节与踩坑(Windows 下多行 prompt、cordis inject 依赖等)以仓库 README 为准。
- 目录页:https://www.skillhub.cn/plugins/Ykls53/dsh-memory-inject
- GitHub:https://github.com/Ykls53/dsh-memory-inject