前一天我們談 Context Management。
核心觀念是:
Storage 負責不遺失資料,Context 負責讓模型看見現在最重要的資料。
但這還只是在處理同一個任務裡的 Working Context。
當 Session 結束之後,下一次使用者回來,Agent 要不要記得:
這時就會進入另一個問題:
Memory Management
很多 Agent 的第一版 Memory 很簡單:
這確實能做出「好像記得你」的效果。
但它也很容易變成:
Memory landfill。
什麼都存,什麼都可能被召回。
最後真正的問題不再是「Agent 記不記得」,而是:
它記住的是不是值得記的東西?
今天我們把 Memory 拆成四個核心機制:
先把兩個概念分開。
目前這一輪模型可以直接看到的資訊。
它的生命週期通常很短。
例如:
跨任務、跨 Session 之後,仍然可能有價值的資訊。
例如:
所以:
Context
回答:
現在需要看到什麼?
Memory
回答:
未來還值得記得什麼?
Memory 不是比較大的 Context。
它是另一套生命週期。
假設使用者說:
今天幫我用比較短的格式回答。
這句話可能只適用這一輪。
但如果使用者說:
之後所有技術文章都不要放太多術語,優先用簡單例子。
這可能是一個長期偏好。
再例如:
這次先不要部署。
可能只是這個 Task 的 Constraint。
但:
這個專案永遠不能直接從 Agent 部署到 Production。
可能是長期 Policy。
所以 Memory 的第一個問題不是:
要存到哪裡?
而是:
這句資訊值得跨 Session 保存嗎?
這就是 Selection。
Selection 決定什麼資訊值得進入 Memory。
可以從幾個維度判斷。
這個資訊多久後還可能有效?
例如:
今天下午三點開會
→ 很快過期
這個 Repository 使用 Python 3.12
→ 可能長期有效
未來類似任務是否會再次需要?
例如:
這次測試失敗的 Temporary Path
→ 可能不值得保存
這個專案的測試指令
→ 很可能會再次使用
資訊是否足夠明確?
例如:
使用者喜歡好的回答。
沒有什麼用。
但:
使用者偏好技術內容先給結論,再解釋架構。
比較可操作。
這個資訊是事實,還是推測?
Agent 不應該因為一次互動就寫入:
使用者不喜歡 Kubernetes。
如果只是一次抱怨,可能只是當下情境。
這個資訊是否根本不應該被長期保存?
Memory Selection 不只是 Utility Filter。
也需要 Privacy 與 Policy Boundary。
不是所有訊息都直接進 Memory Store。
先經過 Memory Gate。
新的資訊
↓
是否具有長期價值?
├── No → 不保存
└── Yes
↓
是否足夠具體?
├── No → 不保存或等待更多證據
└── Yes
↓
是否允許保存?
├── No → 丟棄
└── Yes → Extraction
這個 Gate 可以由:
共同完成。
例如非常明確的系統規則可以直接用程式判斷。
模糊的自然語言偏好,可以讓模型協助分類。
Selection 決定:
值不值得記?
Extraction 決定:
到底要記成什麼?
這兩件事不一樣。
假設原始對話是:
我不太喜歡上次那種很學術的寫法,之後 LinkedIn 可以更直接一點,最好開頭先有一個比較反直覺的觀點。
不應該直接把整段 Conversation 永久存成 Memory。
更好的 Extraction 是:
Preference:
LinkedIn 技術貼文優先使用直接、反直覺的 Hook,
避免過度學術語氣。
這樣 Memory 比較:
Extraction 是把 Raw Experience 轉換成可重用的 Memory Unit。
一個 Memory 不一定只有一句文字。
可以包含:
真正要記住的內容。
例如:
適用在哪裡?
例如:
有多確定?
來自哪一次 Interaction?
什麼時候建立?
最後一次確認是什麼時候?
是否會過期?
這些 Metadata 會影響 Recall 與 Consolidation。
把完整聊天紀錄丟進 Vector Database 很方便。
但 Raw Conversation 有很多雜訊。
例如:
如果全部索引,下次 Retrieval 很容易召回:
曾經說過,但現在已經不對的資訊。
所以 Memory 不應該只是 Conversation Archive。
Archive 可以存在。
Memory 則應該是從 Archive 中抽出的長期訊號。
有 Memory Store 之後,下一個問題是:
什麼時候應該把 Memory 放回 Context?
這就是 Recall。
最簡單的方法是:
但這樣很容易召回「語意相似,實際不相關」的內容。
例如目前任務是:
幫我寫一篇 LinkedIn 貼文。
Vector Search 可能找回:
使用者之前寫過 LinkedIn Recruiter Message。
兩者都跟 LinkedIn 有關。
但任務完全不同。
所以 Recall 不應該只依賴 Semantic Similarity。
可以把 Recall 想成 Ranking:
Candidate Memories
↓
Scope Filter
↓
Freshness Filter
↓
Relevance Ranking
↓
Conflict Resolution
↓
Top Memories
↓
Inject into Context
這比單純 Top-K Vector Search 更可靠。
Memory Retrieval 最常見的錯誤是:
多找一些比較安全。
但 Memory 和 Context 一樣有 Attention Cost。
如果每次都塞入 20 個 Memories:
所以 Recall 最好追求:
最少但足夠。
不是:
越多越完整。
不要只是把所有 Memory 丟到 Prompt 最後。
最好有明確區域。
例如:
Relevant memory:
Project facts:
- Python 3.12
- Tests use pytest
User preferences:
- Prefer concise technical explanations
Constraints:
- Never deploy directly to Production
Past failure patterns:
- Integration tests often fail because of missing env vars
分類有助於模型理解:
這些不是這一輪新產生的 Observation,而是長期保存的背景資訊。
該記得的沒有被叫回來。
例如使用者明明有長期格式偏好,系統卻每次都重新問。
叫回太多不需要的東西。
例如每次寫文章都帶入大量舊專案細節。
兩種都會降低體驗。
所以 Memory Evaluation 不只看:
有沒有 Recall 到正確 Memory?
還要看:
有沒有避免 Recall 不相關 Memory?
Memory 不應該只會一直增加。
隨著時間過去,Memory Store 會出現:
這時就需要 Consolidation。
例如原本有三筆:
User prefers concise answers.
User prefers concise technical answers.
User prefers concise technical posts with a strong opening.
可以合併成:
User prefers concise technical writing with a strong opening.
這樣 Recall 更乾淨。
Consolidation 可以做幾件事:
Memory Store 如果沒有 Consolidation,最後會變成另一個 Context Landfill。
假設舊 Memory 是:
使用者偏好詳細回答。
新的 Interaction 是:
之後請盡量簡短。
哪一個應該優先?
最簡單的方法是:
新的永遠覆蓋舊的。
但也不一定正確。
因為新的要求可能只適用當前任務。
所以 Conflict Resolution 要考慮:
例如:
"這次回答簡短一點"
Scope: Current Task
"之後技術問題都盡量簡短"
Scope: Persistent
Scope 比單純時間更重要。
Agent Memory 有一個危險特性:
錯誤會跨 Session 傳播。
如果模型錯誤抽取:
這個專案使用 PostgreSQL。
但實際上專案已經改成 MySQL。
未來每次 Recall 都可能讓模型在錯誤前提下工作。
所以高影響 Memory 應該可以被重新驗證。
例如 Project Fact 可以有:
Source:
pyproject.toml
Last Verified:
2026-08-07
下次 Repository 明顯更新後,可以重新確認。
當 Agent 因為 Memory 做出某個決定時,我們應該能回答:
同樣地,寫入 Memory 時也應記錄:
否則 Memory 系統很難 Debug。
Knowledge Base 通常保存的是外部知識。
例如:
Memory 通常保存的是:
兩者都可以使用 Retrieval。
但來源、更新方式與信任程度不同。
不要因為底層都使用 Vector Search,就把它們視為同一套東西。
Skill 是:
遇到某類任務時,應該怎麼做。
Memory 是:
過去發生過什麼,未來可能還值得知道。
例如:
Skill:
如何寫一篇高品質 LinkedIn 技術貼文
Memory:
使用者偏好 LinkedIn 開頭先提出反直覺觀點
Skill 比較像可重用 Procedure。
Memory 比較像從 Experience 中保留的 State。
Context Archive 可以保存完整 Session。
這對:
很有價值。
但 Archive 不應該自動成為 Memory。
可以把架構拆成:
Raw History
完整保存
Memory Extraction
挑出值得長期保存的部分
Memory Store
保存結構化 Memory
Recall
只取目前相關 Memory
這樣才能避免「有保存」和「值得記住」混在一起。
一筆 Memory 可以經過:
Observed
↓
Selected
↓
Extracted
↓
Stored
↓
Recalled
↓
Revalidated
↓
Merged / Updated / Expired
這和 Context Lifecycle 很像。
差別是 Memory 的時間跨度更長。
常見類型包括:
例如:
例如:
例如:
例如:
例如:
例如:
但每一類都需要 Scope 與有效期限。
例如:
Memory 的品質往往取決於:
你敢不敢不存。
Memory 系統不應該只用幾個 Demo 感覺「它好像記得」。
可以分成幾個指標:
這些指標比單純「有沒有 Vector Database」更能反映 Memory 品質。
不一定。
每輪都跑 Memory Extraction 會增加:
可以採取:
每輪檢查。
適合高價值互動,但成本較高。
任務結束後集中抽取。
通常更有效率。
只有出現特定事件才抽取。
例如:
Event-triggered 往往比較容易控制。
Memory 是背景。
它不應該覆蓋更高優先級資訊。
例如:
Memory:
使用者通常喜歡詳細回答
Current User Request:
這次請一句話回答
這次應該一句話。
Priority 可以理解成:
Current explicit instruction
>
Current task constraint
>
Verified project state
>
Relevant memory
>
General preference
Memory 不是命令。
它只是輔助目前決策的背景。
Memory Store 最後變成 Conversation Dump。
不知道是「不值得記」還是「抽取失敗」。
相似不代表適用。
Memory 重新變成 Context Pollution。
重複、衝突與過期資訊越來越多。
沒有考慮 Scope。
錯誤會跨 Session 傳播。
背景資訊不應該壓過當前明確需求。
可以先只保存三類:
每一筆至少包含:
Recall 時先做:
然後定期 Consolidate:
這已經比「整段 Conversation 全部 Embedding」可靠很多。
Day 9 我們管理同一個任務中的 Working Context。
今天加入跨 Session 的 Memory Lifecycle:
因此,Agent 不再只是「把過去找回來」。
它開始回答更重要的問題:
哪些過去,真的值得影響未來?
Memory 的核心不是 Storage。
也不是 Vector Database。
真正的 Memory System 至少需要:
最重要的原則是:
好的 Memory 不只是記得更多,而是只讓值得記住的事情繼續影響未來。
下一篇會進入 System Prompt Assembly:
System Prompt 真的應該是一大段固定文字嗎?還是應該根據任務、工具、Permission、Skill 與 Memory 動態組裝?
完整系列與範例收錄於:https://github.com/hardness1020/awesome-agent-architecture