DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

@tuhengyu/dsh-full-life-memory

Full Life Memory

仿生终身记忆:上下文放不下时把旧轮次蒸馏成 token 线索并从历史切除,需要时用 recall_from_clues 把线索重建成回忆。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add @tuhengyu/dsh-full-life-memory@0.7.1
README兼容性版本

兼容性与来源证明

Full Life Memory 以 @tuhengyu/dsh-full-life-memory 发布,当前版本为 0.7.1。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/11/2

版本

0.7.1stable
2026/11/2
0.7.0stable
2026/11/2
0.5.0stable
2026/11/1
查看其余 4 个版本收起版本
0.4.0stable
2026/11/1
0.3.6stable
2026/10/31
0.3.2stable
2026/10/31
0.2.3stable
2026/10/24

相关插件

正在加载相关插件…

最新版
0.7.1
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
195 kB
文件数
18
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 4
周下载
0
最近提交
2026/11/2
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

相关插件

继续浏览 memory-context 分类下经过校验的插件。

Experimental Session Search@deepseek-ai/dsh-experimental-session-search为 Agents 提供搜索和读取当前工作区早期会话的工具。Hindsight Coding Agents@vectorize-io/hindsight-coding-agents面向编程代理的仅反思式 Hindsight 长期记忆(可插拔支持多种运行框架:opencode、……),自动在后台导入(无需设置 CLI)。Contextdsh-context用于上下文洞察和管理的 DeepSeek Harness 插件,提供上下文仪表板和上下文命令,帮助了解上下文的构成及其演变过程。Memory Plugin@openviking/dsh-memory-plugin适用于 DeepSeek Harness 的 OpenViking 记忆与上下文套件

README

Full-Life Memory

Full-Life Memory

不存原文,只存线索。
像人一样遗忘,也像人一样回忆。

@tuhengyu/dsh-full-life-memory

一个给 DeepSeek Harness 用的「仿生终身记忆」插件:
上下文快满时,它把旧对话蒸馏成几个关键词,从历史里物理删除;
当你再提起那件事,它顺着线索把记忆重新长出来。


上下文不是硬盘。 人不会记住三个月前的每一句话,只留下几个名字、半句原话、一种「我们好像聊过」的感觉。 需要的时候,再顺着这些线索,把当时的场景重新拼出来。

✨ 三个核心卖点

🧠 仿生记忆
不存原文,只存 Token 线索
落盘的只有 keywords、seed_tokens、一句摘要——没有 message 正文,没有向量,没有 embedding。回忆时用线索组装一段"想起"的提示交给模型,而不是把数据摊开给它看。
⚡ 零 Token 成本
正则蒸馏,不调模型
遗忘不经过任何 LLM:引号里的原话、文件路径、标识符、中文短语,用规则抽出来就完事。一次折叠 0 次模型调用、0 token 计费、0 延迟。
✂️ 真正释放上下文
物理切除,不是"请忽略"
走 DSH 的 surface 节点替换,被切掉的 6 个节点直接从下一轮请求里消失。不是 system prompt 里那句"请忽略更早的内容",是真的不发了——KV cache / 显存跟着一起降。

🔁 它是怎么运转的

        agent/pre-step
             │
             ▼
   tokenMeter.measure(session)
             │
   < 8000 ───┴─── ≥ 8000
     │              │
  keep going        ▼
          keep the last 4 turns, fold the oldest 2
                    │
                    ▼
          regex distill  →  keywords + seed_tokens    (0 LLM calls)
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
   SQLite memory_clues   surface replace
   (only file on disk)   6 nodes → 1 checkpoint
          │                   │
          │                   ▼
          │            【🧠 记忆已折叠】…
          ▼                   │
   recall_from_clues  ◄───────┘
   rebuilds the scene

🆚 和别的做法比

方案每轮额外成本上下文占用旧事怎么找回来真的移除了吗
全量保留0线性增长,迟早爆窗原文还在❌
LLM 摘要压缩每次压缩 1 次模型调用压缩后仍占位读那段摘要✅(摘要节点)
向量 RAG嵌入调用 + 每次检索检索片段临时塞入召回原文分块❌ 原文还在库里
Full-Life Memory0只留一行提示线索 → 模型自己重建✅(surface 替换)

一句话区别:向量库是「查」,线索是「想」。 检索把原文递给你,回忆让模型自己长出来——后者更像人,也更省。

🚀 安装

plugin_manager { action: "install_bundle", target: "<本目录的绝对路径>" }

装完重启一次 DSH。之后每个新会话都会带上:

  • recall_from_clues 工具(Phase 1)
  • 自动遗忘钩子(Phase 2,默认开启)

兼容性:@deepseek-ai/dsh-agent / dsh-tools 声明为 >=0.2.1-rc.2 <0.3.0。 DSH 会把这两个 peer 依赖当作兼容版本要求;钉死小版本会在 DSH 升级后报“不兼容”, 所以这里用区间,0.2.x 的补丁与 RC 升级都能直接通过。

本插件是 link 安装:改完代码不用重装,但要重启 Host 才会重新加载模块。

⚙️ 配置

- insert:
    - id: full-life-memory
      name: '@tuhengyu/dsh-full-life-memory'
      config:
        dbPath: '~/.dsh/full-life-memory/memory.db'  # 线索库
        limit: 5                                     # 一次回忆取回几条线索
        maxPromptChars: 1800                         # 回忆提示的字符上限

        autoForget: true                             # Phase 2 总开关
        forgetThresholdTokens: 8000                  # 超过多少 token 开始遗忘
        forgetTurns: 2                               # 每次切掉几轮已完成对话
        keepCompletedTurns: 4                        # 最近这么多轮永远保留

        sceneOverrides: {}                           # 按场景覆盖,见下一节
字段默认说明
dbPath~/.dsh/full-life-memory/memory.db目录自动创建,WAL 模式
limit5单次回忆最多带几条线索(上限 20)
maxPromptChars1800超出截断并标注"更早的线索已淡忘"
autoForgettrue关掉后只剩手动回忆,历史不再被切
forgetThresholdTokens8000用 ctx.tokenMeter 的口径;没有该服务时按字符粗估
forgetTurns2一次折叠几轮
keepCompletedTurns4保护最近对话:已完成轮数 ≥ forgetTurns + keepCompletedTurns 才动手
sceneOverrides{}按场景覆盖,键是会话 header.agentPreset

🌐 多场景覆盖

桌面端、QQ 群、QQ 私聊、微信……同一个模型在不同入口的"记忆压力"完全不同,所以除了全局默认,还可以按场景覆盖:

autoForget: true
forgetThresholdTokens: 8000   # 全局默认(桌面端)
sceneOverrides:
  qqbot:
    enabled: true
    forgetThresholdTokens: 4000   # 群聊碎片多,早点折叠
    keepCompletedTurns: 1         # 只保最近 1 轮
  wechat:
    enabled: false                # 微信交给别的插件,本插件直接让路

场景标识 = 会话的 header.agentPreset(小写)。DSH 的 SessionHeader 没有单独的"渠道"字段,QQ/微信这类接入插件通常用自己的 agent 预设建会话,所以拿它当场景键最稳;没有预设时退回 header.origin,再退回 default。桌面端的默认预设通常是 standard,想给桌面单独一套规则就写 standard:。

生效规则:

  • 场景里没写的字段继承全局
  • enabled: false 直接跳过折叠(连日志都不写)
  • 场景可以反向打开全局关闭的折叠——全局 autoForget: false 只影响没有场景覆盖的会话

设置页的「场景」标签页可以增删改这些覆盖,不用手写 YAML。

👥 群聊记忆隔离(Phase 3)

DSH 把一个 QQ 群当成一个 Session,默认是「全群共用一份记忆」——群友 A 说的话,B 一问就可能被召回,这就是串台。

打开 isolateByUser 后:

阶段行为
识别从最新一条用户消息的正文前缀抽发送者:[User: 12345]、[用户: 12345]、小明(123456):、qq: 10001;正则可用 senderPatterns 覆盖
折叠按发送者分组:自己的对话存成私有线索(user_id = 10001),别人的存成全群共享(user_id IS NULL);othersAsGlobal: false 则直接丢弃别人的对话
召回默认 scope: auto = 自己的 + 全群共享;scope: user 只看自己;scope: global 只看共享
降级认不出发送者 → 自动回到全局模式,不报错、不丢数据
isolateByUser: false        # 全局默认关
othersAsGlobal: true        # 别人的对话进共享记忆
sceneOverrides:
  qqbot:
    isolateByUser: true     # 群聊场景打开

旧库不用手动处理:启动时检测 memory_clues 缺 user_id 就自动 ALTER TABLE 补上,历史线索保留为共享记忆(user_id 为 NULL),新折叠的才按人归档。

🔌 NapCat / AstrBot 这类桥接的兼容

桥接插件不会给 DSH 传结构化发送者,只能从正文里读。为了少踩坑,做了四件事:

场景处理
昵称: 内容(AstrBot 常见)新增昵称前缀正则;注意:、12:30 这类不会误判
一条 prompt 合并多个发言人逐行识别,按行归属,不再整条算给第一个人
[CQ:at,qq=…]、[User: 123]蒸馏前剥掉,不会变成线索词
格式对不上、识别失败退化成全群共享,不报错;日志里 owners: global 能看出来

排查格式时打开 debugSender: true,折叠时会打印:

full-life-memory: sender probe preset="qqbot" sender="小明" groups=2 sample="我的猫叫豆豆"

还有两个边界要记住:

  • 纯昵称做键不稳定(改名、同名);能让桥接带上 QQ 号就带 [User: 12345],比昵称可靠。
  • 桥接必须按群复用 DSH Session;如果每次请求都新建会话,永远凑不出「已完成轮次」,折叠不会触发。

🎯 场景兜底:桥接不设 agentPreset 怎么办

场景原本只认 header.agentPreset。如果桥接不设预设,用 sceneMap 按正则匹配会话的 preset / origin / 会话 id / cwd:

sceneMap:
  '^qq-': qqbot          # 会话 id 前缀
  'napcat|astrbot': qqbot
sceneOverrides:
  qqbot:
    isolateByUser: true

匹配到场景后,线索会带上 scene 字段,排错时能直接看出这条记忆来自哪个场景。

🚧 隔离粒度:跨群还是按群

isolationScope 决定同一个人的记忆能不能跨群看到:

isolationScope: user        # 默认:同一个人跨群共享(人设一致)
# isolationScope: user+scene  # 更严格:同一个群才共享(避免 A 群的事在 B 群被抖出来)

user+scene 下查询会额外带上 scene = 当前场景 的条件;全群共享记忆(user_id IS NULL)两种粒度都可见。

🤖 AstrBot / NapCat:对话不经过 DSH 时

如果整条链路是 NapCat → AstrBot → 模型,DSH 根本不在场,插件的钩子不会执行。 仓库里的 astrbot/ 是一个独立的 AstrBot 插件,默认用纯 Python 读取同一个 SQLite,不需要 Node:

QQ 消息 ──► AstrBot ──► astrbot/ 插件 ──► memory.py (sqlite3) ──► 线索

安装(AstrBot 插件页 → 安装插件):

  • 从链接安装:填插件仓库地址(仓库根目录就是 astrbot/ 的内容)
  • 从文件安装:下载 astrbot_plugin_full_life_memory.zip(Release 附件)
  • 或者直接把 astrbot/ 拷进 data/plugins/astrbot_plugin_full_life_memory/

配置里把 db_path 指到 DSH 用的同一个库即可(留空默认 ~/.dsh/full-life-memory/memory.db)。 命中触发词(记得 / 上次 / 之前…)时回忆一次并注入 system_prompt,同一个群友 120 秒内只查一次。

也可以用 flm CLI 自己接别的平台:

npm i -g @tuhengyu/dsh-full-life-memory     # 安装后得到 flm 命令
flm recall --text "你还记得上次那个数据库吗" --user 10001 --scene qqbot
flm remember --keywords "数据库,sqlite" --seed "用 node:sqlite 存线索" --user 10001
flm stats

输出是 JSON,方便任何语言调用。安装与配置细节见 astrbot/README.md, 发布到插件的步骤见 astrbot/MARKETPLACE.md。 核心逻辑只有一份(同一个 SQLite、同一套 SQL),DSH 插件、AstrBot 插件、CLI 都只是消费者。

🛠 设置界面

两个入口,同一张表单:

  • Settings → 终身记忆(独立设置页)
  • Plugins → 已安装插件 → Full-Life Memory(插件详情页的配置区,DSH 的插件配置约定位置)

选项用大白话,不再出现「阈值 / 折叠轮数」这类实现词:

控件含义
遗忘触发条件对话超过多少 token 时开始遗忘(调大记得更久)
遗忘会话轮数一次遗忘几轮已经聊完的对话
最近记忆保留轮数最近这么多轮永远保留,方便接着聊
自动遗忘总开关

分为两个标签页:

  • 全局默认:上面那四项
  • 场景:每个场景一张卡片(启用开关 + 三个数值 + 删除),底部输入场景标识即可新增

下方实时算出「什么时候会触发」:例如 至少要有 6 轮聊完的对话(遗忘 2 轮 + 保留 4 轮)才会开始,改数字时同步刷新。

🌍 多语言

表单右上角有语言下拉框,选项来自 DSH 的语言服务(不是插件自己写死的列表),切换时调用 ctx.locale.setLocale(id)——也就是跟随全局偏好,插件不维护自己的语言状态。

只带 zh / en 两套文案,加语言只要两步:

// client.js
const DICTS = { zh, en, ja }          // ① 补一份字典
// locale/ja.json(插件管理器里显示的名字)
{ "meta": { "title": "フルライフ記憶", "description": "…" } }

不需要改 UI:下拉框会自己出现 ja(前提是宿主语言列表里有它,可用 ctx.locale.addLanguage({ id, label, fallback }) 注册)。缺键会走宿主的 fallback 链,不会显示 undefined——client-smoke 里有一条断言专门检查所有字典键集合一致。

🔄 检查更新 / 一键更新

表单上方有一行版本信息:v0.3.5 [检查更新],最右侧是语言下拉框。

状态表现
点「检查更新」请求 registry.npmjs.org/<包名>/latest,与运行中的版本比对
有新版本显示 → v0.3.2 和「立即更新」
已是最新顶部轻提示「当前已是最新版本」,2.6 秒后自动消失
点「立即更新」调用 DSH 的 pluginManager.installBundle,由 Host 执行 pnpm 下载并校验
更新完成弹出模态框:「更新已下载,请重启 DSH 以应用新版本」

为什么不自己 child_process 跑 pnpm:pluginManager 已经处理了 profile 写入锁、依赖脚本审批、peer 兼容性检查、失败回滚、registry 回退和「是否需要重启」的判定。自己 spawn 会绕过这些,还可能把 profile 的 package.json 写坏。

版本探测优先走浏览器直连 registry;如果部署的 CSP/CORS 拦住了跨域请求,会退回 Host 的 pluginManager.inspect 再查一次。

这些字段标了 .volatile():保存后下一轮就生效,不用重启 Host;已经折叠掉的历史不会被恢复。

👀 你会看到什么

对话流里多一行系统提示:

【🧠 记忆已折叠】为了腾出空间,我已淡忘更早的 2 轮对话,
留下的线索:E:/Fishwork/app.ts、recall_from_clues、node:sqlite。
需要时我会用 recall_from_clues 自己回忆。

日志里多一行账:

full-life-memory: folded 2 turn(s) (~9123 tokens) from surface seq 2..9
                  as compaction 6f1c…; clues: E:/Fishwork/app.ts, recall_from_clues, node:sqlite

然后你随口问一句「我们之前那个 sqlite 的事呢?」——模型会自己调 recall_from_clues,把线索接成回忆。

🧩 工作原理(30 秒版)

  1. 测压:agent/pre-step(waterfall)里用 ctx.tokenMeter.measure(session) 读当前请求压力。
  2. 选段:只挑已完成轮次(turn/end 之后),天然避开半个 tool-call;surface 第 0 个 system 节点永不参与。
  3. 蒸馏:正则抽 keywords 与 seed_tokens,连同 session_id 写进 memory_clues 表。
  4. 切除:session.append('user/message', checkpoint, { surfaceOp: { op:'replace', startSeq, endSeq } })——和 DSH 自己的 dsh-compaction-basic 逐字同一条路径。
  5. 留痕:外面套 compaction/start → summary → replace → end,Chat 因此把它渲染成原生的「记忆折叠」行,而不是一条用户消息。

安全边界都是显式校验过的:区间必须工具配对平衡、没有未闭合的 compaction/start、同一轮最多切一次、最近轮次受保护。任何一步失败都只是"这次不遗忘",绝不留半截事务。

❓ 常见问题

忘掉的东西还能找回来吗? 能找回"上下文",找不回"原文"——这正是设计目标。线索足够模型重建当时在聊什么、做到哪一步;逐字复述不重要。

真的不花 token 吗? 遗忘过程 0 token(纯正则)。只有你主动回忆时才会花几百 token——这笔钱花在真正需要的那一刻,而不是每一轮都替全部历史付费。

中文能匹配吗? 能。线索库用 LIKE 模糊匹配而不用 FTS5:中文不分词,线索本来就短,LIKE 反而更稳;% 和 _ 已转义。

会不会和 DSH 自带的自动压缩打架? 不会。检测到未闭合的 compaction/start 就跳过;自己开事务时严格成对闭合,不会把锁留给别人。

会不会把系统提示或工具配对切坏? 不会。system 头永不切;只切 turn/end 之后的范围;区间前后都做 tool-call/result 平衡校验。

数据在哪?会不会上传? 只有一个本地 SQLite 文件,默认 ~/.dsh/full-life-memory/memory.db。没有网络请求,没有遥测。

能只用手动回忆吗? autoForget: false。历史不再被切,recall_from_clues 照常可用。

🗂 项目结构

dsh-full-life-memory/
├── package.json          # bundle 清单 + dsh.bundle.patch + dsh.client
├── cordis.patch.yml      # 插入 Host 插件行 + 默认 config
├── index.ts              # Host 源码(类型完整,改这里)
├── index.js              # Host 运行时 = index.ts 编译产物
├── client.js             # 浏览器半边:Plugins 页里的设置界面
├── locale/{en,zh}.json   # 插件管理器里的标题与描述
├── icon.svg
└── test/
    ├── smoke.mjs         # Phase 1:命中 / 未命中 / 截断 / 转义 / 连接回收
    ├── auto-forget.mjs   # Phase 2:阈值 / 切除区间 / 配对校验 / 落库 / 每轮一次
    └── client-smoke.mjs  # 设置页:用假 slots/configForms 跑一遍渲染

🧪 测试

node test/smoke.mjs
node test/auto-forget.mjs
node test/client-smoke.mjs

auto-forget.mjs 用一个仿 Session 契约的假会话跑完整链路,并额外做一次 index.ts 与 index.js 的行为对拍:同一个场景分别执行,逐字段比较追加事件、被切的 surface 区间、落库的线索行,确保"编译产物"和源码不漂移。

覆盖:阈值以下不动、到阈值切最旧两轮、replace 区间精确、system 头保留、后续轮次完好、线索落库、同轮不重复切、最近轮次受保护、工具配对不平衡拒绝、未闭合 compaction 拒绝、落库失败不留半截事务。

🧭 设计取舍

规则蒸馏不如语义摘要细腻——它抓的是"名字、路径、术语、原话",不是"结论"。这是刻意的:遗忘不该再花钱,也不该再等一次模型响应。真想要语义摘要,只需替换 extractClue() 一个函数,返回结构不变,其余逻辑(选段、切除、落库)完全复用。

🛣 Roadmap

  • extractClue 的可选 LLM 后端(默认仍是正则)
  • 遗忘曲线权重:越久远的线索越淡,命中时排在后面
  • 按项目 / workspace 分区的线索库
  • /forget 手动命令与「回忆命中率」统计
  • 线索之间的弱关联图,支持"顺着一条线索想起另一条"

📄 License

MIT © tuhengyu · 完整文本见 LICENSE

记忆不是存储,是重建。