dsh-headwater · 源流
给你的 Harness agent 一套自己的记忆:
- 超人的部分:说过的话原样留下,不丢、不改
- 人类的部分:会从里面长出「我理解你是谁」,会变、会丢细节
- 分寸:知道哪句话现在该说,哪句话现在不该说
不装模型,不做向量检索,不切块。三层文件 + 十个小工具。
装
两步。
第一步,打开 PowerShell,粘贴这一行,回车:
dsh plugin --profile desktop add github:h1-cat/dsh-headwater
不知道 PowerShell 在哪:按 Win 键,输入 powershell,回车。
DSH 开着也没关系,不用退。
第二步,重启 DSH。 设置页里会多出一个「记忆」,就是它。
用的是网页版(web profile)不是桌面端的话,把命令里的 desktop 换成 web。
装不上?
最常见的是第二步报「找不到 dsh 命令」。这说明你的 DSH 是精简版、便携版或者商店版,没带命令行工具。这种情况暂时得手动装一次,步骤在 INSTALL.md 里。
别的报错,把那段文字发到 Issues 就行。
卸载
dsh plugin --profile desktop remove dsh-headwater
记忆数据不会跟着删。它在你的工作区 .composure 目录里,是你的东西,不是这个应用的。
你的数据在哪
这个仓库里不含任何记忆数据。装好之后,账本写在你自己的工作区 .composure,不联网、不上传。唯一一次对外调用是重算「当前理解」,用的是你在 DSH 里自己配的那个模型。
三层
<workspace>/.composure/
├── episodes.jsonl L0 流水账 每句话原样追加,永不改写
├── book.json
│ ├── portrait L1 报表 「当前理解」:他是谁 / 还没了结 / 最近状态
│ ├── relation L2 账本 熟悉、张力、承受力
│ ├── open L2 账本 悬着的话
│ ├── stances L2 账本 我说过的立场
│ └── sayings L2 账本 我说过的重话 + 后续反应
L0 永不改,L1/L2 随便改。 理解错了改报表,事实丢了说明流水账里本来就没有。
怎么用
会话开始:不用检索就知道
插件每一轮把一小段挂在提示词末尾(section headwater,order 850):
## 我记得的
他是谁:…
还没了结:…
最近状态:…
## 分寸
熟悉 0.30,张力 0.00,承受力 0.62。关系平稳。
悬着的话:…
我说过:…
这就是「记忆自己出现」,不是等你调用。通常三到十行。
说之前:问一次
headwater_check(draft, intent, topic)
→ verdict: say | soften | warn_then_say | hold | stop
五档依次是:
- say —— 直接说,不用铺垫
- soften —— 说,但先接住他的状态
- warn_then_say —— 先说「这话可能不太好听」
- hold —— 先别说
- stop —— 别聊正事了,收一句留门的话
第 3 档是「难听但还是要说」;第 5 档是「他不想聊了」。这两条都不是「少说话」。
要原话:回查
headwater_recall(query, days, role, limit)
按时间或关键词翻原文,返回带时间戳的片段。不是摘要。
重写理解
headwater_portrait(action: 'write', who, threads, mood)
整段覆盖,写成你现在的判断。会随认识加深而变,这是对的。
它自己会重算
每 8 轮对话、且距上次重算超过 30 分钟,插件会用一次轻量模型调用把最近 40 条原文压成新一版的理解——不用谁记得去调用。
两个旋钮,写在数据目录的 settings.json 里,改完立即生效:
headwater_config(everyTurns=8, minMinutes=30) 每几轮重算一次、两次之间的最小间隔
也可以手动催一次:
headwater_recompute()
它返回 detail 说明这一步走到哪了:material(原文不够)/ empty(模型只产出了推理)/ json(没给可解析的 JSON)/ finish(调用被中断)。
推理模型的坑:
deepseek-flash这类模型会先把 token 预算花在推理上,正文可能一个text-delta都没有。所以这里先探测模型支持的最小 reasoning effort,再给maxTokens: 3000。如果你换模型后重算总是at: 'empty',就是这个原因。
别的
| 工具 | 用途 |
|---|---|
headwater_open |
挂一条悬着的话(relational 过期作废 / task 可以晚点提) |
headwater_settle |
了结一条 |
headwater_stance |
记下我在某话题的立场 |
headwater_state |
看全部账本 |
说话方式也跟着上
记住一个人说什么,和说得像个人,是两件事。前者靠 book.json,后者只能靠原文里的口气——写一段「他是个务实的人」没有用,形容词学不来。
每轮提示的末尾因此多一段:
他平时是这么说话的(原话,一个字没改。这是标尺不是台词——学句长、断句和用词,别复述内容):
- 「……」
- 「……」
五条样本从 episodes.jsonl 里由代码挑,不经模型:
- 长度 10–160 字,跳过代码块,末尾是问号的不收
- 按长度分三档各取几条,免得五条样本全是同一个口气、同一个话题
- 刚说的两条不收——否则提示里的样本每轮跟着他上一句抖,模型很容易把「他刚说的」当成「我该说的」,原地复读
- 引用块(
>)里混着我说过的话,整条跳过:学过去就是把我的句子当成他的口音 - 总字数超过 260 就从最长的开始砍。提示是每轮都在付钱的东西
- 原文一个字不改。模型顺手润色一次,口气就被磨平了
关掉:headwater_config(voice=false)。
它不替你定性格。 样本给的是「人是怎么说话的」的标尺,不是「你该是个怎样的人」的设定。
话掉在地上,插件自己捡
不需要模型记得调用 headwater_open。每一句话进来,插件自己看:
短(≤20 字)+ 问句之外 + 含「算了 / 随便 / 不想说 / 没事 / 别问了 / 无所谓 / 没意思 / 不想聊」
→ 自动挂一条 relational 的悬着的话
去重、最多同时挂 5 条、标记 auto: true。
为什么不做成「等模型自觉」:那等于让最关键的动作依赖最不可靠的东西。模型在聊到第三十轮时想不起来调工具,是常态,不是例外。
自动挂上之后,它会在下一轮的提示里出现,模型自己决定接不接。
不会在更新里被抹掉
三次压缩之后,「他为什么严谨」就只剩「他是个严谨的人」——来路没了。
三个机制挡住这件事:
① 锚点:不参与压缩,只增不减,每一轮都出现。
headwater_anchor(action='add', text='他要的是能跑起来的东西,不是说法')
重算时模型也能提议新锚点(anchors_add),但代码只负责去重和追加,绝不覆盖已有的。移除必须显式调用并给理由,同时记进变更日志。
② 变更日志:每次重算记下 who / threads / mood 从什么变成了什么。
who: …… → ……(多了「担心理解被磨成标签」这一层)
headwater_state 返回最近 6 条,能回答「它什么时候开始这样看我的」。
③ 核心印象有保护期:who 默认 6 小时才允许改写一次,threads 和 mood 每次都能变。
headwater_config(whoMinutes=360)
细节变得快,轮廓变得慢——这就是人类记忆对时间的处理方式。
④ 记忆数据自己有历史:账本目录(默认 .composure)如果是 git 仓库,插件会把变化自动提交进去。
- 每
autoCommitMinutes(默认 20)分钟检查一次,有变化就提交;没有变化不产生空提交 - 每次重算「当前理解」之后,立刻提交一次
- commit message 带原因和时间:
memory: portrait recomputed 2026-11-05 04:20 - 目录里没有
.git时不替你init,只记一条日志——仓库边界由人来划 - 只用 git 退出码判断结果,不读子进程输出,受限环境里也能跑;失败只记日志,绝不影响记忆写入
这样「它什么时候开始这样看我的」不止能查变更记录,还能用 git log / git diff 看到具体哪一版账本长什么样。
git -C .composure log --oneline -5
反应记录
你每说一句较有分量的话(headwater_check 之后实际说了),系统会盯着下一条用户消息:
- 他追问细节 →
engaged - 他说「嗯」「哦」「随便」 →
dismissed - 其他 →
acknowledged
这是全套里唯一别人不记的东西:说完之后那个人怎么样了。
它不做的事
- 不做向量检索、不切块、不装模型
- 不改人设。声音层给的是标尺,不是性格设定——它让语气落回人话,不替你决定你该是谁
- 不替你写台词。只给结论和理由
关闭
在 profile 的 cordis.patch.yml 里给 headwater 那行加 disabled: true,或在插件管理器里停用。停用后不写入任何东西,账本留着。
一条纪律
写入中立,读取带倾向。
账本记的是事实(他说了什么、隔多久、用了什么词),倾向只发生在解释的时候。这样换人设、换模型,底账都是同一份。
许可
MIT,全文见 LICENSE。
No comments yet. Be the first to write one.