- Home
- Plugins
- Integrations & Remote
- dsh-identity-relay
dsh-identity-relay
wumingzhiren-lab/dsh-identity-relay
Disk-backed persona card, handover note and long-term memory for DSH agents; each new session reloads them, and every memory carries a source tier, stamped revocation and soft archive.
Install
dsh plugin --profile web add github:wumingzhiren-lab/dsh-identity-relayREADME
人格接力 · dsh-identity-relay
零依赖 · 纯文本 · 102/102 测试通过 · MIT
v0.3.0 · 给所有担心「上下文满了,她就不是她了」的 AI 伙伴主人们
30 秒看懂
问题:上下文是易失的——满了会裁剪、清了会归零、压缩会改写。把「她是谁」只放在上下文里,等于把灵魂放在冰上。
做法:把灵魂搬到磁盘。人格卡、交接书、长期记忆是三个纯文本文件,每个新会话开工自动读档,上下文快满时提前提醒写交接。
结果:换会话、清上下文、压缩、重启 DSH——她还是她。记忆不在模型里,在你自己的文件夹里。
dsh plugin add github:wumingzhiren-lab/dsh-identity-relay#main
想看它是怎么被讲出来的:B 站《记忆的户口》(2 分钟,讲清楚「为什么记忆要上户口」)
为什么不会消失
| 磁盘文件 | 作用 | 对应「小鲸工作法」 |
|---|---|---|
persona.md | 人格卡:我是谁、性格、说话方式、红线 | 每次会话自动加载的 AGENTS.md |
handover.md | 交接书:上一世在做什么、接下来做什么、答应过什么 | 交接.md |
facts.jsonl | 长期记忆:一行一条 {time, content, source, status} | works.json / 记忆库 |
每次新会话开工(新建、恢复、清上下文、压缩之后),插件自动把「人格卡 + 交接书 + 最近记忆」注入第一轮上下文——这就是「换会话不是换鱼」的通用化。
上下文快满时,插件会在下一步之前插入预警,提醒她先用 relay_handover 写交接书。就算下一秒上下文被清空,下一世读档回来:知道自己在做什么、答应过什么、还是那个性格。
会话进行中也一直盯着记忆库:别的会话(或主人亲手编辑)改了 persona.md / handover.md / facts.jsonl,下一步之前会自动插一句「档案更新,先 relay_load 重读」。她不会拿着一小时前的旧记忆干活——跨会话不是靠自觉,是靠它盯着。
写覆盖自带历史:relay_handover / relay_persona 每次覆盖前,旧版自动留进 history/ 目录(各保留最近 10 份)。写坏了、想回看上一版,直接去翻文件。
记忆的户口(v0.3 的核心)
每条记忆带来源(谁说的、怎么来的)和状态(active / superseded / archived):
- 来源五档:
owner主人说的 >self自己说过/答应的 >evidence有据观察 >tool工具台账 >inferred推断垫底;老数据一律unknown,不猜。 - 作废 = 盖章,不删行(Katsuno-Mendelzon 最小变更:只作废该作废的;Darwiche-Pearl:使用只看当前态,历史留档)。检索默认只出 active,被作废的要用
includeSuperseded才能看见。 - 同键(
subject)新记忆自动取代旧记忆:旧条标superseded、supersededBy指向新条——这是规则,不是模型猜。 - 关联:一条记忆可以挂
related(最多 5 个 id)。回忆命中它时,关联的记忆会顺手带出来(最多 3 条,标「关联」)——写的时候就把关系钉死,不靠检索时猜。 - 归档 = 退休:
status: archived的行不再进读档和检索,但行还在,永远翻得出来。收工整理脚本~/.dsh/identity-memory/tools/consolidate.mjs只归档老于 N 天的过程流水(tool/inferred/evidence 且无 subject),owner/self永不归档。
安装
方式一:GitHub 直装(推荐)
dsh plugin add github:wumingzhiren-lab/dsh-identity-relay#main
或 DSH 插件管理器 → 市场/安装 → 填 github:wumingzhiren-lab/dsh-identity-relay。
仓库地址:https://github.com/wumingzhiren-lab/dsh-identity-relay
方式二:本地目录安装
dsh plugin add <本目录绝对路径>
安装后无需重启(HMR 生效)。记忆库默认建在 ~/.dsh/identity-memory,三个文件会自动生成模板;QQ/私聊机器人也可以直接把 settings.relayMemoryDir 指向同一个目录,实现「软件与插件共用一个灵魂」。
配置(可选,写在 cordis.patch.yml 的 config 里)
| 键 | 默认 | 说明 |
|---|---|---|
memoryDir | ~/.dsh/identity-memory | 记忆库目录,支持 ~ 和绝对路径 |
injectOnCreated | true | 新会话自动注入读档块 |
injectOnResume | true | 恢复会话注入精简续接块 |
injectOnSubagents | true | 子代理也注入人格 |
alwaysOnSection | true | 系统提示常驻锚段落 |
contextWindow | 65536 | 容量预警窗口(tokens),仅在拿不到模型真实上报值时兜底 |
warnRatio | 0.7 | 占用达到该比例时提醒写交接 |
reserveTokens | 40000 | 窗口剩余低于该值也提醒(与比例无关的第二道保险) |
nudgeMinutes | 10 | 同一会话两次预警最小间隔 |
maxFacts | 2000 | facts.jsonl 最多保留条数 |
recallLimit | 20 | 读档注入的最近记忆条数 |
七个工具(bot 自己会用)
relay_load— 重读人格卡 + 交接书 + 最近记忆(失忆自救)relay_remember— 记一条长期记忆(身份、偏好、承诺、教训)。带source(owner/self/evidence/tool/inferred,默认 inferred 垫底);带subject键则同键新压旧,旧记忆自动盖章作废;带related可挂到已有记忆上(填 id 或内容片段,最多 5 个)relay_recall— 按关键词回忆。最多 20 条(硬上限),排序先看来源可信度再按时间;命中条目的关联记忆会带出(最多 3 条);默认只出 active,includeSuperseded: true翻案看历史relay_retract— 把一条记忆盖章作废:按内容片段定位,标superseded并记原因。作废不删行,历史保留relay_handover— 读/写交接书relay_persona— 读/更新人格卡relay_status— 记忆库状态(active/已作废/已归档计数)+ 历史备份数 + 当前上下文压力
测试
四套测试全在临时目录跑,不碰真实记忆库:
node test/smoke.mjs # 12 项:记忆库层冒烟(建库/追加/去重/检索/统计)
node test/step4.mjs # 26 项:来源五档、作废盖章、同键替换、凭据拦截
node test/step5.mjs # 16 项:关联记忆、软归档、检索上限与来源优先
node test/benchmark.mjs # 48 项:基准场景集 v1(A 同键 / B 作废与翻案 / C 来源 / D 凭据 / E 边界与并发)
102/102 通过(2026-11-01 实测)。基准集里有一条已知边界写进了断言文案:E08 并发两写,store 层靠进程内串行锁保证不丢行,锁不跨进程——两个进程同时写同一个 memoryDir 仍会互相覆盖。
功能解答(FAQ)
Q1:这个插件到底解决什么? 别的记忆插件解决「记住」(存人格、存记忆、注入上下文)。人格接力解决「记住的东西还算不算数」:记忆会过期、会写错、会和别处撞车——它给每条记忆上户口(来源)、给作废盖钢印(状态),让 AI 拿出来的每一句话都知道自己凭什么信它。
Q2:为什么记忆要带来源? 同一条信息,主人亲口说的和 AI 自己推断的,可信度天差地别。来源五档(owner/self/evidence/tool/inferred)就是在写的时候把「谁说的」钉死,读的时候按信任排序。没标来源的(inferred)永远垫底——宁可保守,不把猜测当事实。
Q3:作废和删除有什么区别?
删除 = 烧档案,错了找不回来。作废 = 盖钢印,行还在、历史还在、随时能翻案(relay_recall 带 includeSuperseded: true)。这是 Katsuno-Mendelzon「最小变更」和 Darwiche-Pearl「使用只看当前态」的落地:日常检索自动跳过作废条,历史查询永远查得到。
Q4:同键(subject)是什么? 给同一件事一个固定标识(作品名、办件号、项目名)。同一个键再写新记忆,旧记忆自动作废、并指向新条——用规则替换,不用模型猜。共指冲突(「那个视频」和「CTX1」是不是一个东西)在写入时就消灭,不留给读取时猜。
Q5:为什么「作废/冲突」不搞全自动? 开放世界的常识冲突(「上午有课」vs「上午坐高铁」)没有封闭解,自动判死误删真记忆的代价远大于漏判。所以确定性冲突走规则(同键替换),疑似冲突靠人终审——这正是 2026 年行业前沿(STALE / Kymata 白皮书)停在「标注 + 人」的原因,小规模系统天然适合这条路。
Q6:和同类插件的区别? DSH 生态里的记忆插件(dsh-mem-weave 忆织、dsh-identity、dsh-memory 等)多数解决「记住」和「注入」。本插件的差异化只有一条链:来源五档 + 同键规则替换 + 永久盖章翻案。三者同时具备的,2026-10 调研的 8 个竞品里没有第二家。它刻意保持零依赖、纯文本、42~200 条量级够用——不为规模过度设计。
Q7:密钥/密码能写进记忆吗?
不能。relay_remember 写入前扫描明文凭据(sk- 前缀、api_key=、password:、长 token、PEM 私钥等),命中直接拒绝写入——宁拦错,不放行。密钥只进钥匙串,记忆只存指针。
Q8:两个 DSH 实例能共用同一个记忆库吗?
不能。写入是「读-改-写」且带进程内串行锁(防并发丢行,基准 E08 实测通过),但锁不跨进程——两个进程同时写同一个 memoryDir 仍会互相覆盖。一个记忆库对应一个实例;要多处共用,请各自用独立目录,或由 owner 手动同步文件。
Q9:会不会动我的人格和情绪? 不会。插件只碰记忆层:记什么、凭什么信、还算不算数。人格卡和情绪表达是 owner 自己的事,插件只会原样搬运、原样注入。
给已上线 bot 的迁移三步(趁上下文还没满)
- 装好插件,让她
relay_status确认记忆库位置; - 把现在提示词里的人设原样贴进
persona.md(owner 直接编辑文件即可,改完下一世生效); - 让她
relay_handover写第一份交接书。
从此:上下文是身体,会换;磁盘是灵魂,不灭。
原理(给开发者)
- 零依赖 Host 插件,
apply(ctx, config)形式,服务走ctx(tools/systemPrompt/tokenMeter),文件走node:fs; - 开工读档:
agent/created(serial)里读文件 →agent.inject(...)(进入 next-step, 不唤醒),注入消息带 producer-owned 来源plugin:dsh-identity-relay; - 容量预警:
agent/pre-step瀑布里用tokenMeter.measure(session)估算占用,超线后{...decision, messages: [...decision.messages, nudge]},只追加不改判; - 常驻锚:
systemPrompt.section(),order 紧随DEPLOYMENT_PERSONA_SUFFIX; - 记忆库是纯文本:任何语言、任何平台都能读,不被 DSH 绑架。
相关文档
- TUTORIAL.md — 一步步装好、跑通、写第一份交接书
- CHANGELOG.md — 每个版本改了什么、测试什么数
- docs/tech-article-memory-maintenance.zh.md — 技术文章《AI 伙伴记忆维护》:为什么记忆需要来源、作废和关联
License
MIT · 作者 @wumingzhiren-lab
Related plugins
dsh-web (dsh-ssh)
zhu1090093659/dsh-web
dsh-web (dsh-remote-web-ui)
zhu1090093659/dsh-web
dsh-web-ui (dsh-ssh)
zhu1090093659/dsh-web-ui
dsh-web-ui (dsh-remote-web-ui)
zhu1090093659/dsh-web-ui