Hermes Agent 是怎麼"記住你"的?
摘要
Hermes Agent 能"記住你",不是靠更大的上下文窗口,而是靠一套四層分工的長期記憶系統:USER.md(1,375 字符 / 約 500 tokens)負責"你是誰",MEMORY.md(2,200 字符 / 約 800 tokens)負責"我們做過什麼",SQLite + FTS5 會話檔案負責"任何一句原話都可以數週後精確翻回來",Skills 負責"我該怎麼做這類事"。寫入由 Agent 在 Compression / Checkpoint / Nudge / 用户顯式指令四種時機主動組織,召回同時結合結構化默認加載、FTS5 精確命中、LLM 語義摘要三條腿——這才讓"記住你"從概念落到工程。
引子:大部分 AI 助手讓人失望的第一個瞬間
不是它答錯了什麼,而是——
"你上次不是剛跟我説過嗎?"
上下文窗口從 8k 一路飆到 200k、1M,但"記住你"從來不是靠塞更多 token 能解決的:一次會話內的 200k 上下文,會話一斷就煙消雲散。真正想讓 Agent 長期記住你,必須回答三個反問:
- 什麼值得被寫入長期記憶?(寫入閘門在哪?)
- 記憶應該以什麼形態存下來,才能幾周後仍然可以被找到?
- 找的時候,Agent 是靠向量相似度,還是靠別的東西?
Hermes 用一整套長期記憶系統正面回答了這三個問題。下面把它拆成 5 層來看。
一、先定義"記住"是什麼
在人類語境裏,"記住你"至少包含三層意思:
- 知道你是誰——名字、職業、偏好、常用工具鏈。
- 知道我們一起做過什麼——之前聊過的項目、給過的結論、踩過的坑。
- 知道該怎麼和你打交道——你喜歡簡短還是詳細?先結論還是先過程?
一個只有大上下文窗口的模型,能在一次對話內同時做到這三點;但只要會話一斷,第 1、3 點就重置了。
Hermes 的思路是:把這三層分別落到不同的持久層裏,各自用最合適的方式維護——第 1 點交給 USER.md,第 2 點交給 MEMORY.md,第 3 點由 USER.md 中的偏好字段 + Honcho 用户建模共同維護。
二、寫入:Agent 主動組織,而不是隨手記
Hermes 的長期記憶不是"每説一句話就記一條",而是由 Agent 在四種明確時機主動組織並落盤:
| 觸發時機 | 作用 |
|---|---|
| Compression(壓縮) | 上下文接近上限時,先把當前會話裏"值得長期保留"的信息抽出來,再壓縮當前 context |
| Checkpoint(檢查點) | 完成一個子任務、切換話題等里程碑時,主動記一次 |
| Nudges(週期性提示) | 系統週期性地"戳"一下 Agent:"看看有沒有值得寫入長期記憶的內容?"這避免了信息在長會話裏悄悄丟失 |
| 用户顯式指令 | 用户直接説"以後記住我在 X 項目裏用的是 Y",會被識別為高優先級記憶寫入 |
關鍵在於:決定是否寫入長期記憶的是 Agent 自己,而不是全量落盤。這一步過濾,是"記憶質量"的第一道閘門——也是它和"每句話都存"的 Chat 歷史最本質的區別。
一個具體的經濟賬:如果沒有這層過濾,一個日活 50 次的用户,一年會往長期記憶裏灌進大約 1,800 萬 tokens 的原始對話;而 Hermes 的做法能把這個數字壓到 1% 以下,同時保留幾乎全部關鍵事實。
三、存儲:四層分工,各司其職
Hermes 把長期記憶拆成四種,分別放在不同的位置,每一層都有明確的容量上限:
| 層 | 載體 | 典型容量 | 加載時機 | 主要職責 |
|---|---|---|---|---|
| 用户畫像 | USER.md | ~1,375 字符 / ~500 tokens | 每次會話必載 | 你是誰、角色、偏好、常用棧、溝通風格 |
| 事實記憶 | MEMORY.md + memories/ | ~2,200 字符 / ~800 tokens | 每次會話必載 | 事件、決定、結論、跨會話要複用的事實 |
| 會話檔案 | SQLite + FTS5 全文索引 | 無上限(數月曆史) | 按 query 命中時載入 | 任何一句原話都可以數週後精確翻回來 |
| 程序性記憶 | skills/ 目錄(SKILL.md) | 單文件 KB 級 | 場景匹配時高優先級裝載 | "遇到這種情況我該怎麼做"(本分類另有專篇) |
除此之外,Hermes 還有一份 SOUL.md——Agent 自己的"人格描述",屬於 Agent 的自我模型,不屬於用户記憶,但會和用户記憶共同構成上下文底座。
為什麼每一層都設死上限?
有人會問:既然上下文窗口這麼大,為什麼 USER.md 只給 500 tokens?
三條理由:
- 系統提示每多 1,000 tokens,每天 50 次調用一年浪費 1,800 萬 tokens——一等一的成本壓力。
- 每次會話必載的東西,必須精挑細選——它是系統提示的一部分,臃腫了會擠壓真正的任務上下文。
- 上限逼出取捨——容量滿了不會靜默丟棄,而是逼 Agent 主動整合(後面第五節講)。
這也是 Hermes 的核心哲學:"記住"不是"存下",是"經過取捨的存下"。
一個不能忽視的補充組件:Honcho
Hermes 還引入了一個叫 Honcho 的組件,做的是 dialectic user modeling——通俗講,就是不斷從對話裏抽取"關於用户的可複用陳述",反哺 USER.md 的維護。
結構化文件不擅長的"隱性偏好"(比如"這個用户總在下午 3 點後不耐煩"、"用户對語氣助詞特別敏感"),就靠這一層純 LLM 驅動的推斷來補齊。
四、召回:結構化 + 全文 + 語義,三條腿走路
傳統 RAG 方案的召回,很依賴向量相似度。但只用向量,會遇到兩個老大難問題:"你重要不代表你和 query 相似"、"細節被稀釋在整段裏"。
Hermes 的召回策略更像"混合檢索":
| 檢索方式 | 觸發場景 | 典型延遲 |
|---|---|---|
| 結構化默認加載 | 每次對話啓動 | 幾乎為零(就是系統提示的一部分) |
| FTS5 全文檢索 | 用户問具體事:"上次那個報錯是啥來着?" | ~20ms 命中,~1ms 翻頁 |
| LLM 語義摘要 | 需要跨條目整合的問題 | 秒級,用便宜模型跑(如 Gemini Flash) |
這三層配合,才讓"記住你"不只停留在"我們向量相似",而是"我真的知道你説過什麼"。
一個便利貼的類比可以幫你理解這個分層:USER.md 是貼在顯示器邊框上的便利貼(每次抬眼就看得到),MEMORY.md 是桌上的日記本(每次抬眼也看得到,但內容更多),SQLite+FTS5 是書櫃裏的檔案盒(不常翻,但要找一定找得到),Skills 是肌肉記憶(該做的時候身體自己知道)。
五、更新:記憶是活的,不是流水賬
一個常被忽視的點:記憶不僅要能寫入,還要能被修改和淘汰。Hermes 在這點上有三條明確策略:
理由 1:新舊衝突時,優先更新而不是並列寫入
避免"分裂人格"——不能同時存在"用户偏好 Vue / 用户改用了 React / 用户又回到了 Vue"三條並列的記錄。Hermes 的做法是:偏好類字段覆蓋舊值,事實類保留歷史但更新"當前狀態"字段。
理由 2:長期沒被引用的記憶條目,會被判定為"低價值"逐步降權
MEMORY.md 有硬上限(2,200 字符),容量滿了的時候會返回:
{
"success": false,
"error": "Memory at 2,100/2,200 chars. Consolidate now...",
"current_entries": [...],
"usage": "2,100/2,200"
}這不是錯誤,而是閘門信號:Agent 必須做取捨,把陳舊的、低價值的條目合併或刪除,才能繼續寫。
理由 3:用户明確否認的信息,立刻刪除
不是"記錄一條相反的",而是物理刪除——保持世界模型自洽。
也就是説,Hermes 更接近"編輯一份活的檔案",而不是"追加一份日記"。
六、這套機制想真的跑通,還差一個東西
再好的記憶機制,也需要一個前提:Agent 得一直活着。
如果你把 Hermes 裝在自己筆記本上,筆記本一合蓋就"打盹",後台自省循環(nudge)就停擺;換設備、系統重裝還要手動搬 ~/.hermes/ 目錄;FTS5 索引每次重裝都要從零重建。
這時候,雲託管方案就變得非常有意義。LightVela 是雲託管的 Hermes Agent 服務:
- 獨立雲端實例,24×7 在線,
MEMORY.md/USER.md/SQLite 會話檔案永久駐留; - 後台 nudge 循環持續運行,Agent 真正做到"你不用它的時候也在成長";
- 數據僅存於你的專屬服務器;
- 手機、筆記本、Telegram、飛書……多渠道進來都是同一個"認識你的 Agent"。
Hermes 把"記住你"做成了工程實現;LightVela 讓這套工程實現的每一天都在你身邊生效。
小結
- Hermes 的"記住你"不是靠更大的窗口,而是靠主動整理 + 分層存儲 + 混合召回 + 持續更新。
- 每一層都有明確容量:
USER.md500 tokens,MEMORY.md800 tokens,SQLite 無上限,Skills 場景化。 - 好的 Agent 記憶系統,一定是"編輯檔案"而不是"追加日記"——上限逼出取捨。
- LightVela 想做的,是把這份能力從命令行帶到產品裏,讓"被記住"成為默認體驗。