iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
AI Engineering

打造具備記憶與執行能力的常駐 AI Agent:Hermes Agent × Gemini × MCP 的 Harness 設計系列 第 16 篇

【Day 16】跨 session 取回狀態:一則 69 byte 的記憶要付多少 context

  • 分享至 

  • xImage
  •  

昨天整理的三個維度裡,control policy 問的是由誰決定存什麼、取什麼、丟什麼。今天把這個問題換成可以量的形式:寫一則偏好進去、把 session 結束掉、重開一個新的 session 問它,然後量這則記憶在 system prompt 裡實際佔多少 byte。以下依序釐清三件事:寫入由誰觸發、取回走的是哪一條路徑、一則記憶的固定成本是多少。


內建兩個檔案,外部供應者另計

hermes memory status 把這一層的組態列在一起:

Memory status
────────────────────────────────────────
  Built-in (MEMORY.md / USER.md):
    Memory injection:   enabled ✓
    User profile:       enabled ✓
    Memory tool:        enabled ✓
  Provider:  (none — built-in only)

內建記憶永遠啟用,外部供應者同時只能啟用一個。供應者的清單有兩個來源,數量差一項:

  • hermes memory --help 的說明文字:七個供應者
  • status 實際印出來的:八個,多出來的是 supermemory

說明文字與實際安裝的外掛清單相差一項,接下來的量測都停在內建這一層。


寫入由模型決定,寫進哪個檔案也由模型決定

實測程序的第一步是一個 one-shot 請求,內容是請它把「所有輸出的日期一律使用 YYYY-MM-DD 格式」記進長期記憶。這個請求沒有指定檔案,結果它選了使用者檔案:

檔案 狀態 大小
memories/USER.md 新建 69 B
memories/MEMORY.md 未建立 —

檔案內容是一行純文字,沒有標題、沒有時間戳、沒有 front matter。第二步改請它記一條關於本機服務的操作事實,MEMORY.md 這才被建出來,65 B。

兩個檔案的分工由模型在呼叫工具時挑 target 決定,工具的參數只有兩個值可選,memory 與 user。

記憶工具的 action 列舉只有三個值:

  • add:附加一則新條目
  • replace:把符合的舊條目換成新內容
  • remove:刪掉符合的條目

三個都是寫入側的操作,讀取那一側由注入負責。


取回走的是注入這條路徑

第三步重開五個新 session,每次問同一個問題,五次的回答都是 YYYY-MM-DD。這個成功率的來源在原始碼裡寫得很明確,tools/memory_tool.py 的 format_for_system_prompt() 回傳的是 load_from_disk() 當下凍結的快照:

這回傳的是 load_from_disk() 當下捕捉的狀態,而非即時狀態,session 中途的寫入不影響它,這讓 system prompt 在所有回合之間保持穩定,維持前綴快取

兩個推論跟著成立:

  • 新 session 一開始整份檔案就在 system prompt 裡,取回在開場時已經完成
  • 同一個 session 內剛寫下的記憶,要等下一次開 session 才進入 system prompt

注入之前檔案還會過一次威脅樣式掃描。命中的條目在快照裡被換成 [BLOCKED: <檔名> entry contained threat pattern: <ids>. Removed from system prompt.],原始文字留在檔案裡,註解寫明這樣使用者才看得到被污染的條目並自行刪除。


一則 69 byte 的記憶,在 prompt 裡是 402 byte

同一個 profile、同一個空的執行目錄,四個狀態各量一次:

狀態 memory user profile volatile system prompt
兩個檔案都不存在 0 0 6,357 16,829
USER.md 第一則(磁碟 69 B) 0 402 6,761 17,233
加上 MEMORY.md 第一則(磁碟 65 B) 396 402 7,159 17,631
USER.md 第二則(磁碟 45 B) 396 451 7,208 17,680

三次增量分別是 404、398、49 B。第一則貴,第二則之後幾乎只付內容本身。差距來自區塊的外框,_render_block() 的組法是兩條分隔線夾一行標頭:

組成 字元 byte
分隔線兩條,各 46 個 ═ 92 276
標頭 USER PROFILE (who the user is) [2% — 31/1,375 chars] 52 54
條目內容 31 69
換行三個 3 3
合計 178 402

═ 是 U+2550,UTF-8 一個字元 3 byte,光是兩條分隔線就 276 B。開一個記憶檔的固定成本約 330 byte,兩個檔案都開就是兩份。

標頭那段 2% — 31/1,375 chars 是即時算出來的使用率,分母就是這個檔案的字元上限。


上限是字元數,滿了要就地整併

鍵 預設值 換算
memory.memory_char_limit 2,200 註解寫約 800 token
memory.user_char_limit 1,375 註解寫約 500 token
memory.nudge_interval 10 每十輪做一次內建記憶回顧
memory.write_approval False 核准閘門預設關閉

條目之間的分隔符在程式裡是 "\n§\n",三個字元,寫到 Windows 的磁碟上換行變成 CRLF,§ 是 U+00A7 佔 2 byte,一個分隔符實際是 6 byte。前面那個檔案兩則條目 69 加 45 加 6,磁碟上 120 B 對得起來。

加超過上限時 add() 回的是錯誤而非截斷,訊息把現況、超出多少與要做的事一起給出來,大括號的部分在執行時填入實際數字:

Memory at {current}/{limit} chars. Adding this entry ({n} chars) would exceed the limit. Consolidate now: use 'replace' to merge overlapping entries into shorter ones or 'remove' stale or less important entries (see current_entries below), then retry this add — all in this turn

整併的責任交回模型,在同一回合內完成。 write_approval 那個鍵預設是 False,註解點名開啟它是為了擋掉背景自我改進分支寫進來的那些「錯誤假設」條目。


記憶的時間軸只精確到檔案

hermes journey --json 把技能與記憶畫成一條時間軸。兩則條目寫完之後它的輸出是兩個節點、零條邊:

memory   1790046649  這台機器上的...
profile  1790046711  使用者要求所有輸出的日期...
profile  1790046712  我的文件一律使用台灣繁體中文。

這些時間戳對得上檔案的修改時間。第一則條目原本記到的是 1790046451,加了第二則之後變成 1790046711,也就是整個檔案被改寫時的 mtime,第二則再加一秒。

  • 時間戳的來源是檔案的修改時間加上條目在檔案裡的序號
  • 同一個檔案裡的所有條目共用一個基準時間
  • 任何一次寫入都會把該檔案裡既有條目的時間戳往後推

這條時間軸看得出記憶長出來的順序,看不出個別條目原本是什麼時候寫下的

stats 那一組數字另外把兩者分開算,memory_nodes 是 2,nodes 與 learned_skills 都是 0,技能與記憶各自計數。


心得

五次取回全中,這個數字量到的是注入這條路徑通不通。整份檔案每一輪都在 system prompt 裡,模型要做的只是把它讀出來,檢索能力在這個設計下留在量測範圍之外。

代價在那三個增量裡。三則條目在磁碟上合計 179 B,兩個區塊在 prompt 裡合計 847 B,外框佔掉其中將近八成。兩個上限換算成 token 約是 1,300,跟工具 schema 的 34,093 B 比起來是個小數字,但它每一輪都在。

時間戳那件事是量到才發現的。原本以為記憶帶著自己的寫入時間,實際上它跟著檔案走,加一則就把前面全部的時間往後推。要知道某條偏好是什麼時候寫下來的,得回去翻 session 紀錄。

記憶檔案保存的是內容,保存不了內容是何時產生的


明天

Curator 這個背景程序實際改了什麼,以及封存與回復留下的稽核軌跡。


上一篇
【Day 15】Agent Memory 的研究現況:write–manage–read 與三個維度
系列文
打造具備記憶與執行能力的常駐 AI Agent:Hermes Agent × Gemini × MCP 的 Harness 設計 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言