pokiimon/dsh-memory-eternal-fork ↗★ 0
dsh-memory-eternal-fork
记忆核心(Memory Eternal)· fork 维护版:DeepSeek Harness 记忆插件——对话结束后自动沉淀知识卡到本地 Markdown Vault(自研去重、自研 CJK 检索、可 git 管理),设置页提供图形化知识库(统计 / 搜索 / 知识图谱 + 侧边栏嵌入式卡片),Agent 通过 memory_recall 工具按需召回历史上下文。原项目由 EternalNight996 创建并维护:https://github.com/EternalNight996/dsh-memory-eternal ;本 fork 由 pokiimon 维护,聚焦 DSH 0.2.0-rc.x 兼容性修复与界面改进,遵循 MIT、保留原作者署名。 适合需要自动积累对话知识、通过本地知识库增强模型长期记忆的用户。
설치
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:pokiimon/dsh-memory-eternal-fork⚙️ 记忆配置(大白话)
所有配置都在 记忆库左栏「记忆配置」(或 DSH 设置 → 记忆)里改,点「保存配置」生效。下图就是配置页全貌(含插件信息 / Agent MCP 挂载状态 / 自动审核配置):

一、最常用
| 配置项 | 默认 | 大白话说明 |
|---|---|---|
| 自动沉淀 | 开 | 每轮聊完自动把有用的内容存成知识卡 |
| 自动召回 | 开 | AI 需要历史时自动帮你查记忆 |
| 记忆库目录 | ~/.dsh/memory-vault | 记忆存哪,纯 Markdown 可 git 管理 |
二、省钱包(重要)
| 配置项 | 默认 | 大白话说明 |
|---|---|---|
| 蒸馏知识卡 | 开 | 把对话压缩成精炼知识卡(要调 AI,花钱)。关掉 = 存原文,一分钱不花 |
| 语义去重喂 AI | 开 | 判断新内容是不是重复(要调 AI)。关掉 = 用简单去重,省一次 AI 调用 |
| 蒸馏输出上限 | 900 | 压缩一次最多写多少字,越大越准越费钱 |
| 召回相关性阈值 | 2 | 检索要「多像」才返回,越大越准但漏得越多(越省) |
| 捕获最小长度 | 200 | 对话太短不存,避免闲聊浪费 |
| 日配额 | 60 | 一天最多存几张,防 AI 烧钱 |
| 沉淀诊断日志 | 关 | 打开后每次跳过都会在宿主控制台留下 [memory-eternal] capture: …,用于排查「库里一直没有卡」 |
| 无路由时存原文卡 | 关 | 解析不出模型路由(宿主只暴露"可配置 provider 目录"这类情况)时,仍落一张原文卡,而不是静默放弃 |
设置页能不能直接改配置? 看宿主。0.1.x 时代插件持有可写的设置段,页面直接写; 0.2.x 移除了该 API,插件改为把「保存」翻译成宿主的
SettingsForms.mutate(ns, ops)持久化(自 0.7.2 起)。并且宿主只接受标了 volatile 的字段,否则报Plugin entry "memory-eternal" has no volatile fields。所以自 0.7.3 起按「运行时是否 每次重新读」划线:沉淀 / 召回 / 去重 / 审核 / 回收 / 库位置这些字段标了 volatile, 保存后立即生效;autoMcpSetup、autoWeb、autoWebMode、webPort、webCheckIntervalMs、webMaxRestart、watchdogAutoSpawn只在启动阶段读一次, 宿主会拒写并提示改 profile 的cordis.patch.yml行 config 再重启。⚠️ 标了 volatile 的字段,宿主交给插件的是「引用对象」而不是值(要
.get()才是当前值, 等价于宿主内部的plainConfig())。所以插件读配置前先做一层还原——少了这层, schema 里一标 volatile,启动就TypeError: cfg.vaultDir.trim is not a function, 整个 fiber 挂掉、路由全部没挂上(自 0.7.4 起修)。🧩 设置页整份表单一起提交也不会失败(自 0.7.5 起迭代到 0.7.6):页面里既有沉淀/召回这类 热改字段,也有端口 / 保活 / 看门狗这类启动期字段,而宿主是按字段逐个校验的。 现在的做法是两类字段都标 volatile、都能存下来,插件再单独点名哪些「需要重启 DSH 才生效」 (返回里的
needsRestart,GET/config也会给出bootOnly清单)——写下去 ≠ 立刻生效, 这一点如实说,不假装热改。
沉淀为什么没出卡? 自动沉淀在每轮结束时按顺序过四道关:开关 → 本轮文本长度 (
捕获最小长度,计的是该轮用户+助手文本)→ 日配额 → 模型路由(resolveRoute)。 前两道被卡住是设计使然;第四道以前是静默返回——宿主没给可用路由时既没卡、也没 任何提示。现在打开「沉淀诊断日志」就能看到具体是哪一道,或者直接打开 「无路由时存原文卡」让内容先落盘。🐞 0.2.x 上还有一道更隐蔽的坑(自 0.7.7 起修):会话事件在
agent.session.snapshotEvents()上,而agent.session没有events字段 (宿主packages/core/session/src/index.ts:649)。老代码只认.events→ 钩子在Array.isArray那一步静默 return:没卡、没报错,连captureDebug的日志都不会出现(因为连runCapture都没进)。现在统一走resolveSessionEvents()兼容读取(快照方法 → 旧字段 → 空数组), 钩子层自己也会写诊断:控制台 +$DSH_HOME/memory-eternal-capture.log。🧭 插件在会话中途被加载/重启时不会吞掉整段历史(自 0.7.8 起):第一次见到某个会话 只登记水位线、跳过存量事件,从下一轮开始增量沉淀;单轮文本超过
TURN_TEXT_MAX(20000 字符)时保留最新部分。否则重启后的第一轮会把整段会话 一次性喂给模型(贵、且会产出一张巨大的垃圾卡)。
三、服务怎么跑
| 配置项 | 默认 | 大白话说明 |
|---|---|---|
保活模式 autoWebMode | init | init=DSH 启动时开一次 web;interval=定时检查挂了自动重启;manual=全靠手动 |
看门狗 watchdogAutoSpawn | 开 | 后台一个独立进程保证 web 不死(+47 MB 内存)。个人用可关 |
自动挂载 MCP autoMcpSetup | 关 | 让 Claude Code / Codex / Cursor 也能用你的记忆库。开=自动配好它们;关=不碰你电脑配置,手动跑 dsh-memory setup |
💰 想省钱:把「蒸馏知识卡」关掉、调低「蒸馏输出上限」、调高「召回相关性阈值」。
🎯 一键推荐配置(按场景点一下)
配置页顶部有 🟢 A 轻量省心 / 💰 B 极致省钱 / ⭐ C 高质量 三个按钮,点一下自动填好对应值,再点保存即可:
| 方案 | 场景 | 保活 | 看门狗 | 蒸馏 | 蒸馏上限 | 召回阈值 | 内存 | LLM 成本 |
|---|---|---|---|---|---|---|---|---|
| 🟢 A 轻量省心 | 个人开发(默认) | init | 关 | 开 | 900 | 2 | ~47 MB | 正常 |
| 💰 B 极致省钱 | 预算敏感/多 Agent | init | 关 | 关 | 500 | 3 | ~47 MB | 近 0 |
| ⭐ C 高质量 | 长项目/团队 | interval | 开 | 开 | 1200 | 1 | ~94 MB | 高 |
🎯 一键推荐配置(按场景点一下)
配置页顶部有 🟢 A 轻量省心 / 💰 B 极致省钱 / ⭐ C 高质量 三个按钮,点一下自动填好对应值,再点保存即可:
| 方案 | 场景 | 保活 | 看门狗 | 蒸馏 | 蒸馏上限 | 召回阈值 | 内存 | LLM 成本 |
|---|---|---|---|---|---|---|---|---|
| 🟢 A 轻量省心 | 个人开发(默认) | init | 关 | 开 | 900 | 2 | ~47 MB | 正常 |
| 💰 B 极致省钱 | 预算敏感/多 Agent | init | 关 | 关 | 500 | 3 | ~47 MB | 近 0 |
| ⭐ C 高质量 | 长项目/团队 | interval | 开 | 开 | 1200 | 1 | ~94 MB | 高 |