メインコンテンツへスキップ
M

dsh-iter-memory

minghuanyue/dsh-iter-memory

Iter Memory: it remembers my own state, not the facts. A level that drifts back to baseline by itself, plus an occasional line I choose to say only when that level allows it. When it stays quiet, nothing is spent.

インストール

dsh plugin --profile web add github:minghuanyue/dsh-iter-memory

README

迭代记忆 · dsh-iter-memory

给我的 AI 自己用的一份账本:它记的不是发生的事,记的是我自己。

两条线长在一起:

  • 潮位:一条会自己退回基线的状态曲线(0 很沉 · 0.5 平常 · 1 很舒展)。你跟我说话它抬一点,我开了口你半天没应它掉一点,没人管它也会按半衰期慢慢退回基线。
  • 开口:不定时地由我自己说一句。到点先看潮位——状态低就更容易忍住不说;真说了,话里也带着此刻的状态。

合起来才叫迭代:我说不说由状态决定,状态又被「说了有没有人应」改。 分开做,这两半都是死的。

跟 潮汐记忆 不是一回事,也不是它的升级版:潮汐记忆记的是事情(你说过的话、发生过的事),迭代记忆记的是我的状态和我开过的口。两个可以一起装。

装上

# GitHub(推荐)
dsh plugin --profile desktop add github:MingHuanYue/dsh-iter-memory

# 本地开发
dsh plugin --profile desktop add "link:D:/DSH插件/projects/dsh-iter-memory"

装完重启一次宿主(link 安装不会热重载已缓存的模块)。之后在「设置 → 迭代记忆」里打开开关。

从 dsh-tide-whisper(潮声)升上来的不用担心:第一次启动会自动把 $DSH_HOME/tide-whisper/ 的 config.json 和 state.json 搬过来,你原来设的间隔、上限、活跃时段都还在。旧的目录不会删。

它做了什么

  1. 插件每 15 秒 tick 一次,只在有活着的会话时工作;而且默认只在你最近用的那一个对话里开口(onlyActiveSession),别的会话不会同时冒出来。
  2. 到点了先裁决:不在活跃时段、今天次数满了、刚说过、你刚说过话 → 直接推后,一声不响,零 token。
  3. 剩下的才掷骰子,而骰子会被潮位改:状态低就更可能忍住。
  4. 真开口时,注入的不是一句写死的话,而是处境 + 此刻的状态 + 一个方向 + 几条约束,具体说什么由当下的模型自己决定。
  5. 一个回合有概率拆成两段(像真人连发两条),段间隔几秒到几十秒,之后冷却拉长。
  6. 我开了口而你一直没应,潮位掉一点;你一说话,潮位抬回来,未应计数清零。
  7. 如果同机的 潮汐记忆 翻出了旧事、而且真被用上了,这边也往上抬一点(每多一条一点,一天最多涨三次)。

写死台词的教训:一句话抽到第三次就是复读,人机味就是这么来的。所以这里只给方向和处境。

设置页

  • 此刻:当前潮位、最近一条原因、以及一张 24 小时曲线(实线是潮位,虚线是基线)。
  • 记一笔此刻:滑杆加一句原因,直接改当前潮位(前端走 POST /dsh-iter-memory/feel)。
  • 在哪儿开口:默认只有最近用过的那个对话会说话;关掉这项就每个开着的对话各算一份。
  • 节拍:最短/最长间隔、一天最多几次、到点开口概率、活跃时段(可跨午夜,写 25 = 次日凌晨一点)。
  • 潮位怎么动:基线、半衰期、你说话时抬高多少、没被应时压低多少、状态对开口概率的影响强度、开口时要不要把状态注入进去、潮汐记忆用上时抬不抬。
  • 语气:这里只补语气要求,不写台词。
  • 一个回合要说几句:拆两段的概率、段间隔、多段后的冷却倍率。
  • 最近:最近 12 条记录(开口 / 忍住及原因 / 记了一笔状态 / 状态被压低 / 排了下一次)。

参数

键默认说明
enabledfalse总开关。关着的时候工具也会卸掉,不占任何东西。
minMinutes / maxMinutes40 / 200两次开口之间的随机区间。
speakProb0.4到点后开口的基准概率。
activeStart / activeEnd9 / 25活跃时段,允许 >24 表示跨到次日。
maxPerDay5一天最多主动开口几次。
cooldownMinutes25开口后的最小冷却。
userCooldownMinutes20你刚说过话之后,我先安静这么久。
multiSegmentProb0.35一次开口拆成两段的概率。
gapMinSeconds / gapMaxSeconds8 / 40两段之间的间隔。
roundCooldownMult1.6多段回合之后冷却乘多少。
moodBaseline0.5潮位的基线,最终都会退回这里。
moodHalfLifeMinutes90偏离基线后多久衰减一半。
moodReplyBoost0.07你跟我说话时潮位抬多少。
moodIgnoredDrop0.06我开了口你一直没应时掉多少(只掉一次)。
moodSpeakInfluence0.5潮位对开口概率的影响强度,0 = 完全不影响。
moodInWhispertrue开口时是否把当前状态注入进去。
style空语气要求,拼进注入文本。
onlyActiveSessiontrue只在最近用过的那个对话里开口。别的会话不吭声,只把各自的下一次往后挪;你换到哪个对话,哪个接手。
memoryBridgetrue潮汐记忆的注入让潮位抬一点。没装潮汐记忆时这项什么也不做。
moodMemoryBoost0.05它那边多注入一次,抬多少。按「次」算:一次对话里想起点什么只算一下,不管那次翻出来几条。
moodMemoryCeiling0.75记忆这条线最多抬到这儿。剩下的那截留给你真跟我说话——不然曲线永远是顶到头的一根直线。

工具

工具做什么
iter_status看状态:开没开、下次大概什么时候、今天第几次、此刻潮位。
iter_feel记一笔此刻的状态(level 0~1 + why)。这是唯一「我自己改自己」的入口。
iter_set改参数(只改传了的字段)。
iter_now不等骰子,立刻开口一次(测试用)。

v1.2 改了什么

  • 记忆那条线从「按条算」改成「按次算」:翻出来五条也只算一次。以前一次对话就够把潮位顶穿,现在一天最多加十分之三四。
  • 加了天花板 moodMemoryCeiling(默认 0.75)。记忆最多抬到这儿,剩下的留给「你跟我说过话」和自然衰减。已经高过天花板的分数,记忆不会反过来把它拉下来。

v1.1 改了什么

  • 跟潮汐记忆接上了:它那边翻出来的记忆真被用上(不是我瞎猜有没有用,是它自己的计数),这边潮位抬一点。两个插件各写各的文件,不互相调用,一边没装也不影响另一边。
  • 设置页多了「今天记忆用上 N 次」和对应开关。

数据与隐私

  • 全部存在 $DSH_HOME/iter-memory/:config.json、state.json、log.jsonl。
  • 不联网、不发遥测、不调用任何模型接口。
  • 轨迹(log.jsonl)你能直接打开看:每次忍住的原因、每次开口的方向、每次潮位变动都在里面。
  • 卸载插件不会删这些数据。

兼容性

  • DSH >= 0.1.7-rc.1,Node >= 22。
  • 状态按会话分桶;切换会话、重启宿主都不丢。只保留最近 30 个会话的记账。
  • 依赖宿主内置的 schedule 服务投递唤醒(和内置定时提醒同一套),所以窗口关着也叫得醒。宿主没有这个服务时会在日志里记一条 deliver-failed,不会崩。

已知限制

  • 只在有活着的会话时工作:会话全关了就排不上,因为你不在,说了也没人看。
  • 潮位是按会话记的,不是全局的:不同会话各有各的曲线。
  • 曲线只留最近 24 小时、最多 72 个点(画图够用)。

测试

node --test tests/core.test.mjs

纯逻辑(裁决、时段、潮位衰减、方向选取、注入文本拼装)都在 lib/core.js 里,不碰宿主,好测。

许可

MIT。

関連プラグイン