dsh-selfnote
让模型自己写「自述」,跨会话带着走。不是记用户的事,是记它自己的。
主体约定:自述里的第一人称「我」= agent 自己;「记忆条目」与「事实」的主语是用户。两者分开存、分开注入。
它做什么
- 写:模型通过
self_note工具追加一条自述(第一人称,一句话到三句话) - 存:
~/.dsh/selfnote/notes.md,纯文本一行一条,随时能打开看、能 grep - 读:每回合把生效的那段注入系统提示,排在人格段之后
- 有上限:默认 1600 字 / 40 条,写满后最旧的条目自动进
archive/YYYY-MM.md(只追加,不删除)
热度(遗忘曲线)
记忆会淡,但不会消失。三条轴分开走:
| 轴 | 会不会变 | 说明 |
|---|---|---|
| 可信度 | 不变 | 只有人能改(采纳 / 退役) |
| 热度 | 随时间和使用衰减 | (1 + ln(1+命中次数)) × 0.5^(闲置天数/半衰期) × (1 + 0.5×重要度) |
| 重要度 | 人工给 | 默认 1,0–3 |
- 只有真的进了注入才算一次使用;检索命中没进上下文的不记(否则搜到一次就永远活跃)。
- 一小时内重复注入只记一次。
- 半衰期默认 30 天,可在设置页调 1–365。
- 冷下去只影响注入排序,不会自动退役;哪天真想起来,它还在库里能被搜到。
装
plugin_manager { action: "install_bundle", target: "<这个目录的绝对路径>" }
或者对 agent 说:帮我装一个 DSH 插件,目录是 <绝对路径>。
装完重启 DSH,模型就多三个工具:self_note(写自述)、memory_recall(翻历史原文)、memory_stage(把查到的一句连着出处放进候选区)。
记忆
memory_recall:按关键词翻我和你的历史对话原文,回来带出处。
- 原料是 DSH 自己写的会话记录
~/.dsh/sessions/*/session-*.v4.jsonl.zstd,不重复落盘 - 解压结果缓存在
~/.dsh/memory/cache/,按会话修改时间失效,最多 60 个 - 只收正文:
reasoning、工具调用、以及source.kind不是user的注入内容(mnemon 快照等)全部剔除 - 每条结果带
会话 id / 日期 / 第几条,可以按行号回原文核对 - 多个词全部命中优先;一条都没有时才放宽成「任一命中」,并标注 relaxed
- 排序先分层再比分数:他本人说的 > 我说的 > 委派提示。子代理会话里的
user/message是委派方写的任务书,记成delegated,不按原话计权
memory_stage:从原文里读到一句值得记的话,连出处一起放进候选区。
- 没有出处直接拒绝(会话 id + 行号要能落到真实的一轮上),所以编不了
- 写进去只是候选,还要你在设置页点「采纳」才生效
- 已采纳的可以「退役」:条目留着备案,不再注入、不再检索
索引(可选)
启用后 memory_recall 先查倒排表,再只读命中的那几个会话:
- 索引只存词元与位置,不存正文(
~/.dsh/memory/index.json,261 个会话约 8 MB) - 中文按 bigram、英文按单词切;AND 优先,全空才退回并集并标 relaxed
- 最近 5 分钟内还在写的会话算 hot,不参与「过期」判定,结果里会注明「索引不含最近 5 分钟内的 N 个会话」
- 过期(有冷会话没进索引)时拒绝启用,先重建;重建 261 个会话约 7 秒
- 查询没命中会退回线性扫描,不会因为索引没覆盖就说「没有」
- 把正文片段也塞进索引能把查询压到 100 ms 内,但体积涨 2–3 倍 —— 明确不做
画像(关于你)
不是新的事实库,是已采纳记忆的聚合视图:
- 只读
approved;candidate/retired不参与 - 不产生新事实:画像里每一句都能回指到某条
fact.id(设置页列出来源) - 同一标签有多条时不擅自归纳,只取最新的一条,另标「另有 N 条未合并」
- 可手改、可关闭;手改优先,且不会叠加自动结果
- 可重建:facts 一变,画像就重算,画像本身从不落盘、也不反过来当事实来源
注入预算
每回合注入四段,合计 300 字:
| 段 | 上限 | 来源 |
|---|---|---|
| 自述 | 120 字 | notes.md |
| 画像 | 60 字 | 已采纳 facts 按标签聚合(可手改,最多 120) |
| 常驻结论 | 80 字 | 已采纳的 facts |
| 习惯 | 40 字 | 升成习惯的条目 |
超了按新近度截断;设置页显示本回合实际注入了多少、各段占多少。注入文本按「三份文件的 mtime + 配置」缓存,没变就不重算 —— 这既省算力,也让系统提示词前缀稳定、能吃到缓存。
习惯怎么来
不是模型总结出来的,是统计出来的:同一个标签在已采纳的事实里出现 ≥3 次,设置页才提示「可以升成习惯」,升不升你点。模型没有这个开关。
设置页
装好重启后,DSH 设置里会多一节「自我叙述」(在「知识库」下面):
- 三个数字:条数 / 字数 / 容量占用
- 一个开关:每回合注入(关掉后内容还在,只是不进上下文)
- 两个上限:字数、条数,改完下一回合生效
- 一个输入框:你自己也可以替它写一条
- 清空:内容全部进
archive/,不会丢 - 折叠区「文件在哪」:内容、归档、配置三个绝对路径
配置存在 ~/.dsh/selfnote/config.json,和 notes.md 放在一起。
和人格插件的区别
dsh-agent-md 管的是「设定」——你写给它的人设,它照着演。
这个管的是「自述」——它自己攒下来的、关于自己的话。
两段都注入,顺序是人格在前(order 260)、自述在后(order 262)。
边界
- 只写自己的目录,不碰任何笔记库;笔记库那边是只读契约。
- 不写用户隐私(工具描述里明确要求:姓名、住址、账号、健康、财务一律不写)。
- 清空 = 删掉
~/.dsh/selfnote/整个目录。
测试
node --run test
三个文件:tests/smoke.mjs(13 项:注册、写入、容量裁剪、归档、注入长度、开关)、tests/api.mjs(9 项:状态、写入、改上限、非法值不落盘、清空进归档、404)、tests/client.mjs(2 项:slot 注册与 label、CSS 注入与清理、未连宿主时的提示)。
No comments yet. Be the first to write one.