为角色补上跨会话的档案、召回与情感状态
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add KikaiLastest/dsh-memory-core该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · search
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 4 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
发起外部网络请求
查看扫描证据(共 2 处,展示前 2 条)
- 发起网络请求client.js:24
fetch(BASE + '/config', { cache: 'no-store' }) - 发起网络请求client.js:28
fetch(BASE + '/config/save', {
扫描于 2026/11/2(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
DSH 本地记忆插件:BM25-lite 历史召回 + 记忆使用协议 + 结构化固化 + 情感状态。全部落本地 Markdown/JSONL,无数据库、无云端。
README
由 DeepSeek 最新模型翻译生成dsh-memory-core
给 DeepSeek Harness(DSH) 里的持久化 AI 角色加一层记忆与状态:常驻记忆协议、按需历史召回、结构化记忆固化、两标量情感状态。
面向的场景很简单:模型每次重启都是同一份权重,跨会话的「记性」只能靠外部文件。这个插件把那份档案变成能找回来、能追溯、且不会压过人设的一层。
为什么做这个
更新更新着烂掉了, 放弃维护了
大模型像一块孤立的前额叶:工作记忆短、无状态、换个会话就忘。这个项目按仿生学思路给它补了海马体(档案 + 召回 + 固化)和一点点杏仁核(情感状态)。
但它不承诺意识。用中文房间的话说,我们只是给房间加了一个档案柜——回答更连贯了,符号仍然没有接地。所以这里的定位是弱人格同一性:不承诺内在体验,只保证行为上的连续、可追溯、一致。
组成
| 层 | 干什么 |
| P0a 记忆使用协议 | 用 systemPrompt.section 注入 5 条规则:历史参考不是本轮发言、可能过期、要能追溯、以新事实为准、不许编造。刻意不重复 AGENTS.md 的人格段,避免权威倒置。
展开完整文档(README 剩余 1 节)
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 | 数字 | 3 | 1–10 | 每次注入几条 | | timeoutMs | 数字 | 150 | 50–1000 | 召回超时(毫秒) | | minCoverage | 数字 | 0.2 | 0–1 | 查询 2-gram 覆盖率下限(0 = 不设门槛) | | minMatched | 数字 | 2 | 1–5 | 最少命中片段数 | | halfLifeDays | 数字 | 30 | 1–365 | 权重半衰期(天) | | dailyQuota | 数字 | 10 | 0–100 | 自动捕获每日配额(0 = 不写) | | enableStable | 开关 | 开 | — | 是否注入常驻「记忆使用协议」 | | enableAutoCapture | 开关 | 开 | — | 是否开启自动捕获 | | enableMemoryNav | 开关 | 开 | — | 是否注入常驻「记忆导航」(无记忆时不注入) | | summaryMaxChars | 数字 | 600 | 80–2000 | 导航总长度上限(字),超出按新鲜度截断 | | enableSummary | 开关 | 开 | — | 是否跑后台摘要 | | summarizeIntervalMinutes | 数字 | 10 | 1–1440 | 后台检查间隔(分钟) | | summarizeIdleMinutes | 数字 | 30 | 1–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
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
KikaiLastest/dsh-memory-core
为角色补上跨会话的档案、召回与情感状态
相关插件 · 搜索 / 抓取
LLM 知识平台Tencent/WeKnora
概览 ·快速开始 ·新特性 ·功能 ·客户端 ·文档 ·开发
★ 36,161已汉化DSH
72.1
智能体记忆系统MemTensor/MemOS
MemOS 2.0 Stardust星尘
★ 12,195已汉化DSH
71.2
跨代理记忆库zilliztech/memsearch
跨平台语义记忆,专为 AI 编程智能体打造。
★ 2,799已汉化DSH
70.9
技能语料库EverMind-AI/SkillCorpus
SkillCorpus 能给你什么
★ 694已汉化DSH
69.7
代码图谱记忆syncable-dev/memtrace-public
你的智能体值得拥有结构化记忆。
★ 509已汉化MCP
67.9
AnySearch 搜索插件anysearch-team/anysearch-dsh
AnySearch 网页搜索服务商,为 DeepSeek Harness(DSH)提供高级搜索工具
★ 457已汉化DSH
66.6