前言¶
長對話的 agent 最常見的死法是”聊着聊着忘了你是誰”。靠上下文窗口硬塞,遲早要被壓縮擋掉;壓縮一發生,”他爲什麼嚴謹”就只剩”他是個嚴謹的人”,來路沒了。向量檢索能把句子存起來,但存進去的是碎片,答出來的是相似度,既沒有”該不該說”的判斷,也說不清這個印象是從哪句話長出來的。
下面介紹 h1-cat 維護的 dsh-headwater(分類:記憶,當前星標 0)。它的思路不是”存更多”,而是用三層文件把”原話”和”理解”分開:原話永不改寫,理解可以隨時改,改錯了也有個底賬可查。
這是什麼¶
一句話定位:給 DSH Harness agent 加一套自己的記憶——原話一句不丟,從原話里長出”我理解你是誰”,開口前先判斷這話現在該不該說。
- 維護者:h1-cat
- 分類:記憶
- 許可:MIT
- 不裝模型、不做向量檢索、不切塊,只有三層文件加十個小工具
它把記憶分成三層:
<workspace>/.composure/
├── episodes.jsonl L0 流水賬 每句話原樣追加,永不改寫
├── book.json
│ ├── portrait L1 報表 "當前理解":他是誰 / 還沒了結 / 最近狀態
│ ├── relation L2 賬本 熟悉、張力、承受力
│ ├── open L2 賬本 懸着的話
│ ├── stances L2 賬本 我說過的立場
│ └── sayings L2 賬本 我說過的重話 + 後續反應
規則只有一條:L0 永不改,L1/L2 隨便改。理解錯了改報表,上了下一次重算就覆蓋;事實丟了說明流水賬裏本來就沒有。
安裝與啓用¶
官方安裝命令不是 dsh plugin add github:...,而是帶上 profile:
dsh plugin --profile desktop add github:h1-cat/dsh-headwater
粘貼到 PowerShell 回車,DSH 開着也沒關係。如果用的是網頁版(web profile),把命令裏的 desktop 換成 web。
然後重啓 DSH,設置頁裏會多出一個「記憶」。
卸載:
dsh plugin --profile desktop remove dsh-headwater
記憶數據不會跟着刪。它留在工作區的 .composure 目錄裏,是你的數據,不是這個應用的。
最常見的報錯是第二步提示「找不到 dsh 命令」,說明裝的是精簡版、便攜版或商店版,沒帶命令行工具。這種情況要手動裝一次,步驟在倉庫的 INSTALL.md 裏。別的報錯可以直接到 Issues 提交。
會話開始:記憶自己出現¶
插件每一輪把一小段掛在提示詞末尾,section 名爲 headwater,order 850:
## 我記得的
他是誰:…
還沒了結:…
最近狀態:…
## 分寸
熟悉 0.30,張力 0.00,承受力 0.62。關係平穩。
懸着的話:…
我說過:…
這不是等模型調用工具纔會出現的記憶,而是自動注入,通常三到十行。
說之前:問一次¶
headwater_check(draft, intent, topic)
→ verdict: 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',就是這個原因。
說話方式也跟着上¶
記住一個人說什麼,和說得像個人,是兩件事。後者只能靠原文裏的口氣,寫一句”他是個務實的人”學不來。所以每輪提示末尾還多一段樣本:
他平時是這麼說話的(原話,一個字沒改。這是標尺不是臺詞——學句長、斷句和用詞,別複述內容):
- 「……」
- 「……」
五條樣本由代碼從 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。這是全套裏唯一別人不會替你記的東西——說完之後那個人怎麼樣了。
它不做的事¶
- 不做向量檢索、不切塊、不裝模型
- 不改人設,聲音層給的是標尺不是性格設定
- 不替你寫臺詞,只給結論和理由
適用場景與注意¶
適合交流長、需要記住此前說過什麼、以及需要判斷分寸的對話型 agent。它默認以當前 dsh 進程的權限運行,安裝前應先打開源碼看一眼,並確認 MIT 許可符合你的分發要求。
一條紀律貫穿整個實現:寫入中立,讀取帶傾向。賬本記的是事實(他說了什麼、隔多久、用了什麼詞),傾向只發生在解釋的時候。這樣換人設、換模型,底賬都是同一份。
數據都在自己的工作區 .composure,不聯網、不上傳,唯一一次對外調用是重算”當前理解”,用的是你在 DSH 裏自己配的那個模型。
關閉¶
在 profile 的 cordis.patch.yml 裏給 headwater 那行加 disabled: true,或在插件管理器裏停用。停用後不寫入任何東西,賬本留着。
結尾¶
dsh-headwater 的價值不在”多記住幾句”,在於把原話、理解和分寸拆成三層,讓原話永遠在、理解可重寫、說出口前過一次判斷。目錄頁在 https://www.skillhub.cn/plugins/h1-cat/dsh-headwater ,源碼在 https://github.com/h1-cat/dsh-headwater 。