Letta 把記憶當成 agent 自己推理的對象,而不是外部服務。它源自 MemGPT 論文的核心類比——把 LLM 的 context window 當成作業系統的實體記憶,把外部儲存當成磁碟,讓 agent 自己執行分頁——並在此之上加了兩個關鍵演化:labeled memory block 與 sleep-time compute。理解 Letta 的價值不在於是否採用它,而在於它示範了「記憶治理放進 agent 迴圈之內」這條路線能走多遠。
核心機制:OS 式的三層記憶
Letta 的記憶模型是三個層次,對應作業系統的記憶體階層:
Main context(主上下文)——agent 每一輪都看得到的內容,等同 分類學 裡的 working memory。它由系統在每次推理前「編譯」出來:從資料庫讀取當前的 block 值,透過 Jinja 模板組裝成 prompt。「編譯」這個用詞很精確——main context 不是儲存,是一個由 DB 狀態算出來的結果。
Recall storage(召回儲存)——近期的訊息歷史,agent 可以按需搜尋。它是對話流水,不是精煉的事實。
Archival storage(歸檔儲存)——長期的可搜尋知識庫,容量無上限。agent 用工具主動寫入與查詢。
三層之間的移動由 agent 自己透過工具呼叫決定。這是 Letta 與所有「外部記憶服務」路線最根本的差異:在 Mem0 的模型裡,記憶治理發生在 agent 的推理之外(一條管線在背景抽取事實);在 Letta 的模型裡,「要記什麼」是 agent 推理內容的一部分,會消耗 token、會佔用推理步驟,也因此可以被 agent 的目標所引導。
Memory block:這個框架最值得抄的東西
Block 是 Letta 的載重原語,也是本篇最重要的「可抽取模式」。一個 block 有四個成分:
- Label(標籤)——標示用途,例如
human(對使用者的理解)、persona(agent 自己的角色)、knowledge。 - Value(值)——一段字串,可以是任意序列化後的結構。
- Size limit(容量上限)——這個 block 最多能佔多少 context。
- Description(說明,可選)——告訴 agent 這個 block 該放什麼。
Block 各自以 block_id 持久化在資料庫,因此開發者可以透過 API 直接讀寫(update_block_value() 之類),不必經過 agent。每個 block 可以獨立設定為可編輯(agent 能改)或唯讀(只有開發者能改)。
這個設計解決了一個在其他框架裡處理得很糟的問題:context window 的預算分配。當記憶是一個扁平的 memories 表時,你只能控制「召回幾條」,無法保證「使用者畫像一定有 500 token 的空間、專案規則一定有 1000 token」。Block 把 context window 從一塊整體切成有名字、有配額、有存取控制的分區——這正是作業系統管理記憶體的方式,而且它可以在任何框架裡實作,不需要用 Letta。
一個容易被忽略的細節:主 agent 通常沒有直接編輯 core memory 的工具。它能發訊息、能呼叫使用者工具、能搜尋 recall 與 archival,但編輯 block 這件事在較新的設計裡被推給了 sleep-time agent。這是一個有意的職責分離——把「做事」與「整理記憶」放在不同的推理迴圈裡,避免記憶維護污染當前任務的推理。
Sleep-time compute:把整理記憶搬到背景
Letta 把這個機制稱為 sleep-time compute(他們的部落格也用 dreaming 這個說法)。機制是:背景的 sleep-time agent 審視近期的對話輪次或既有的 codebase,把歸納出的結論寫回 memory block,Letta 稱這種產物為 learned context,而且它可以被多個 agent 共享。
它解決的問題是成本與延遲的錯配。如果記憶整理發生在使用者等待回應的路徑上(hot path),你會為了品質付延遲;如果搬到背景,你付的是額外的 LLM 呼叫但不影響回應速度。 LangMem 把同一個取捨明確地做成了兩個 API 選項(見 LangMem/LangGraph),Hermes 用 periodic nudge 達成類似效果(見 檔案原生路線)。
「記憶整理是一個非同步的、與主任務分離的推理任務」是 2026 年跨框架最強的共識之一。 三個路線完全不同的框架各自獨立收斂到這個結論,這比任何單一框架的宣稱都更值得採信。
儲存後端
Letta 是一個 runtime 而非一個 library:你部署它(自建或用它的雲服務),它管理 agent 的狀態。底層以資料庫持久化 block、訊息、archival 條目,archival 檢索用向量。它另外提供 ADE(Agent Development Environment)——一個可以直接檢視與編輯 agent 記憶狀態的介面。
這個「runtime 而非 library」的定位是選型時最關鍵的一件事。 採用 Letta 意味著把 context window 的管理權交給它:它決定何時壓縮、何時分頁、何時觸發 sleep-time。這在 agent pattern 已經確定、長程記憶價值明確時是很大的槓桿;在架構還在變動時則是很重的綁定。
寫入與召回策略
寫入:由 agent 或 sleep-time agent 透過工具呼叫觸發(歷史上是 core_memory_append / core_memory_replace 這類工具編輯 block;archival 則有獨立的插入工具)。寫入時機是模型決定的,不是規則決定的——這是它的最大優點也是最大風險:優點是判斷可以有脈絡,風險是不可預測、不可稽核成一條規則。
召回:block 是常駐的(每輪都在 context 裡,不需要召回);recall 與 archival 由 agent 主動搜尋。常駐與按需的分界由 block 的設計決定,這是開發者控制得到的部分。
優缺點
優點:記憶治理與任務推理共用同一個模型,因此判斷有脈絡;block 提供了明確的 context 預算控制;狀態可透過 API 與 ADE 直接檢視,不是黑盒;block 共享提供了多 agent 協作的原語。
缺點:runtime 綁定深,遷移成本高;寫入品質完全依賴模型判斷,難以用規則約束;每次寫入都是一次 LLM 呼叫,成本與對話量成正比;block 的容量上限需要人工調校,沒有自動化的預算最佳化。
適合場景:長期陪伴型 agent、需要跨 session 累積對特定 codebase 或領域理解的 agent、多 agent 共享知識的系統。不適合:短會話的一次性任務、記憶只是加分項的產品、已經有既定 orchestration 框架且不願替換 runtime 的專案。
可抽取的模式
即使不用 Letta,這四個模式可以直接搬到任何架構:
Labeled memory block with quota(有標籤與配額的記憶分區)——把常駐 context 切成有名字的分區,每個分區有 token 配額與存取權限(唯讀/可寫)。這是本專欄推薦所有新專案都採用的模式,它讓 context 預算從一個模糊的總量變成可分配、可監控的資源。實作見 介面草案 的 MemoryBlock 定義。
Compiled context(編譯出來的上下文)——把 main context 當成從持久化狀態算出來的結果,而不是一個逐步累積的緩衝區。這讓「上一輪的 context」可以被完整重建,是可觀測性與 debug 的基礎。
Separation of doing and remembering(做事與記憶的職責分離)——用不同的推理迴圈處理任務執行與記憶整理。
Read-only blocks as guardrail(唯讀分區作為護欄)——把不該被 agent 改動的東西(專案規則、安全紅線)放進唯讀 block。這是防止記憶投毒影響行為規則的結構性手段,比在寫入路徑上做內容過濾更可靠。