/always-on-agent-architecture — 建構永不遺忘的代理
您正在為一個具有情節記憶(Episodic Memory)的永遠在線 AI 代理設計架構。這不是一個擁有長上下文視窗的聊天機器人。這是一個能在會話之間持久化狀態、管理自身記憶體階層、以服務形式運行,並在數週乃至數月內維持身份的系統。核心見解:將 LLM 視為一個操作受管理記憶體的 CPU,而不是一個無狀態函數。
決策點
記憶框架選擇樹
Q1: 您是否需要完整的代理運行時(伺服器、API、工具)?
├─ 是 → 使用 Letta(最完整、生產就緒)
└─ 否,我有自己的代理循環
├─ Q2: 您是否需要時間/關係追蹤?
│ ├─ 是 → 使用 Zep/Graphiti(最佳的時序知識圖譜)
│ └─ 否 → 前往 Q3
│ ├─ Q3: 您是否需要圖譜 + 向量混合?
│ │ ├─ 是 → 使用 Mem0(圖譜模式)
│ │ └─ 否 → 前往 Q4
│ │ ├─ Q4: 已經在使用 LangGraph?
│ │ │ ├─ 是 → 使用 LangMem
│ │ │ └─ 否 → 使用 pgvector 或 Chroma
└─ 想要零依賴? → 自訂 SQLite + 本地嵌入
核心記憶驅逐觸發條件
| 觸發條件 | 臨界值 | 動作 |
|---|---|---|
| 大小溢位 | 核心記憶 > 4KB | 總結最近最少使用的區塊,將摘要移至歸檔 |
| 時間衰減 | 資料未使用 > 30 天 | 標記為壓縮審查 |
| 相關性下降 | 存取分數 < 0.3 | 以衰減標籤移至歸檔記憶 |
| 使用者覆寫 | 使用者說「忘記 X」 | 立即移除並加入歸檔墓碑(Tombstone) |
| 衝突偵測 | 儲存矛盾事實 | 提示代理進行調和或詢問使用者 |
向量資料庫選擇標準
如果 query_latency_requirement < 10ms 且 data_size > 100M 個向量:
→ 使用 Qdrant(針對速度最佳化)
否則如果 already_using_postgresql:
→ 使用 pgvector(單一資料庫,運維更簡單)
否則如果 need_hybrid_search(關鍵字 + 語義):
→ 使用 Weaviate(最佳混合搜尋)
否則如果 zero_ops_preferred:
→ 使用 Pinecone(完全託管)
否則:
→ 使用 Chroma(本地優先,API 簡單)
記憶層級路由決策
輸入:使用者訊息或代理觀察結果
│
├─ 包含身份/偏好更新?
│ └─ 是 → 更新核心記憶,立即持久化
├─ 需要對話上下文?
│ └─ 是 → 搜尋回想記憶(對話歷史)
├─ 需要事實性知識?
│ └─ 是 → 搜尋歸檔記憶(向量儲存)
└─ 需要外部資料?
└─ 是 → 使用外部工具(API、檔案等)
故障模式
記憶損毀串聯(Memory Corruption Cascade)
徵狀: 代理人格漂移、回應矛盾、核心記憶衝突 根本原因: 對核心記憶進行無鎖定的並發寫入,或部分更新失敗 偵測規則: 如果核心記憶大小突然下降 >50% 或包含格式錯誤的 JSON/YAML 恢復程序:
- 立即停止代理以防止進一步損毀
- 從最後已知的良好備份(< 1 小時)恢復核心記憶
- 重播自備份以來的對話日誌,重建遺失的更新
- 在重新啟動前,對核心記憶更新實施寫入鎖定
向量搜尋退化(Vector Search Degradation)
徵狀: 搜尋結果越來越不相關,代理無法找到最近儲存的事實 根本原因: 嵌入模型漂移、索引損毀或未進行記憶壓縮 偵測規則: 若已知查詢的 top-3 結果平均餘弦相似度 < 0.7 恢復程序:
- 對隨機取樣的 100 個向量執行嵌入一致性檢查
- 如果 >10% 顯示異常嵌入,則重建整個索引
- 實施嵌入模型版本固定
- 加入嵌入漂移監控以防止復發
持續性層死結(Persistence Layer Deadlock)
徵狀: 代理在記憶體操作時掛起,資料庫連線逾時 根本原因: 同時對相同記憶區塊進行讀/寫,連線池不足 偵測規則: 如果記憶體操作耗時 >30 秒或資料庫出現鎖等待超時 恢復程序:
- 終止掛起的連線以釋放鎖
- 為記憶體操作實施指數退避重試邏輯
- 加入最大連線數限制的連線池
- 檢視記憶體更新的事務隔離級別
上下文視窗爆炸(Context Window Explosion)
徵狀: API 成本飆升、回應延遲增加、Token 限制錯誤 根本原因: 核心記憶體膨脹,每次查詢擷取太多歸檔區塊 偵測規則: 如果每個請求的平均 Token 數超過模型上下文限制的 80% 恢復程序:
- 審計核心記憶體大小 - 壓縮或歸檔過大的區塊
- 將歸檔搜尋結果的預設數量從 10 減少到 5
- 在 LLM 呼叫前實施 Token 計數
- 為 >$1/次對話的成本監控加入警報
記憶洩漏 - 無界增長(Memory Leak - Unbounded Growth)
徵狀: 資料庫大小線性增長,搜尋效能隨時間下降 根本原因: 未進行記憶壓縮、重複的事實插入、缺少垃圾回收 偵測規則: 如果正常使用下,總記憶體大小每月增長 >100MB 恢復程序:
- 對歸檔記憶執行事實去重(餘弦相似度 > 0.92)
- 對超過 7 天的回想記憶實施對話摘要
- 加入相關性評分,並自動修剪低分記憶
- 安排每週壓縮任務
實例
範例:建構個人研究助理
場景: 為一個協助技術研究、記住您的偏好、並在數月內積累知識的代理設計架構。
步驟 1 - 記憶層級設計
核心記憶 (2KB):
- 使用者名稱:"Sarah"
- 研究領域:["機器學習", "分散式系統"]
- 偏好的論文來源:["arxiv", "acm digital library"]
- 寫作風格:"帶有程式碼範例的詳細說明"
- 當前項目:"分散式訓練最佳化"
回想記憶:
- 所有對話儲存在 PostgreSQL 並啟用全文搜尋
- 30 天保留窗口,之後進行摘要
歸檔記憶:
- 論文摘要、提煉的見解、程式碼片段
- 在 PostgreSQL 上使用 pgvector(已用於回想)
- 使用 nomic-embed-text 進行本地嵌入(隱私 + 成本)
步驟 2 - 框架選擇決策 依照決策樹:
- 需要完整的代理運行時?否(建構自訂的)
- 需要時間追蹤?否(研究事實大多是永恆的)
- 需要圖譜+向量?否(簡單的語義搜尋已足夠)
- 已經在用 LangGraph?否
- → 決定:pgvector + PostgreSQL
步驟 3 - 代理循環實作
async def research_step(user_query: str):
# 載入核心記憶
core = load_core_memory() # 使用者偏好、活躍項目
# 檢查查詢是否與當前項目相關
if "最佳化" in user_query.lower():
# 搜尋歸檔中與項目相關的知識
relevant_papers = search_archival("分散式訓練最佳化")
context = f"當前項目上下文:{relevant_papers}"
else:
# 搜尋一般領域知識
context = search_archival(user_query)
# 建構包含核心記憶 + 檢索上下文的提示
system_prompt = f"""
你是 Sarah 的研究助理。
使用者偏好:{core['preferences']}
當前項目:{core['current_project']}
檢索到的上下文:{context}
"""
response = await llm.chat([
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_query}
])
# 持久化互動
save_to_recall(user_query, response)
return response
新手容易忽略的點:
- 在歸檔中儲存原始論文而非提煉的見解
- 未實作對話搜尋(回想記憶)
- 在核心記憶中放入過多內容(包含 50 個條目的研究領域列表)
- 沒有記憶壓縮策略
專家會注意到的點:
- 核心記憶應專注於「工作中的身份」而非知識本身
- 歸檔記憶儲存策劃過的事實,而非原始文件
- 在檢索前先進行搜尋(由代理決定相關性)
- 從第一天起就規劃記憶體增長
品質閘門
部署驗證檢查清單
- 記憶體延遲 SLO: 核心記憶載入 <100ms,歸檔搜尋完成 <500ms
- 記憶體一致性: 代理重啟後核心記憶無損毀(透過刻意殺死程序來測試)
- 搜尋相關性: 對於已知查詢,前 3 個歸檔結果的餘弦相似度 >0.6
- 記憶體大小規則: 核心記憶 ≤4KB,回想記憶保留 ≤30 天,歸檔區塊每個 ≤1KB
- 持續性耐久性: 所有記憶更新在資料庫重啟後仍能存活(經驗證符合 ACID)
- 成本控制: 每日 100 次對話下,每次對話的記憶體操作成本 <$0.01
- 壓縮排程: 記憶壓縮每週執行,並將總大小減少 ≥10%
- 身份一致性: 代理人格在 50+ 次對話會話中維持穩定
- 冷啟動恢復: 代理能優雅地處理空的記憶狀態(入職流程正常運作)
- 備份驗證: 記憶備份能成功恢復並保留代理身份
非適用邊界
請勿將此技能用於:
- 選擇代理訓練資料 → 請改用
/always-on-agent-inputs- 該技能涵蓋應提供哪些資料給代理,本技能則涵蓋如何儲存與檢索 - 發想代理應用 → 請改用
/always-on-agent-applications- 該技能涵蓋使用案例發想,本技能涵蓋技術實作 - 代理安全與隱私 → 請改用
/always-on-agent-safety- 該技能涵蓋資料治理、同意與安全;本技能假定這些已設計完成 - 通用代理模式 → 請改用
/agentic-patterns- 該技能涵蓋 ReAct 循環、工具使用、規劃;本技能涵蓋底層的持續性層 - 一次性代理任務 → 請改用
/agent-creator- 如果代理不需要跨會話記憶,則不需要永遠在線的架構 - 資料庫綱要設計 → 本技能假定您了解基本的資料庫概念;綱要最佳化請使用特定資料庫的相關技能
- 成本最佳化策略 → 本技能提及成本考量但未深入探討最佳化;請委由成本相關技能處理