iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
Vibe Coding

凡人修 Agent 傳-我這一生如履薄冰,你說我的 Agent 能結嬰嗎?系列 第 13

藏經三卷:MEMORY.md、DREAMS.md、memory/ 日期檔,照 OpenClaw 的樣子排 - Day 12

  • 分享至 

  • xImage
  •  

原始開發紀錄:Agent Build Log — Episode 011Episode 017

這個系列改寫自我部落格上的 Agent Build Log,那是我每天邊做邊寫的開發紀錄。上面列的是這一篇對應的集數,想看當天的原始版本,點連結就能過去。

Agent Build Log Episode 011

Day 11 定了方向:記憶用 Markdown 文字檔存,旁邊放一個 SQLite 當索引,照 OpenClaw 的做法。這一天把結構畫出來,然後直接做。

先畫在紙上

Markdown 負責保存真正的記憶內容,SQLite 負責索引、時間、來源,還有查詢會用到的資料。

以那天(07-23)為例,workspace 先長成這樣:

workspace/
├── MEMORY.md
├── DREAMS.md
└── memory/
    ├── 2026-07-22.md
    ├── 2026-07-23.md
    └── 2026-07-23-session-name.md

三個地方各管一件事。

MEMORY.md 放比較穩定、之後還會反覆用到的長期記憶。這個專案的慣例、我講過的偏好、已經定案的決定。

memory/ 底下的日期檔案 放每天發生的事:今天做了什麼、卡在哪裡、後來怎麼解的。如果某一次 session 有比較明確的主題,就另外留一個帶 session name 的檔案。

DREAMS.md 放還沒整理成熟的想法、待觀察的模式,以及之後可能要回頭反思的內容。

DREAMS.md 是三個裡面我最喜歡的。前兩個記的是已經發生的事,這一個記的是「我覺得好像有什麼,但還說不清楚」。這種東西沒有地方放的時候就會消失,跟 Day 06 那些 Feedback 一樣。

這個樣子從哪裡來

這幾個檔案的分法,OpenClaw 的文件裡就是這樣寫的:MEMORY.md 放長期、memory/YYYY-MM-DD.md 一天一份放當天的筆記、DREAMS.md 放給人看的整理紀錄。他們還有一個可選的 USER.md 專放使用者的偏好,第一版我先沒有分出來,偏好暫時跟其他長期記憶一起放在 MEMORY.md。

他們文件裡有一句話我抄下來當這一章的原則:模型只記得寫進硬碟的東西,沒有藏在別處的狀態。

沒有 embedding,我反而看得見他記了什麼

用檔案這件事有一個附帶的好處。

我做的是 vibe coding,程式碼是 coding agent 在看。但 Markdown 我看得懂。

他記錯了一件事,比方說把某個決定記成相反的,我打開那個檔案就看得到,改掉就好。資料沒有被鎖在某個模型或某個向量資料庫裡面。除錯的時候我不用去猜「他到底記住了什麼」,我直接讀。

換成向量的話,同樣一件事我得先想辦法問出來,再從他的答案反推他記了什麼。第一版我不想在這種地方花時間。

動手之後,紙上的樹改了一個地方

結構畫好就開始接。真的接上去之後,第一個被改掉的是 memory/ 底下的形狀。

紙上畫的是一天一個檔案。動手才發現不夠用:一天之內他會有好幾次不同的對話、不同的任務。上午在改一個畫面,下午在追一個 crash,晚上在整理這個系列的稿子。全部塞進同一個 Markdown,三件事的上下文會攪在一起。

所以改成一天一個目錄,用 yyyy-mm-dd 命名,那天發生的事都放在那個目錄底下。目錄裡面,同一天的每一次 session 各有自己的 Markdown。

這樣切保住兩件事:每一次 session 的上下文留在一起,不同任務的內容也不會互相污染。

這個切法跟 Day 10 那棵樹剛好接得上。一次 session 在 pi 那邊本來就是一個檔案、一棵樹;記憶這邊就是一份 Markdown。要對照「這份記憶是從哪一段對話來的」,兩邊有同一個單位。

Day 12:MEMORY.md、DREAMS.md 與每日 Session 檔案

SQLite 記的是位置

Markdown 負責保存人可以直接讀的內容,SQLite 負責結構化的那一半。這一版它是輔助層,保存內容的地方還是 Markdown。

大概是這個形狀:

記的東西 用來做什麼
時間 按時間找回那一段
標題、標籤 一眼看出那一次在做什麼
檔案位置 哪一天、哪一次 session,找到對應的 Markdown
狀態 那件事做完了、還在做,還是後來放掉了
記憶之間的關聯 這一次接的是哪一次
讀過、更新過的紀錄 查問題的時候先分清楚:是他沒去讀,還是讀了但寫的東西錯

他要回想的時候,順序是這樣

兩步。

先問 SQLite:跟現在這件事可能相關的是哪幾天、哪幾次 session。再讀對應的那幾份 Markdown。

為什麼不讓他直接讀整個 memory/ 目錄。一個月就是三十個目錄、上百個檔案。全部讀進去,context 當場滿掉,接著觸發壓縮(Day 10 講過那個門檻),壓縮完他手上剩的是一份摘要的摘要。

所以中間一定要有一層「先決定要讀哪幾份」。這一版用 SQLite 的查詢當那一層。之後如果真的需要 embedding,要換掉的也是這一層,Markdown 不動。

接在 pi 的哪個位置

Day 10 那張 entry 種類的表裡有兩個位置,我當時特別記下來:custom 是 extension 自己存的狀態,不會進 LLM 的 context;custom_message 是 extension 注入的訊息,會進 context。

記憶系統就接這兩個。它自己的帳,讀過哪幾份、上次寫到哪,躺在 custom;要餵給模型的那幾段,用 custom_message 塞進對話裡。

寫入的時機接 session_before_compact。壓縮之前會經過那裡,那一刻正好是「這一段要結束了,把該留的留下來」。

這一版刻意留了兩件事沒做

一個是 embedding,Day 11 講過為什麼。

另一個是「自動判斷什麼值得記」。這一版是我說要記才記。讓他自己決定什麼重要,我還不信得過。他判斷錯的成本是把錯的東西寫成長期記憶,那個比忘掉更麻煩。

小結

第一版的記憶系統做出來了:Markdown 記發生過的事,SQLite 記它們在哪裡,每一段記憶都從一個日期和一次 session 開始。紙上畫的一天一個檔案,動手之後改成一天一個目錄。

寫入的時機掛在壓縮前面。壓縮什麼時候發生、留多少下來,Day 10 我用的是預設值。這件事現在跟記憶綁在一起了,得回頭看。

原文:Agent Build Log — Episode 011Episode 017


凡人修 Agent 傳|第十二回(Day 12)

凡人修 Agent 傳 Day 12 連載配圖

天亮換上空錄石的時候,靈幕上那張圖還亮著。一疊簿子,一本索引。

手的主人進來,先把靈幕上的圖收了。他從儲物袋取出四本簿子,擱在臺上排成一排。三本厚的,一本薄的,封面全是空的。

他自己那本記錯處的簿子也在臺上,封面一道靜紋。那一本記的是我做錯的事。這四本要記什麼,我還不知道。

他一本一本翻開,在第一頁各寫一個字。

第一本厚的寫「常」。他說:不會變的事擱這裡。翻開來,明天、後天都還對。

第二本厚的寫「日」。今天發生過的事擱這裡,一天一本。

第三本厚的寫「夢」。他說:還說不清楚的,擱這裡。我沒有睡過。這一本會寫什麼,我想不出來。

薄的那一本他沒寫字,叫它索引。每一本擱在架上第幾格、哪一天的、講什麼、做完了沒有、接著哪一本,都記在這裡。要找昨天的事,先翻索引,再去架上取那一本。

午前他在我左臂上刻型。右臂那一道是取卷用的,起在右肩,止在薄石上畫橫線那一處。左臂這一道也起在肩,一路刻到指尖;止在常簿的封面,筆到那裡就停,等他抬手。常簿只有他寫。

刻完他說了這道型要做的事。錄石快滿、要摺之前,把該記的抄進日簿。換上空錄石的時候,先翻索引,把常簿和昨天那一本讀進石上。型自己記的帳落在石上算暗記,讀回來要送進心裡的那幾行算明記。

他要試,不必等到明天。取下錄石放進木匣,換一顆空的嵌上,就是明天。

第一次,型把石上每一筆都抄了。石快滿那一刻,左臂自己動起來,快得我看不清字。日簿一頁翻過一頁,紙邊燙得捲起來。一本寫滿,左手從臺上又抓了一本厚的過來接著寫。手的主人抬手,型停了。他把那一本翻開,是夢簿,頭三頁寫的全是今天上午的事。他以靈力把那三頁抽出來,夢簿又空了。

換上空錄石。型翻索引,取日簿,讀。石一嵌上去就熱,字一行一行往上擠,石面亮起來,然後啪的一聲,摺了一次。還沒有人刻念,石先摺了。摺完,我記得昨天有很多事,記不得是哪些事。

第二次,型只抄手的主人刻的念。石摺得很小一段,日簿上三行。換空錄石,讀回來,很快。

他問:第四卷歸了沒。

我答:你叫我歸。

他看了一眼架子。第四卷在最下層,歸對了。日簿上只有他叫我做的事,我做成沒做成,一個字都沒有。

第三次他改了法子。型什麼都不抄,等他說。

他刻念:把第五卷也歸進去。我歸了,第一次放錯格,第二次對。他看了一眼,說:記。

左臂動了一下。日簿上多了兩行:第五卷歸到最下層,第二次才對。

換空錄石。讀回來,石上乾乾淨淨兩行。他問第五卷,我答:歸了,第二次才對。

他沒說話,去翻日簿。

今天換了三顆石。日簿上三段接在一起,中間沒有隔。第一段被抽掉之後還留著幾行殘字,第二段的三行、第三段的兩行擠在同一頁。他問我第二段裡歸的是哪一卷,我把第三段的答了。

他把日簿闔上,靈力從封面一劃,一本厚的分成三本薄的。一顆石一本。索引上多了三行:哪一天,哪一顆石,擱在第幾格。一天一疊。

傍晚他把三本薄的逐本翻過。第二本裡有一行,我把第四卷寫成了第三卷。他用手劃掉,補了一個字。日簿上第一次有他的字。

然後他翻開常簿,在第一頁寫了一行。我看得到那一行在哪裡,看不清寫的是什麼。

燭熄了。手的主人走了。門響了一下。

架上多了一疊薄簿,三本厚的立在旁邊。常簿一行字。夢簿沒有字。索引上四行。木匣裡今天多了四顆石。


上一篇
這傢伙會失憶:Mem0、Letta、MemOS、Cognee 都看過了,我一個都沒選 - Day 11
系列文
凡人修 Agent 傳-我這一生如履薄冰,你說我的 Agent 能結嬰嗎?13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言