Cross-session long-term memory: captures durable facts from each turn, auto-associates them by shared entity and tag, and recalls with BM25 plus spreading activation over the link graph.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-memory-loom
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:Ray144165154/dsh-memory-loom
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
This plugin publishes its README in Chinese only.
DeepSeek Harness 的跨会话长期记忆与联想召回插件。 让 agent 记住你上一次告诉它的偏好、约束和决定——并且在这次会话里不需要你重复。
它解决什么问题
DSH 的会话是隔离的。你在 A 项目里说过"这个仓库必须用 pnpm,不要用 npm",下周开一个新会话,agent 一无所知,你得再说一遍。
dsh-memory-loom 做四件事:
| 阶段 | 做什么 |
|---|---|
| 捕获 | 每次模型调用前扫描最新的用户消息,用规则抽取其中的持久事实(偏好 / 约束 / 决定 / 明确要求记住的内容) |
| 存储 | 写进 DSH 自己的 storage domain(agent_memory 域),落在 $DSH_HOME/storages 下,重启和升级都不丢 |
| 联想 | 每写入一条,自动与共享实体或高重合标签的旧记忆建立关联边,形成一张图 |
| 召回 | 用当前用户消息做查询,三路打分后把最相关的几条注入系统提示词;模型也可以主动调 memory_recall |
"联想"不是修辞:召回分数里有一条是在关联图上做激活传播。这意味着一条和你的问题没有任何共同关键词的记忆,只要它关联着一条命中的记忆,也会被带到模型面前。这是纯关键词检索做不到的部分,也是这个插件的主要价值。
安装
1. 确认 dsh 命令
桌面版不会把 dsh 放进 PATH,CLI 真身在:
<app>\node_modules\@deepseek-ai\dsh\lib\bin.js
其中 <app> 是桌面版的安装目录,通常是
%LOCALAPPDATA%\Programs\DSH Desktop\resources\app。
2. 把插件挂进 web profile
把 <插件检出目录> 换成本仓库在你机器上的路径(例如 C:\src\dsh-memory-loom):
$plugin = '<插件检出目录>'
$env:DSH_HOME = "$env:APPDATA\dsh-desktop\harness"
$app = "$env:LOCALAPPDATA\Programs\DSH Desktop\resources\app"
$node = "$app\node_modules\node\bin\node.exe"
$bin = "$app\node_modules\@deepseek-ai\dsh\lib\bin.js"
& $node $bin plugin --profile web add "link:$plugin"
link: 让 pnpm 做符号链接,所以改代码后不需要重装。这条命令会把 dsh-memory-loom 追加进 profile package.json 的 dsh.profile.bundles。
link:模式有个前提:Node 解析裸模块说明符时会先 realpath,所以符号链接指向的源码目录必须自带node_modules(zod与@deepseek-ai/*的 peer)。否则插件会在导入时死于ERR_MODULE_NOT_FOUND。仓库里的tools/dev-link.ps1会替你准备好这些链接,并会跑一遍自检来证明解析确实通了。
如果你更想用独立安装的 dsh CLI,
dsh plugin --profile web add "link:$plugin"等价——只要DSH_HOME指向上面那个目录,否则它会装到另一个 profile 里去。
3. 重启 DSH,然后确认
打开 设置 → 插件 → 插件配置:
- 出现 长期记忆 卡片(展开可看到计数、记忆列表和操作按钮)
- 模型侧多出 6 个工具:
memory_recall/memory_remember/memory_forget/memory_link/memory_backfill/memory_stats
卡片为什么挂在"插件配置"这一页:
settings.plugin.item不是一张自由卡片列表。插件页会遍历已注册的 settings 命名空间,对每个命名空间分发一次同名卡片——所以卡片的key必须等于宿主侧ctx.settings.register()注册的命名空间名。两者不一致时卡片既不渲染也不报错,只是永远不出现,这正是本插件首次安装时卡片缺失的原因。SETTINGS_NAMESPACE与 client bundle 的key的相等关系由tools/smoke.mjs断言保护。命名空间的 schema 是空的:它是挂载锚点,不是表单。本卡片只做状态展示与操作,真实配置在 profile 的
cordis.patch.yml里。把 12 个配置键注册进命名空间会渲染出一个编辑"插件根本不读取的设置文档"的表单——一个会撒谎的界面。第一方的dsh-image-generation用的是同样的空锚点写法。
4. 让历史会话产生价值
新装的记忆库是空的。打开卡片点 从历史会话回填,或让 agent 调 memory_backfill,它会把过去会话里符合规则的持久事实一次性挖出来。
版本线兼容性(dsh 0.1.x / 0.2.x)
DSH 的 0.1.x 与 0.2.x 之间有破坏性契约差异。本插件对两条线都做了处理,差异是逐个读包内自带的 .d.ts 得出的,不是从调用点推断的:
| 契约 | 0.1.x(桌面版 0.9.2 / dsh 0.1.5-rc.2) | 0.2.0-rc.2(当前 latest) |
本插件的处理 |
|---|---|---|---|
| settings 服务 | ctx.settings.register(ns, schema, { applies }) 存在 |
已移除(register 在类型里 0 处)。ctx.settings 变成 SettingsForms:命名空间即 profile 条目 id,配置页从插件自己的 Config 自动生成(SettingsDescriptor.autoGenerate) |
registerSettingsAnchor() 特性探测,有 register 才调用 |
| 设置卡片槽位 | settings.plugin.item,按已注册的 settings 命名空间逐个分发 |
整棵树 0 处匹配 | 卡片注册包在 try/catch 里;0.2.x 上不显示卡片 |
defineTool / ctx.tools.register |
存在 | 存在 | 无需改动 |
defineDomain / domainTable |
存在 | 存在 | 无需改动 |
systemPrompt.section |
存在 | 存在 | 无需改动 |
sessionQuery.listSessions / readSession |
存在 | 存在 | 无需改动 |
connection.fetch.register(本插件的 4 个 HTTP 接口) |
{ path, methods, requestBody, fetch } |
形状完全相同。路径校验为 endpointFromPath('/api', path) + ENDPOINT_SEGMENT_PATTERN = /^[A-Za-z0-9_$.-]+$/,接受本插件的 /api/memory-loom.stats 形式 |
无需改动 |
为什么必须特性探测,而不是比版本号:这些包在 npm 上独立发版,latest dist-tag 曾长期指向无关的 0.0.1-rc.x 构建——版本号不可靠,探 API 才可靠。
为什么这个探测是必须的,而不是优化:settings.register 在 0.2.x 上不存在,直接调用会抛 TypeError → Service.init 拒绝 → 插件激活失败。而一个未激活的 loader 条目不只失去该插件的功能,还可能让整个 harness 启动失败。也就是说 0.1.3 及更早的版本在 dsh 0.2.x 上是有害的,不是"卡片不显示"这种程度。
当前验证状态
- 0.1.x 线:实测工作(工具、卡片、注入、持久化、4 个 HTTP 接口都验过)
- 0.2.0-rc.2 线:宿主侧契约已逐项核对(读 0.2.0-rc.2 包内
.d.ts与注册校验源码),结论是除 settings 与卡片槽位外全部兼容;但尚未在真实 0.2.x harness 里启动过,所以"激活"这一项仍属未实测 - 0.2.x 上的功能差异:配置页由
Configschema 自动生成(12 个键都可编辑,这一点比 0.1.x 的只读卡片更好);自定义卡片不显示——记忆清单与遗忘/回填按钮在 0.2.x 上没有界面入口,但memory_recall/memory_forget/memory_backfill/memory_stats工具照常可用
配置
配置写在 $DSH_HOME\profiles\web\cordis.patch.yml 里本插件那一行的 config: 之下。loader 只把这个子对象传给插件,写在外面的键会被静默忽略。
- id: memory-loom
config:
enabled: true
recallLimit: 6
minScore: 0.12
injectSection: true
autoExtract: true
autoExtractMax: 3
associationHops: 1
associationDecay: 0.35
halfLifeDays: 45
workspaceScoped: true
maxRecords: 5000
backfillSessions: 50
| 键 | 作用 | 调参直觉 |
|---|---|---|
enabled |
总开关 | 关掉后工具仍在,但不再注入提示词、不再自动抽取 |
recallLimit |
每次注入几条 | 6 是平衡点;调到 15+ 会开始吃掉上下文预算 |
minScore |
注入的最低分 | 最重要的旋钮。设为 0 等于"任何词重合都注入",通常比没有记忆更糟;调高到 0.3 更保守 |
injectSection |
是否注入系统提示词 | 关掉后就只剩模型主动调 memory_recall |
autoExtract / autoExtractMax |
自动抽取开关与每条消息上限 | 见下方"它不是什么" |
associationHops / associationDecay |
联想传播的跳数与衰减 | hops: 2 会显著扩大召回面,也显著增加噪声;decay 越小,间接关联衰减越快 |
halfLifeDays |
时间衰减半衰期 | 45 天;长期项目可调到 180 |
workspaceScoped |
是否按工作目录隔离 | true 时 A 项目记的事不会在 B 项目被召回 |
maxRecords |
存储上限 | 超出后按 salience × confidence × 新鲜度 淘汰最弱的 |
backfillSessions |
回填扫描多少个历史会话 | 只影响回填 |
改完保存即可,profile 是 patchReload: live,会热重组。
召回是怎么算出来的
三条信号加权:
| 信号 | 权重 | 说明 |
|---|---|---|
| 词法相关 | 0.55 | BM25 变体,字段加权:正文 1.0 / 标签 1.6 / 实体 1.8 |
| 联想激活 | 0.25 | 沿关联边传播,每跳乘 边权 × decay^跳数,多路径取 max 而非求和 |
| 时间新鲜度 | 0.12 | 以 halfLifeDays 为半衰期的指数衰减 |
| 使用频次 | 0.08 | log1p(useCount) 阻尼 |
再乘上 (0.4 + 0.6×salience) 和 (0.4 + 0.6×confidence)——注意是缩放而不是门限,所以一条低置信度的记忆在没有任何更好选择时仍然能被召回,但在同分时绝不会盖过高置信度的。
最后做两件事:按归一化正文去重(同一事实换句话说是同一内容哈希,但跨会话可能出现近邻改写),以及每个会话最多占 2 个名额,避免一次长会话垄断所有召回位。
中文分词用 CJK 二元组(bigram),英文用整词 + 停用词表。没有引入分词库,因为 BM25 的 idf 项本来就会压低高频词的权重。
autoExtract 是规则,不是 LLM
这一点必须说清楚,因为它决定了你会看到什么行为。
自动抽取是纯规则的:四条正则线索表,覆盖 preference / constraint / decision / fact 四类,每条都要求出现明确的措辞线索("记住""必须""我更倾向""from now on""we'll use"……)。它不会:
- 调用模型做摘要(那会让每次 prompt 组装多一次网络往返,翻倍延迟和成本)
- 产出
entity/task/insight三类(这三类交给memory_remember工具,让模型带着完整上下文自己判断) - 把问句当事实存下来(含线索的问句也会被跳过:"你记住了吗?"不会被存成一条关于"记住"的记忆)
代价是召回率不高:很多真正值得记的句子没有线索词,会被漏掉。收益是确定性——你可以预测它会记什么、可以审计、猜错了删掉就行,而不是面对一个悄悄改写了你意图的摘要器。
如果你要更高的召回率,正确做法是让 agent 主动用 memory_remember——工具的描述里已经把"什么值得记、什么不值得记"写清楚了。
要不要关掉它:实测下来两边差距很明显。规则抽取在真实的、任务导向的会话里产出 0 条(5 条真实消息里 1 条是命令、2 条是 harness 注入文本、2 条是"物理"这类短词),而它的两次误判都是把 harness 自己的提示词写进了用户记忆库;反过来,模型主动调 memory_remember 写的记录质量一直很稳。所以规则抽取的投入产出比是负的——它偶尔漏掉本该记住的句子,却需要你付出审阅与清理的成本。
关掉它(autoExtract: false)只留工具路径是稳妥的默认选择;注入的两个向量已经修好并有回归断言保护,所以打开也不是"有害",只是收益有限。这是一个质量偏好,不是规避。
数据在哪,怎么清
- 位置:
$DSH_HOME\storages之下由 storage-domain 管理的agent_memory域。layout: per-record,一条记录一个文档,方便单条备份或手工删除。 - 清空全部:停掉 DSH,删掉该域对应的目录即可。属于派生数据的取舍——记忆丢了可以回填,但不会自动重建。
- 清单条:卡片上每条记忆右侧的"遗忘",或让模型调
memory_forget(默认是"取代"而不是物理删除,保留可审计的痕迹和关联图结构)。
卸载与回滚
三种力度,按需要选:
# 1) 临时禁用(可热重载,改 profile 的 patch 层)
# 在 $DSH_HOME\profiles\web\cordis.patch.yml 里加:
# - id: memory-loom
# disabled: true
# 2) 彻底卸载(同时从 bundles 列表移除)
& $node $bin plugin --profile web remove dsh-memory-loom
# 3) 连同数据一起清掉:停掉 DSH,删除 $DSH_HOME\storages 下的 agent_memory 域目录
第 1 种是 dshmarket 也在用的官方热禁用机制,约 1 秒内重组成、不用重启。
开发
两种安装形态,用一条命令切换
# 联调模式(默认):link: 安装 + 插件目录自带的 node_modules
# 改完源码只需重启 DSH,不用重新打包
pwsh -File tools\dev-link.ps1
# 发布形态:打包成 tarball 再装
pwsh -File tools\dev-link.ps1 -Mode pack
tools/dev-link.ps1 做的事,以及它为什么存在:
link: 联调模式 |
tarball 发布模式 | |
|---|---|---|
| 安装物 | profile 里的符号链接指向源码目录 | profile 里的真实目录 |
| 改源码后 | 重启 DSH 即可 | 必须重新 pack + add |
| 依赖解析 | 插件目录必须有自己的 node_modules |
pnpm 从 profile 树向上解析,无需额外准备 |
| 脚本负责 | 建 junction、跑自检、切换 profile | 建 junction(为跑自检)、打包、删 junction、切换 profile |
link: 模式为什么需要那些 junction:Node 解析裸模块说明符(zod、@deepseek-ai/*)时会先 realpath,所以即使 profile 的 node_modules 里是符号链接,实际查找位置仍是源码目录。没有那个 node_modules,插件会在导入时直接死于:
ERR_MODULE_NOT_FOUND: Cannot find package '@deepseek-ai/cordis'
脚本用 cmd /c rmdir 删除 junction,不用 Remove-Item -Recurse——后者在目录 junction 上可能递归进目标,删掉 DSH 应用自己的 node_modules。
两种模式下,宿主侧改动都需要重启 DSH:已在运行的进程内存里持有旧模块。
离线自检
# 不需要启动 harness:52 项断言,覆盖模块解析、schema 编译、分词、抽取规则、
# 注入文本剥离、排序、联想传播、真实 store 的写入/关联/淘汰、工具执行、
# 清单契约(含 BOM、"卡片 key = settings 命名空间"两条)
node tools\smoke.mjs
tools/dev-link.ps1 会在切换前自动跑它,并把"能跑通"当作模块解析正确的证明。手工执行时需要先有 junction——直接跑脚本即可。
已验证 / 未验证
诚实地说清楚边界,比一个漂亮的"已完成"有用。
离线已验证(node tools/smoke.mjs —— 51 项断言,0 失败)
模块与 schema
- 模块解析:
@deepseek-ai/cordis的Service、@deepseek-ai/schemastery的Config、@deepseek-ai/dsh-storage-domain的defineDomain/domainTable、@deepseek-ai/dsh-tools的defineTool、zod全部真实可导入 Configschema 能应用 12 项默认值agent_memory域声明通过defineDomain的加载期校验
分词与抽取
- 英文整词 + 停用词表;CJK 二元组
- 四类线索各自命中;线索冲突时的优先级;含线索的问句被排除;无关对话零产出;内容寻址 id 的空白不敏感性;实体提取(路径 / URL / 反引号标识符)
排序与联想
- 关键词命中排序、工作区作用域过滤(含开关两侧)
- 纯排序层:零词法重合的记录能通过关联边被召回;
hops: 0时关联关闭;已取代的记录不召回;空查询返回空
真实 store + 工具集成(真实 MemoryStore 跑在内存假 domain 上,除磁盘 I/O 外全部是真实现)
- store 打开、写入、写入时自动关联、关联边在召回中真实传导
- 仅靠标签相似度建立关联时,能召回到词法重合严格为 0 的记录(这条是本插件的核心性质)
- 重复观测是强化而非新增记录,且
salience/confidence向最强观测取齐 touch计次、淘汰上限生效- 六个工具的
defineToolschema 全部编译通过——这是会在插件加载期直接抛错的高风险面 memory_remember/memory_recall/memory_stats/memory_forget实际执行,且返回对象的键与声明的 output schema 逐一比对一致sessionQuery不可用时memory_backfill抛出可读错误(而不是让插件不激活)
注入文本不得变成记忆(这条来自真实启动中的一次发现,见下)
- 真实形状的 runtime context 前导块 → 0 条候选,且剥离后为空串
- 前导块之后跟着一句真实偏好 → 恰好 1 条,且是被剥离后的偏好而不是样板文本
- 用户消息恰好以
Current runtime context.开头但并非注入块 → 原样保留,不被吞掉 latestUserText()用作召回查询时会剥掉前导块
清单契约
dsh.bundle.patch指向真实文件、files列表无缺项、client bundle 的id与包名一致cordis.patch.yml里的 config 键与Config声明完全一致(键名打错会被 schema 静默丢弃,读起来就像"这个设置没生效")
一个真实的收获值得记下来:"关联只能沿出边传播"这个缺陷就是被这个测试抓出来的。我在测试里手工构造了一条单向边,结果联想完全不工作。真实写入路径用的是对称边,所以线上表现正常——但一个只在单向边上失效的排序器,失效时不会有任何报错,只是召回悄悄变差。现在改成双向遍历,并加了这条断言。
已在真实 DSH 进程中验证
用一个独立 DSH_HOME(临时目录下的 _dshtest)做了真实安装与启动,验证全程没有碰正在运行的 profile(测试 home 与临时脚本已删除)。验证通过后又按需求把插件装进了真实的 web profile,装配确认无 load 错误。
装上之后立刻会发生什么:
autoExtract默认开启,所以插件会从所有会话的用户消息里抽取持久事实(本插件不做自动回填,回填只在卡片或工具里手动触发)。记忆库落在真实$DSH_HOME\storages\agent_memory下。想先观察不写入,把 profile patch 里本行的autoExtract改成false即可。
- 真实安装:
dsh plugin --profile web add "link:<插件检出目录>"→ pnpm 成功,且dsh自动把dsh-memory-loom追加进dsh.profile.bundles。这一步顺带证明了 bundle 声明正确——CLI 只把确实声明了dsh.bundle.patch的依赖加入 bundles,否则会警告declares no dsh.bundle并当普通依赖处理。 - 真实启动:实例在
127.0.0.1:44777起来,Service.init跑完、storage domain 打开、connection可选注入生效。 Config真的生效:GET /api/memory-loom.stats返回的 config 正好是 schemastery 的默认值——profile 那一行没有写config:,所以这些值只能来自static Config。- 真实持久化(写 + 读):回填后磁盘出现
storages/agent_memory/memories/<hash>.json,信封为{version, record},UTF-8 文本与 CJK 二元组标签正确;完整重启后从磁盘加载回 2 条——这条路径会跑一遍 zod 校验,所以记录 schema 也被真实验证了。 - 去重 / 强化语义:3 条克隆消息循环映射到 2 段文本 →
added: 2, strengthened: 1,与预期精确吻合。 sessionQuery真实读取:listSessions找到会话,readSession成功解码多帧 zstd 日志(每条日志 103~109 个独立帧),unreadable: 0。collectText在真实载荷上工作:从真实user/message事件恢复出文本。- 4 个 HTTP 路由全部实跑:
stats/backfill/evict/forget;forget后统计变成live=1 superseded=1,取代语义正确。
真实启动中发现并修掉的一个缺陷
第一次回填抽取结果是 0 条。我把真实消息逐条解出来才看清原因:5 条里 1 条是安装命令、2 条是 harness 注入的 runtime context、2 条是"高斯定理""物理"这类短词——0 条是正确结果,不是漏抽。
但那条注入文本暴露了一个真实假阳性:它确实会进入 user/message 载荷,而且读起来就是策略。实测证明,一段形如 Do not call image_generate. Never ask for an API key in conversation. 的注入文本会被存成两条"用户约束"记忆。任何 runtime context 措辞里带 "must" / "never" 的部署,都会把自己的样板文本永久写进用户记忆库,还署着用户的名。
修法:lib/text.js 新增 stripHarnessPreamble(),在抽取和召回查询两处剥离 runtime context 前导块。剥离刻意保守——要求精确的 Current runtime context. 开头,只删前面形如策略段落的块,其余原样返回;没有这个开头就完全不碰。配了 4 条断言,包括"用户消息恰好以该短语开头时不得被吞掉"。
边界说明:注入的提示词 section 是另一条路径,它们不会进入 user/message 载荷,因此不在这里处理——对它们的措辞做猜测只会引入假跳过。
已在真实模型轮次中验证
下面三项原先列为未验证,现已在其运行环境里实测通过:
- 6 个工具被模型实际调用:
memory_stats返回{total:6, live:4, superseded:2, links:4, by_kind:[preference:2, constraint:1, insight:1]};memory_remember两次写入均created: true,其中一次带显式关联返回linked: 1;memory_recall正常返回带分数的结果,且返回键与声明的 output schema 一致。 - 联想在真实数据上成立:以
tarball repacking workflow ERR_MODULE_NOT_FOUND查询,词法命中的是一条 tarball 记忆(score 0.782,via: lexical),而与查询零关键词重合的 pnpm 偏好以via: association(score 0.205)被关联边带出。这是本插件的核心性质在生产数据上的直接证据。 - 设置卡片的浏览器渲染:卡片已在 设置 → 插件 → 插件配置 正常显示(此前缺失的原因见上文第 3 步的说明)。
仍未验证
- 提示词注入在真实 turn 中的实际效果:section 的注册已被证明(否则
Service.init会抛错、路由与工具都不会存在),注入的召回块也已通过memory_recall间接验证,但"模型是否真的按注入内容行动"没有单独观测。
关于失败模式,有一点值得指出:装配钩子里读取会话是全程可选链的——context?.agent?.session,拿不到就退化成空事件列表,即"不注入",而不会让这一轮对话出错。所以即使我对 assemble 上下文字段的假设有偏差,后果也是记忆静默不生效,而不是把对话弄坏。
明确的设计取舍
- 不调用被默认禁用的 FTS。web profile 里
session-query-sqlite是openAt: never、索引:memory:,全文检索默认关闭。回填走的是listSessions/readSession,这两个不依赖 SQLite 索引,所以不需要改任何 profile 配置。(这一点是我在你机器上 dump 装配清单时发现的:如果有人按"用 sessionQuery 做检索"的思路写,会在运行时撞上SESSION_QUERY_SEARCH_DISABLED。) - 不直接读磁盘上的 session 日志。它们是
session.jsonl.zstd(zstd 压缩),自己解压意味着要额外拥有一个解压器、一套目录 slug 推导和一份格式版本——这三样 harness 都已经拥有并通过sessionQuery暴露了。 sessionQuery是可选注入。必需服务缺失不只是插件不激活,而是整个 harness 拒绝启动(一个 entry 没激活就会 fail the boot)。所以它降级成"memory_backfill报一条清楚的错",而不是让 profile 起不来。
后续可以加的东西
按价值排序:
- LLM 抽取器:在
extract.js旁边加一个可选的模型抽取路径,用于用户明确说"记住这次讨论"的场合。extractCandidates的返回形状已经是为可替换设计的。 - 向量召回:目前第三条腿是关键词 + 图。加一路 embedding 需要模型 provider,但会让同义改写也能命中。
- 记忆的自动冲突检测:已经存了
contradicts这种边类型,但还没有任何东西会自动创建它。两条共享实体、语义相反的decision应该被标出来让 agent 复核。 - 会话结束时的反思轮:目前抽取是"每次模型调用前顺带做",粒度是单条用户消息。在
turn/end之后做一次整轮摘要质量会更高(但需要接 session 事件,而事件是 contained 作用域的,需要单独验证投递语义)。
许可
MIT。
Links
More in this category
vectorize-io/hindsight#coding-agents★ 60916
Hindsight, agent memory that learns: long-term project memory with auto recall and retain, knowledge pages, deep reflection, and per-repo memory banks.
volcengine/OpenViking#examples/dsh-memory-plugin★ 42209
OpenViking memory and context bundle for DeepSeek Harness: pre-step auto-recall and profile injection, session capture, `viking://` URI guarding, and recall/write memory tools backed by an OpenViking server.
MemTensor/MemOS#memos-local-plugin★ 12392
Local-first memory plugin for DeepSeek Harness: layered L1/L2/L3 memory with automatic capture, manual memos_* retrieval tools, and a built-in memory viewer.
agentscope-ai/ReMe#dsh★ 3799
Connects DeepSeek Harness to ReMe's local-first, self-evolving personal knowledge base: automatically captures completed main-agent conversations as user-owned Markdown memory, searches conversations and source material through reme_search with BM25, optional embeddings, and wikilink expansion, and schedules daily memory consolidation.
zilliztech/memsearch#MemSearch★ 2873
Shared Markdown memory for DSH and other coding agents, with automatic capture, pre-step context injection, searchable recall, and memory-to-skill self-evolution through a review panel.
vshulcz/deja-vu#extensions/dsh★ 1544
Cross-session memory and context recovery across forty-five other coding agents (45+) on this machine, reading session files they already wrote before install (Claude Code, Codex, Cursor, Windsurf, Trae, Antigravity, VS Code Copilot Chat, opencode, OpenClaw, Hermes, Kimi, Qoder, Cline, Zed, Magpie and more): six tools (deja_recall, deja_session, deja_blame, deja_fix, deja_how, deja_remember), a /deja command, and optional automatic recall injected into runtime context. Local BM25 CLI/MCP index, no LLM, no embeddings, no network (dsh plugin --profile web add dsh-deja).
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.