dsh-layers-hippocampus

memorynpmMIT

Layered long-term memory for DeepSeek Harness: append-only event log, rebuildable tag index, day diaries, semantic layer, trend quarantine, and an offline knowledge-graph panel.

下载量 / Downloads
0

Install

dsh plugin --profile web add dsh-layers-hippocampus

Sandbox test

This plugin has not been tested yet. Submit a test →

README

dsh-layers-hippocampus · 海马体记忆

给 DeepSeek Harness(DSH)智能体的分层长期记忆:追加式事件日志、可重建标签索引、按天日记、独立语义层、L2.5 趋势隔离、离线知识图谱,以及一个完整的 Web 面板。

版本 · 1.5.6

包名 · dsh-layers-hippocampus(npm 只允许小写;仓库名保留 dsh-Layers-Hippocampus,Hippocampus 双 p)

仓库 · <https://github.com/382quaii/dsh-Layers-Hippocampus>

许可证 · MIT

运行时依赖 · 零。Host 半边只用 Node 内置模块,React 由 Harness 提供

详细设计 · [docs/ARCHITECTURE.zh.md](docs/ARCHITECTURE.zh.md)


安装

从 GitHub

pnpm add "github:382quaii/dsh-Layers-Hippocampus#v1.5.6"

从 npm

pnpm add dsh-layers-hippocampus

通过插件管理器(推荐)

plugin_manager action=install_bundle target="C:\Users\86135\Documents\deepseek-harness\default-workspace\dsh-memory"

安装后 profile 会得到这一行:

- insert:
    - id: hippocampus
      name: "dsh-layers-hippocampus"
      config:
        briefing: true

Host 半边随下一次宿主启动生效;UI 半边在页面加载时从 boot graph 取得。冷启动后用下面的脚本确认路由已就绪:

node scripts/wait-for-routes.mjs

工具

工具(memory_*) · 用途

remember · 追加一条长期记忆(内容哈希幂等);可带 media_url + media_type 指向附件;pinned: true 表示“永不衰减、命中标签时置顶”的经验教训(必须带 tags,否则 MEM_E_PINNED_TAG_REQUIRED)

checkpoint · 记录唯一进行中的重任务:task_id、progress(0–100)、updated_at

space_transfer · 跨空间原子迁移:event_ids + target_space_id + transfer_mode: copy \ · move;必须 user_approved: true(AI 自行调用会被引擎拦截);隐私词拦截、剥离 raw_turn、目标空间重新生成 event_id 并打标

transfer_to_global · 迁移到 global 空间,参数与安全门禁同 space_transfer(memory_transfer_to_global)

recall · 关键词 + 标签检索,衰减加权,含图谱联想;宽限中 mid 的命中只回元数据并引导 deep_raw;mode: "deep_raw" 走受限 raw 扫描

capture · 把一轮原始对话存入取证层(受门控与预算限制,不进索引)

reinforce · 确认一次记忆,不重写内容,并推进复习档位

forget / restore · 两阶段删除(pending_delete 倒计时)与取消/反墓碑

admin · status / maintain / active_tags / semantic / active_task / reviews / pending_deletes

原始回合留存(raw)与 deep_raw

  • 极简黑匣子:每行恰为 { turn_id, timestamp, role, content };不写 tags / salience / decay / event_id / 图谱关系 / metadata。寻址用 (日期文件, 行号)——append-only 保证行号稳定(这是“禁止行号指针”在 raw 层的唯一合法例外)。
  • 独立日分片 raw/YYYY-MM-DD.jsonl,不进主日志、不进索引、启动不加载;只有 deep_raw 和 maintain() 的 TTL 会读它。
  • 异步写盘:捕获只入内存队列,每 10 条或 1 秒批量 appendFile,绝不阻塞 session/event 回调。
  • 明文存储 + 读出脱敏:落盘保留 100% 原文(黑匣子完整性);deep_raw 返回前对 snippet 做脱敏(Bearer、sk-、长 base64 串 → [redacted]),防止密钥进入云端 prompt。注意:本地磁盘为明文。
  • 墓碑:forget 真正执行 purge 后,按内容 hash 追加 { type: "raw_tombstone", hash, timestamp };扫描时命中墓碑的记录直接跳过(防死灰复燃)。
  • 时间窗:memory_recall mode="deep_raw" 通常必须同时给 start_time 与 end_time,缺失抛 MEM_E_INVALID_INPUT;但若查询词命中超级大标签(关联数 > 500),缺失时间窗抛更具体的 MEM_E_TIME_RANGE_REQUIRED(1.5.0)——大标签裸扫正是要防的上下文/内存洪峰。
  • Token 预算:结果上限 raw.maxResultTokens(默认 1000),超出截断并在 notes 末尾注明「由于预算限制,部分原始记录已被截断」。
  • 最新优先扫描:deep_raw 在分片内从尾部倒序扫描(日文件内越新越先看到),回合预算 raw.maxScanTurns(默认 5000,UI 可调)控制"从最新往回看多远"。超出预算返回 truncated: true + notes 说明,绝不假装更旧的数据不存在。1.4.3 前是头部正序扫描,大分片里最新的 5000 条永远查不到——黑匣子的核心价值被反转,已修复。
  • ⚠ 尾扫偏置(明确的已知代价):单个日分片超过 maxScanTurns(默认 5000)时,一次 deep_raw 只能看到该分片最新的 N 条;更早的历史记录不在本次扫描范围内,需要:① 调大 raw.maxScanTurns(上限 50 000);或 ② 按时间窗分页查询——把 end_time 逐步前移、用多个时间窗分别扫描。返回体里 truncated: true 与 notes 会明确告知"本次没扫完",绝不静默返回空。该偏置是"查新优先"的直接代价。
  • TTL:maintain() 删除文件名日期早于 今天 - retentionDays 的整文件;今天正在写的文件绝不删。raw 体积计入 Dashboard 存储环(panel.storage.rawBytes + 总 diskBytes)。
  • 自动捕获:订阅 session/event,只收 user/assistant 原文(剥离宿主注入的 Current runtime context. 段),工具输出默认不收、但 isError 的失败结果强制入库。

两阶段删除与间隔重复

  • forget 先挂起(默认 24h,delete.graceHours),restore 在到期前直接取消;到期由 maintain() 推进到 tombstone→archive→consolidation→purge。未知 id 在挂起前就报 MEM_E_NOT_FOUND。
  • 复习排期 1,2,4,7,15,30 天,持久化在 state/reviews.json;reinforce 推进一档,maintain() 汇总到期项,memory_admin action="reviews" 可查。

数据目录迁移(UI)

设置页 dataDir 可编辑:保存后返回 202 + state=migrating,后台 fs.promises.cp 拷贝、两端 recordCount 校验、写入 .migration-complete 后才切换 dataDir 并重开存储;校验失败删除目标、旧目录仍权威;源目录保留为备份。并发请求由 .migration.lock 阻断(MEM_E_MIGRATION_LOCKED),面板显示进度条。

active_task 直查底层索引,不受活跃集合 cap 200 限制;写入新 checkpoint 会降级旧记录,7 天未刷新由 maintain() 自动降级,模型的 forget 只是 happy path。

提示词软引导与自有工具瘦身

  • 系统提示新增 memory:policy(静态段,保持前缀缓存稳定):要求模型在需要回忆历史、查阅文件、获取系统信息时优先调用 memory_recall,禁止盲目读取外部超长文件或让原生工具输出全文。
  • 本插件工具返回超长 JSON(默认 >2000 tokens)时,由 slimToolPayload 先把完整内容写入 raw,再返回带 [Slimmed] 的瘦身版:保留 summary / topics / key_entities / recovery_hash。
  • 恢复原文:memory_recall(mode="deep_raw", hash="…"),按内容 sha256 精确返回;这是"软拦截"能覆盖的最大范围——其他插件的工具输出仍由宿主投射,插件无法改写。

多模态与防爆仓

  • media_url 只接受 http(s) URL 或绝对路径;media_type ∈ image | video | document | audio,缺一即 MEM_E_INVALID_MEDIA。
  • 内联 base64 不落库:content 中连续 base64 字符 ≥ 256 即抛 MEM_E_INVALID_MEDIA;200 字符以内视为普通文本,不会误杀。

记忆流转(上下文 → 长期 → 联想 → 月记)

1. 推币机折叠:上下文触发 evict 时被驱逐的块不再丢弃,引擎把最近一批折成一条 folded_summary 事件写回 L1(标签 status:folded),抽取人名、任务语句与核心结论。

2. 在线联想唤醒:查询命中某个 Tag 时读取 state/graph.json,取该节点最强的 3 个邻居,把邻居事件以 0.5 惩罚系数放进候选池;命中标记 association.via,直连结果永远排在联想结果之前。

3. 月记(Monthly Memo):maintain() 发现某个自然月已完整,就把该月日记压成一条 status:monthly 记忆;月记不参与日常衰减(decay = 1),模糊时间查询(“上个月”“2023-10”“去年”)会优先召回它。

一切都从唯一真相源(追加式日志)派生;索引、日记、活跃标签集、知识图谱都是可丢弃、可重建的投影。

分层

1. L1 事件日志:追加式 JSONL 代际 + CURRENT 指针。

2. L2 索引:标签表、活跃集合、日记、墓碑;A/B 双缓冲,读者永远看不到半成品。

3. L1.5 标签层级树:root/mid/leaf 三层寿命 + 宽限幽灵;派生缓存,state/tag-tree.json。

4. L2.5 趋势隔离:短命观察,经晋升窗口与突发检测才升级为记忆(情景可删,模式不删)。

5. L3 语义层:摘要独立于原始日志生死。

6. 图谱:标签共现网络的离线投影。

L1.5 标签层级树与幽灵节点

层级标签按 / 解析为 root / mid / leaf 三层(tech/frontend/vue3),三种寿命:

  • root 永生:tech 这类命名空间根,永不删除;无 / 的扁平标签(project:dsh)同样是受保护的根。
  • leaf 引用归零即死:它的所有事件被遗忘后进入待修剪队列;maintain() 每次只消费 tagTree.pruneBatchSize(默认 100)条,队列落盘、跨重启分批排空——绝不一次维护风暴。
  • mid 宽限:失去最后一个叶子后进入 midGracePeriodDays(默认 30 天)宽限期(graceUntil)。期内挂上新叶子会立即复活;期内它叫幽灵节点(ghost),只存在于 state/tag-tree.json

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::2,最后更新 2026-11-04

Links

GitHub · Homepage · npm

Same category