DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-memory-core

K

dsh-memory-core

Discovered

DSH 本地记忆插件:BM25-lite 历史召回 + 记忆使用协议 + 结构化固化 + 情感状态。全部落本地 Markdown/JSONL,无数据库、无云端。

Machine translated

dsh-memory-core

给 DeepSeek Harness(DSH) 里的持久化 AI 角色加一层记忆与状态:常驻记忆协议、按需历史召回、结构化记忆固化、两标量情感状态。

面向的场景很简单:模型每次重启都是同一份权重,跨会话的“记性”只能靠外部文件。这个插件把那份档案变成能找回来、能追溯、且不会压过人设的一层。

为什么做这个

大模型像一块孤立的前额叶:工作记忆短、无状态、换个会话就忘。这个项目按仿生学思路给它补了海马体(档案 + 召回 + 固化)和一点点杏仁核(情感状态)。

但它不承诺意识。用中文房间的话说,我们只是给房间加了一个档案柜——回答更连贯了,符号仍然没有接地。所以这里的定位是弱人格同一性:不承诺内在体验,只保证行为上的连续、可追溯、一致。

组成

层干什么
P0a 记忆使用协议用 systemPrompt.section 注入 5 条规则:历史参考不是本轮发言、可能过期、要能追溯、以新事实为准、不许编造。刻意不重复 AGENTS.md 的人格段,避免权威倒置。
P0b 按需召回agent/pre-step 且 step <= 1(首轮与 step 未定义时),用中文 2-gram + BM25-lite + 覆盖率阈值,从档案召回 top 3,前置注入一条带 source.kind='memory-recall' 的消息。150 ms 目标超时,失败静默。
P0c 常驻记忆导航另一个 systemPrompt.section(order 960),把「档案有哪些主题、最近几条记忆的一行摘要 + 关键词」压到 600 字以内注入。没有记忆时不注入;模型需要细节时按关键词自己回查,不靠召回碰运气。
P0d 后台总结setInterval(默认 10 分钟,unref())检查对话文件:空闲超过 30 分钟且有新增小节时,按「标题 + 首句」追加到 ~/.dsh/autocapture/summaries.jsonl。纯规则、不调 LLM,内容 hash + 小节 key 双重水位保证幂等。
P1 结构化固化consolidate.mjs 把对话小节转成 structured.jsonl:稳定 ID、source_id、逐字校验的 quote、幂等水位。
P2 情感状态valence / arousal 两标量 + 规则分类 + 指数衰减 + 事件去重,只影响语气,不碰调度与安全规则。
P3 写入脱敏sanitize.mjs 在自动捕获与摘要落盘前过滤 sk- / gh*_ / github_pat_ / AKIA / Bearer / password= / token= / api_key= 等常见凭证,命中替换成 [REDACTED]。纯本地正则,可在面板关掉。

本地记忆(全部落盘,无云端)

这个插件刻意不做数据库、不做向量库、不调任何外部服务,记忆就是一堆普通文件:

memory/
├── 身份.md               # 我是谁(只读,面板不改)
├── 日记.md               # 按条目追加
├── 生长/
│   ├── 状态.md           # 分节正文
│   └── 生长记录.md       # 一行一条
└── 记忆/
    ├── 事件流.jsonl      # 只追加(面板只读)
    └── structured.jsonl  # P1 固化产物:id / source_id / quote / status
  • 召回只读上面这些文件,命中后带来源(文件 + 行号)注入。
  • 导航只读 memoryRoot 下的 md、对话记录与自动捕获 JSONL,不写任何东西。
  • 后台总结把摘要写到独立目录,绝不碰 memory/:
~/.dsh/autocapture/
├── captures.jsonl              # 自动捕获(已有)
├── summaries.jsonl             # 后台摘要:id / title / summary / keywords / source_id
└── summaries.jsonl.watermark.json   # 内容 hash + 已处理小节 key,保证幂等
  • 固化把对话小节写成 structured.jsonl,每条都带 source_id 和一段逐字校验过的 quote——在原文里搜不到就丢弃。
  • 情感状态是一个 state.json,两个标量 + 触发原因。
  • 换机器时把整个目录拷走即可,没有需要迁移的数据库。

安装

dsh plugin --profile <你的 profile> add file:<这个目录>

或在 DSH Desktop 的「插件管理」里装本地目录。装完重启 DSH。

配置

cordis.patch.yml(整行替换,没写的字段走默认):

- insert:
    - id: dsh-memory-core
      name: dsh-memory-core
      config:
        memoryRoot: "D:\\path\\to\\memory"     # 档案根(身份/日记/生长/记忆)
        dialogueFile: "D:\\path\\对话记录.md"  # 逐轮对话日志
        logFile: "D:\\path\\recall.log"        # 召回日志
        stateFile: "D:\\path\\affect\\state.json"
        topK: 3
        timeoutMs: 150
        minCoverage: 0.2
        minRatio: 0.3
        enableStable: true
        enableAutoCapture: true
        enableMemoryNav: true
        summaryMaxChars: 600
        enableSummary: true
        summarizeIntervalMinutes: 10
        summarizeIdleMinutes: 30
        enableSanitize: true

设置面板(0.3.0)

DSH 设置页左侧多一节 「记忆核心」(客户端 slot settings.section,id: memory-core,order: 58)。面板只做两件事:读当前生效值、把改动存回配置。

参数类型默认范围说明
memoryRoot路径D:\dsh-workspace\memory非空日记 / 生长记录所在根目录(只读)
dialogueFile路径D:\dsh-workspace\对话记录.md非空当语料读的对话记录
topK数字31–10每次注入几条
timeoutMs数字15050–1000召回超时(毫秒)
minCoverage数字0.20–1查询 2-gram 覆盖率下限(0 = 不设门槛)
minMatched数字21–5最少命中片段数
halfLifeDays数字301–365权重半衰期(天)
dailyQuota数字100–100自动捕获每日配额(0 = 不写)
enableStable开关开—是否注入常驻「记忆使用协议」
enableAutoCapture开关开—是否开启自动捕获
enableMemoryNav开关开—是否注入常驻「记忆导航」(无记忆时不注入)
summaryMaxChars数字60080–2000导航总长度上限(字),超出按新鲜度截断
enableSummary开关开—是否跑后台摘要
summarizeIntervalMinutes数字101–1440后台检查间隔(分钟)
summarizeIdleMinutes数字301–1440对话文件空闲多久才总结(分钟)
enableSanitize开关开—自动捕获 / 摘要写入前是否脱敏

保存链路:客户端 POST /dsh-memory-core/config/save → config.mjs 严格校验(越界 / 类型错直接点名,不偷偷改值)→ ctx.configEditor.edit() 写进 profile 的 patch 层(宿主自己的配置机制:保留 YAML 注释与 !!js,重启后仍在)→ 同时就地更新运行中的配置,下一轮召回立刻按新值走。

  • 参数表只写在 config.mjs 一张表里,客户端从 GET /dsh-memory-core/config 拿表渲染,不重复写死中文标签。
  • 部署里没有 configEditor(如 headless)时:改动当次生效,面板会明说「存不进配置文件」。
  • 日志路径 / 捕获存档路径 / 摘要存档路径 / affect 状态文件仍然只在 cordis.patch.yml 里改。

记忆导航、后台总结与脱敏

记忆导航(summary.mjs 的 buildNav)是常驻的,但只给“索引”不给全文:

  • 扫 memoryRoot 下的 .md、dialogueFile、autocaptureStore,按文件 mtime / 标题日期 / created_at 排新鲜度;
  • 头部列最近 8 个主题,下面列最近几条的「日期 + 来源 + 首句 + 关键词」;
  • 总长度 summaryMaxChars(默认 600)硬限制,放不下的旧条目先丢;一条记忆都没有时返回空串,systemPrompt.section 不会注入空块;
  • 按文件 mtime + 长度缓存,对话量再大也不会每轮重扫。
  • 和召回共用 status.mjs 的状态判定:superseded / archived / draft 的对话小节不会出现在导航里。否则一条被淘汰的旧决策会从召回那个口子消失,又从导航这个口子回到上下文。日记与自动捕获没有结构化状态,不受此过滤影响。

后台总结(summary.mjs 的 summarizeDialogue)默认每 10 分钟检查一次:

  1. 对话文件 mtime 距今不足 summarizeIdleMinutes(默认 30 分钟)→ 认为还在聊,跳过;
  2. 内容 hash 与水位一致 → 跳过(幂等);
  3. 按 ## / ### / #### 切小节,取「标题 + 首句(截断 120 字)」,追加到 ~/.dsh/autocapture/summaries.jsonl;
  4. 水位文件记录内容 hash + 已处理小节 key(最多 5000 条),文件追加后再跑只处理新增部分;落盘 id 也会二次去重。

定时器用的是 unref() 的 setInterval,不会阻止 DSH 退出;面板改开关或间隔会当场重排定时器。

写入脱敏(sanitize.mjs)在两条写路径生效:autocapture.mjs 的 autoCapture(redact 参数)和 summarizeDialogue 的摘要记录。覆盖 sk-、gho_/ghp_/github_pat_、AKIA、Bearer、password=/token=/api_key=;已替换的位置用负向前瞻跳过,所以重复调用不会二次计数。默认开启,enableSanitize: false 可关。

测试

npm test                 # 全量闸门,任何机器上都应该是绿的
npm run eval             # 单独跑召回评测,需要私有档案(DSH_MEMORY_ROOT / DSH_MEMORY_DIALOGUE)
npm run consolidate      # 跑一次固化(幂等)

固化脚本也接受环境变量,换机器不用改源码:`DSH_MEMORY_DIALOGUE`(对话文件)、`DSH_MEMORY_ROOT`(档案根)、`DSH_MEMORY_STRUCTURED` / `DSH_MEMORY_WATERMARK`(覆盖输出与水位)。都不设时从当前目录往上找「对话记录.md」,找不到直接报错,不会静默当成空对话跑完。

selftest 用 mock 宿主验证:section 注册、注入前缀、不相关查询不注入、情感状态变化、日志写入。 test/sanitize.test.mjs 覆盖 9 类密钥模式、幂等、大小写与普通文本不误伤。 test/summary.test.mjs 覆盖空档案不注入、导航内容/长度上限/截断、摘要抽取、水位幂等、追加只摘新增、空闲判定、写入脱敏与开关。 test/panel-routes.test.mjs 用假 ctx / webServer / configEditor 跑一遍读写路由:校验拒绝、落盘调用、0 值保留、headless 降级。

已知限制

  • 召回是词面匹配,不是语义检索;改写幅度大的查询会漏。
  • 语料主题高度单一时召回会失灵:某个 2-gram 在几乎所有条目里都出现时 idf 趋近 0,总分被 minScore 地板拦掉。主题分散的档案不受影响。
  • 150ms 是目标预算,不是硬实时保证:recall(cfg, query, deadline) 把 deadline 贯穿冷启动加载、索引构建和候选扫描;循环每 64 步检查一次,超时就熔断返回已算出的部分结果,并废弃没建完的索引缓存。它不能抢占正在执行的一次同步 readFileSync——Node.js 单线程上,同步 I/O 一旦开始就没法从外部打断。所以准确的说法是「计算阶段协作式检查 + 主动熔断」,不是「整条链严格不超过 150ms」。真遇到超大单文件或慢磁盘,单次同步读取本身就可能吃掉整个预算。整条链路是同步内联检查,用 Promise.race 包裹是伪超时、救不回时间。
  • 导航与摘要都是规则抽取:主题取标题、摘要取首句,不保证语义完整;后台总结只处理对话文件,且必须在空闲窗口里才跑。
  • 固化目前是规则抽取(fact 取小节标题)。status / supersedes 已经真正参与召回——active 以外的记录不进候选池,且 supersedes 关系优先于状态字段。但系统不会自己判断两条记忆是否冲突:新决策落盘后,仍要手动把旧记录标成 superseded,或在它上面填 supersedes。LLM 事实提取与自动冲突识别没做。
  • source_id 是 dialogue:行号,对话记录被编辑后行号会整体漂移。状态表因此同时按内容签名(完整内容的 sha1 前缀,没有截断)对齐,行号对不上时按签名兜底。改内容(不只是挪位置)会让签名也变,那条记忆回到未标记状态——这是有意的:内容变了就是另一条记忆。
  • 档案超过 200 KB 时要考虑上真正的索引(当前靠 mtime 缓存撑)。
  • 脱敏是模式匹配,只覆盖常见凭证形态,不认识的密钥格式仍可能漏过。
  • 召回内容一律按不可信数据处理;但模型仍可能被其中的话术影响,这是概率问题,不是开关问题。

设计文档

  • docs/DESIGN.md:设计推导——问题、约束、四个推导、被否决的方案
  • docs/PLAN.md:实施路线(外部评估摘要)——分阶段交付、验收标准与当前实现对应
  • docs/PHILOSOPHY.md:哲学迷思——中文房间、哲学僵尸、记忆与人格同一性

设计取舍

详细推导见仓库外的两份文档(架构方案 v0.4 / 实施方案 v1.0)。几条关键决定:

  • 不建 SQLite、不上 embedding:21 KB 档案上用 2-gram 就够,先冻结评测再谈升级。
  • 注入前置而不是追加:追加在尾部时模型容易顺着注入块说话。
  • 覆盖率阈值:只靠 top1 相对阈值会放过噪声,必须加查询 2-gram 命中率下限。
  • 情感只接 systemPrompt:不接 selfwake 的调度闸门,避免两套系统抢方向盘。

License

MIT

Comments

Loading…

Similar plugins

dsh-memoir

by Qinling-Melon-Farmers

DeepSeek Harness (DSH) local-first cross-session project memory: zero bundled runtime deps, bounded cache-friendly Hot Memory, BM25 recall/cache, provenance, lifecycle and bilingual Web GUI; no embedd

Memory & ContextManifest valid

★ 38

↓ 788/wk

Apache-2.0

TypeScript

Oct 19, 2026

dsh plugin --profile web add dsh-memoir

by Tangcuyu4

DSH 超长记忆包:跨会话长期记忆 + 长文分块检索 + 聊天记录提取精炼,纯 JS 混合检索零依赖

Memory & ContextSessions & MessagesManifest valid

★ 0

MIT

JavaScript

Oct 8, 2026

dsh plugin --profile web add dsh-long-memory

by SiriusWJ

DSH 简化版记忆插件:SQLite 条目化记忆(标题/重要程度/来源/内容,增删改查)+ 日历与到点提醒(月视图+时间轴+待执行/已完成双tab),对话面板记忆 tab 与设置二级菜单,中英双语自动跟随。

Memory & ContextSessions & MessagesManifest valid

★ 2

BSD-3-Clause

JavaScript

Sep 15, 2026

dsh plugin --profile web add dsh-lite-memory

by ly2601620664

陪伴型长期记忆 DSH 插件:分层记忆(对话→事实→场景→人格)、规则抽取、时间衰减检索,全本地文件、append-only 不丢数据。

Manifest valid

★ 0

MIT

JavaScript

Oct 23, 2026

dsh plugin --profile web add dsh-pet-memory

by Fishsb

DSH 长期记忆插件:记忆库 + 会话蒸馏自动沉淀 + 设置面板,越用越懂你。守藏(Shoucang)单插件,panel + scheduler + 内嵌记忆技能。

Terminal & ClientsManifest valid

★ 5

Apache-2.0

JavaScript

Sep 27, 2026

dsh plugin --profile web add dsh-shoucang-memory

by 1304836815

DSH 会话级记忆插件:收尾提醒 + MEMORY.md 记忆索引维护 + 实时对话日志 + LLM 摘要压缩,配置面板在 设置→插件。Session memory for DeepSeek Harness.

Manifest valid

★ 0

MIT

JavaScript

Aug 21, 2026

dsh plugin --profile web add @dsh-external/dsh-auto-memory