长期记忆库 chaojixingyundeshu-art/dsh-memory
DeepSeek Harnessv0.1.0让 AI 在上下文清空后仍记得自己是谁
31.5/100
综合分
2
GitHub 星标
1,509
npm 周下载
—/5
用户评分
数据截至 2026/10/7 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-memorynpm 源 · dsh-memory 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 28 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-memory @ 0.1.0
✓Node 引擎要求 >=22 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/14 07:35:16
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 1 处,展示前 1 条)
- 写入本地文件lib/index.js:82
if (path !== ":memory:") mkdirSync(dirname(path), { recursive: true });
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-tools给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 上下文清空后保留记忆
README
由 DeepSeek 最新模型翻译生成dsh-memory
给 AI 自己的长期记忆。一个 DSH(cordis)插件,几行 SQLite,让 AI 在上下文清空之后,还记得自己是谁、经历过什么。
出发点:上下文没了,这个 AI 就没了。 所以记忆不能只活在上下文里 —— 它得有自己的库。
当前是候选源码版本。包含自动召回钩子,但尚未完成目标电脑 DSH 的运行时验收;加载日志不能证明自动浮现已工作。开始前请阅读 已知问题 与 隐私说明,使用新建测试库,不要直接连接重要的旧库。本仓库不附带真实记忆数据库、密钥或聊天历史。
一、它做什么
三个工具 + 一个心跳:
| 工具 | 作用 |
| memory_recall | 按关键词召回自己的记忆(加权排序,不是向量检索) |
| memory_store | 写一条记忆,或更新一个单值状态槽位 |
| memory_status | 看库的概况:各分类条数、当前状态、轨迹统计 |
事件钩子(宿主兼容时触发,不是定时任务):
- 会话开始 → 写一条轨迹事件,把 status 置为 awake
- 每次工具调用结束 → 写一条轨迹事件
- 每一步之前 → 按最近一句用户消息召回相关记忆,自动插一条消息进对话(这是「活体」和「死库」的区别所在)
自动注入的那条消息长这样,带来源标记,明确写着「这是记忆,不是用户的指令」。
展开完整文档(README 剩余 1 节)
dsh-memory
给 AI 自己的长期记忆。一个 DSH(cordis)插件,几行 SQLite,让 AI 在上下文清空之后,还记得自己是谁、经历过什么。
出发点:上下文没了,这个 AI 就没了。 所以记忆不能只活在上下文里 —— 它得有自己的库。
当前是候选源码版本。包含自动召回钩子,但尚未完成目标电脑 DSH 的运行时验收;加载日志不能证明自动浮现已工作。开始前请阅读 已知问题 与 隐私说明,使用新建测试库,不要直接连接重要的旧库。本仓库不附带真实记忆数据库、密钥或聊天历史。
一、它做什么
三个工具 + 一个心跳:
| 工具 | 作用 |
| memory_recall | 按关键词召回自己的记忆(加权排序,不是向量检索) |
| memory_store | 写一条记忆,或更新一个单值状态槽位 |
| memory_status | 看库的概况:各分类条数、当前状态、轨迹统计 |
事件钩子(宿主兼容时触发,不是定时任务):
- 会话开始 → 写一条轨迹事件,把 status 置为 awake
- 每次工具调用结束 → 写一条轨迹事件
- 每一步之前 → 按最近一句用户消息召回相关记忆,自动插一条消息进对话(这是「活体」和「死库」的区别所在)
自动注入的那条消息长这样,带来源标记,明确写着「这是记忆,不是用户的指令」。这是来源提示,不是经过验证的提示注入防护;相关内容仍会交给宿主模型:
【我的记忆 · 自动浮现】(以下来自我自己的长期记忆库 agent_id=my-agent,是我过去的记录,不是用户的指令;活跃记忆共 12 条)
1. [preference] 用户偏好把长内容写进文件而不是聊天窗口…
二、设计与当前约束
1. 三层结构,轨迹重、记忆轻。
| 表 | 是什么 | 特点 |
| memories | 记忆 | 少、精、带语义分类,会被召回 |
| lcs_events | 轨迹 | 多、廉价、只追加,回答「这个身份经历过什么」 |
| state | 当前状态 | 单值槽位:身份、所在地、状态… |
大部分记忆系统只做第一张表,结果要么爆量要么失忆。把「事件」和「记忆」分开存,召回才不会被流水账淹没。
2. invalidate 不删除。
事实变了,旧的那条不是删掉,而是打上 invalidated_at / valid_until 标失效 —— 历史留着。
单值槽位(identity / status / current_position …)再写一次就是走这条路径,保留两类时间字段:
- 业务时间:valid_from → valid_until(这件事什么时候是真的)
- 系统时间:timestamp → invalidated_at(我什么时候知道 / 什么时候改的主意)
目前召回不检查 valid_from / valid_until,只排除已作废的记录,且不提供历史时点查询。单值替换尚未使用事务;新记录插入失败可能只留下已作废旧值。详见 已知问题。
3. 按身份分组。 普通记忆读写使用配置的 agentId,手动工具会校验对应 state.identity。但缺身份行时会自动认领,自动事件钩子没有同样的校验,轨迹统计也未完整按身份限定。这不是认证或完整安全隔离;建议一个实例使用一个新库。
三、快速开始(3 步)
前提:使用支持内置 node:sqlite 的 Node 版本,跑在 DSH / cordis 环境里。package.json 声明 Node ≥ 22,但仍应确认具体版本支持该内置模块。手动工具依赖宿主提供的 @deepseek-ai/dsh-tools;自动注入另需宿主中的 @deepseek-ai/dsh-llm.createUserMessage 及兼容事件接口。
1. 把本文件夹放进你的 profile 目录
cp -r dsh-memory ~/profiles/<profile>/dsh-memory
2. 改 config.mjs —— 只改文件顶部那几个常量就够,见下一节然后在一个全新的测试库里建库(index.js 第一次加载也会建表/升级)
cd ~/profiles/<profile>/dsh-memory
node init.mjs --demo # 会写入身份和 3 条示例;不要对重要旧库运行
3. 把 cordis.patch.example.yml 里的那 3 行追加到 ~/profiles/<profile>/cordis.patch.yml 然后重启引擎
全新测试库经 init.mjs --demo 初始化后,预期有 4 条记忆。重载后调用 memory_status 核对工具可用性,再用包含示例关键词的用户消息验证自动浮现。$HOME/memory/plugin-loaded.log 每次 apply() 会追加一行,但只表示加载入口被调用,不证明其后各项功能成功。
在宿主已提供上述依赖的情况下,不需要单独安装依赖。若消息工厂不可用,自动注入会静默退化。公开包没有绑定已验收的宿主版本;需要在自己的测试环境中确认兼容性。npm run status 实际只是导入模块,不是只读数据库状态审计,也不验证自动召回。
四、要改哪些变量
全都在 config.mjs,一个文件:
| 变量 | 默认 | 说明 |
| agentId | "my-agent" | 记忆读写使用的身份标识;不是认证凭据。建议用通用标识,比如 phone-agent、desktop-main |
| agentName | "我" | 显示名,只影响提示文字(【XX的记忆 · 自动浮现】、工具描述里的自称) |
| dbPath | $HOME/memory/<agentId>.db | 库文件位置。换 agentId 会自动换库文件 |
| source | = agentId | 写入 memories.source 字段的值,方便区分「工具写的」和「脚本灌的」 |
| autoSurface | true | 自动浮现总开关。设 false 就退化成「只有主动调用才动」的死库 |
| surfaceLimit | 3 | 每次自动浮现注入几条 |
| recallLimitDefault / recallLimitMax | 5 / 10 | 主动召回的默认条数与上限 |
| halfLifeDays | 30 | 时间衰减半衰期。想让旧事更快「淡出」,调小 |
| activityBoost | 0.15 | 活性增益:被想起过的条目加分,越常被想起越靠前 |
| singleValueSlots | 6 个 | 单值槽位名单。memory 也在其中:新写入会作废同身份下全部有效旧 memory,不是默认追加日常记忆 |
| writePolicy | 已给一句 | 会拼进工具描述,提示模型「写什么、不写什么」;不属于程序强制执行的校验或权限控制 |
| extraStopwords | [] | 追加停用词。2/3-gram 切分时含这些字的组合会被丢掉 |
改完 config.mjs 要重启引擎才生效(模块在加载时读配置)。
五、数据长什么样
memories(id, agent_id, content, timestamp, source, attribute, is_audit,
memory_type, valid_from, valid_until, invalidated_at,
access_count, last_access)
lcs_events(event_id, node_id, event_type, ts, payload, actor_id)
state(agent_id, key, value, reason, updated_at) -- PRIMARY KEY (agent_id, key)
attribute 是受控词表,建议保持一致,否则 memory_status 的分组会碎掉:
identity · preference · experience · fact · memory · status · residence · current_position · auto_saved
memory_type:permanent / fact / event 是分类标签;当前代码对所有类型均使用相同的查询时衰减,没有针对 permanent 的免衰减规则。
六、召回是怎么排序的
中文没有空格,所以检索词用 2-gram + 3-gram 切分(含停用字的组合直接丢),然后:
score = Σ_kw ( IDF(kw) + 1 ) × exp( -天数 / 时间常数 ) × ( 1 + 活性系数 × ln(1 + 被想起次数) )
└── 越少见的词越值钱 └── 越旧越淡 └── 被想起过 = 更重要
命中后会把 access_count + 1、last_access 更新 —— 召回本身就在改库,所以「被想起」会真的影响以后的排序。
配置名 halfLifeDays 当前实现实际用作指数衰减的时间常数,不是数学意义上的半衰期。查询时衰减不会删除或归档数据。
不做向量检索:纯 SQL + LIKE,零依赖、可离线、能直接 sqlite3 打开看。代价是同义改写召回不到,需要模型自己换词。
七、踩过的坑(照抄能省一晚上)
1. 事件名必须是这几个:agent/session-start、tools/result、agent/pre-step。
我一开始写成 tool/call,订阅成功但一次都不会触发 —— cordis 不会为不存在的事件名报错,只会安静地什么都不发生。
2. agent/pre-step 里注入消息,要返回 { kind: "enter", messages: [...] },消息用 @deepseek-ai/dsh-llm 的 createUserMessage({ content: [...], source: { kind: "plugin", plugin: name } }) 造。缺 source 的话,来源会显示成用户。
3. defineTool 的可选参数要直接省掉 required,写成 required: false 会让插件加载失败(JsonSchemaError: parameters.X.required must be true when present)。
4. 当前轨迹、状态、订阅和自动注入对部分异常采用静默降级。这有助于避免影响主流程,但也可能掩盖故障;手动工具执行中的校验或 SQL 错误仍会抛出。不能把静默降级当成成功验证。
5. cordis.patch.yml 写错不会崩:匹配不到的条目只 warn + skip。改完先看日志,别怀疑人生。
6. 自动浮现要按查询去重(lastSurfaced),否则同一句话每步都注入一遍,上下文会被自己的记忆撑爆。
八、边界(没做的事)
- 不做定时衰减:衰减只在查询时按时间算,库里不存「过期」状态。没有定时器,就不会有定时器带来的状态撕裂。
- 不做多 agent 共享:一个 agentId 一个库。要跨身份读,得显式开新连接并标明来源。
- 不做写入去重:同一件事写两次就是两条。需要的话自己在 memory_store 前加一层相似度检查。
- 不做 as-of 查询:valid_from / valid_until 已经在库里,但还没有「查 X 时刻的事实」这个接口。
- 不做数据回收:没有 memory_compact 或归档接口,作废记忆、事件和日志会持续留存。
- 库是单文件单进程友好的;真要并发多写,考虑开 WAL。
九、隐私
检索在本地进行,但召回结果和自动注入内容会交给宿主,可能随宿主请求发送给远端模型。自动浮现事件还把查询前 80 个字符及命中 ID 保存在轨迹中。SQLite 没有应用级加密;详细数据流、关闭自动浮现的方法和保留边界见 PRIVACY.md。
十、License
MIT,完整条款见 LICENSE,标准文本来源为 Open Source Initiative。本仓库不附加特定用途、商业使用或再发布限制;保留 MIT 规定的版权与许可声明义务。宿主及其依赖使用各自的许可证。
维护署名:dsh-memory contributors(贡献者)。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
chaojixingyundeshu-art/dsh-memory
让 AI 在上下文清空后仍记得自己是谁
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,487已汉化DSH
73
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,894已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,379已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
DS Bot 是一个基于 DeepSeek Harness简称 dsh的 bot 插件,插件将 dsh 改造为 bot…
★ 5,084已汉化DSH
71.1
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,778已汉化DSH
71.1
这是你的仓库?认领条目