
多 Agent 系統在實際項目中越拆越細很快會遇到一個比“工具調用失敗”更隱蔽的問題每個 Agent 各記各的上下文片段互相割裂A 會話里確認過的用戶偏好B 會話又重新問一遍甚至同一個 Agent 重啟之后就把關鍵業務約束忘干凈。MemOS 團隊開源的 Memmy瞄準的正是這個痛點用統一記憶層把多個 Agent 的記憶收斂到一起讓記憶像數據庫一樣可寫、可查、可共享。這篇文章會從多 Agent 記憶為什么難入手講清楚 Memmy 的核心設計思路、本地部署方式、關鍵 API 用法、接入多 Agent 框架時的數據模型設計以及生產環境必須考慮的隔離、權限和過期策略。讀完可以在自己的項目中把“記憶”從零散的上下文補丁升級成一個獨立基礎設施。1. 先理解多 Agent 記憶為什么不能靠改 prompt 解決很多團隊剛接觸多 Agent 開發時記憶方案很樸素把歷史對話塞進 system prompt或者把上一輪輸出拼到下一輪輸入里。這種做法在 demo 階段夠用一旦 Agent 數量超過三個、任務鏈變長問題就會集中爆發。1.1 多 Agent 場景下記憶到底指什么Agent 記憶可以從兩個維度拆開看。第一個維度是時間范圍短期記憶對應當前會話內的上下文比如用戶剛提交的需求、上一步工具返回的結果長期記憶對應跨會話的穩定信息比如用戶的偏好、項目的約束、歷史決策記錄。第二個維度是歸屬主體單個 Agent 自己維護的私有記憶以及多個 Agent 需要共享的公共記憶。把這兩個維度交叉就能看到一張矩陣記憶類型時間范圍歸屬典型內容失效風險會話上下文短期單個 Agent當前任務輸入、中間結果會話結束即丟失工作記憶短期多個 Agent任務鏈中的共享結果任務鏈中斷后丟失長期偏好長期單個用戶/項目用戶習慣、風格偏好缺少持久化組織知識長期多個 Agent業務規則、歷史決策難以檢索和更新如果只把記憶塞進 prompt本質上是在模擬短期記憶長期記憶和共享記憶完全沒有落地。多 Agent 協同的時候A Agent 寫入的重要結論無法讓 B Agent 感知整個系統就退化成多個獨立助手而不是一個協作團隊。1.2 prompt 拼接方案的四個典型瓶頸直接在 prompt 中堆歷史記錄至少會遇到四個問題。第一是上下文窗口壓力。一份完整業務歷史可能有幾萬 token塞進 prompt 后留給推理和工具調用的空間被嚴重壓縮Agent 的理解質量會明顯下降。第二是信息新鮮度無法保證。如果 Agent 每次啟動都重新從日志、數據庫或者用戶輸入里拼記憶那么記憶更新就是一個完全靠開發者手動維護的流程很容易漏。用戶昨天變更了偏好今天的 Agent 可能還在用舊信息。第三是檢索能力缺失。prompt 里的記憶是線性文本當記憶量變大之后無法回答“這條規則是在哪個項目里定的”“上個月我們為什么選擇這個方案”這類精確查詢。普通文本只能順序讀取不能按標簽、時間、實體關系過濾。第四是權限和隔離沒法做。所有內容拼進同一個 promptAgent A 能看到 Agent B 的私有信息業務上不允許的跨域數據訪問在 prompt 拼接體系里根本攔不住。1.3 Memmy 的核心思路把記憶當成獨立服務Memmy 的出發點是Agent 的記憶不應該藏在大模型上下文里而應該被建模成一個帶語義索引的存儲層。每個 Agent 通過統一接口寫入記憶、查詢記憶、訂閱記憶變更底層由 Memmy 完成向量化、結構化存儲和相關性檢索。這個思路和人類記憶系統很像。人類不會在每次對話時把一生經歷都讀一遍而是根據當前問題從記憶里提取和任務相關的片段。多 Agent 系統也需要這種機制每次運行只加載相關記憶而不是加載全部歷史和全部上下文。用這種設計Agent 的 prompt 可以變得很干凈只包含當前任務指令和檢索到的相關記憶片段。記憶的寫入、更新、刪除、過期都變成對 Memmy 服務的標準操作而不是散落在各個 Agent 代碼里的字符串拼接邏輯。2. 部署 Memmy 之前需要對齊的環境與概念Memmy 作為基礎設施型組件部署方式和單體應用不同。在動手之前最好先把環境要求、核心數據模型和部署架構理解到位否則后面接入 Agent 時會反復返工。2.1 本地環境與最低依賴Memmy 本身是一個服務端應用對外提供 HTTP API底層存儲負責持久化。結合目前多 Agent 開發常見的部署形態建議按以下環境準備依賴項推薦配置說明操作系統Linux / macOSWindows 也可以但容器部署更方便Docker20.10 以上本地快速啟動依賴容器內存8 GB 以上向量索引和并發請求都需要內存存儲引擎PostgreSQL / SQLite生產用 PostgreSQL本地實驗可用 SQLite向量能力pgvector / 內置向量索引用于語義檢索Embedding 模型本地模型或 API 模型需要把文本轉成向量需要注意這里給的是通用依賴范圍。原始項目文檔如果沒有明確版本號落地時先執行docker compose pull觀察鏡像版本再根據自己項目的模型選型決定 Embedding 來源。推薦先跑一個最小容器實例不要一上來就接生產配置。學習階段只要能確認 API 能起來、寫入一條記憶、查詢到這條記憶就算環境合格。2.2 記憶單元的結構設計Memmy 處理的基本單位是一條記憶記錄。每條記錄通常包含以下字段字段作用示例id全局唯一標識mem_8f3a2cagent_id記憶所屬 Agentagent_orderuser_id記憶所屬用戶或項目user_1001content記憶正文用戶偏好控制臺風格界面metadata結構化標簽{project:consolev2,level:preference}timestamp記憶產生時間2025-01-12T10:30:00Zsource記憶來源conversation / manual / system這個結構解決了一個關鍵問題記憶不只是文本而是帶歸屬、帶來源、帶業務標簽的數據。這樣后續做權限過濾、時間過濾、標簽過濾時不需要再對純文本做解析。2.3 理解寫入、檢索與遺忘三條鏈路Memmy 提供的核心能力可以歸納成三條鏈路。寫入鏈路負責把 Agent 產生的記憶持久化。調用方提交記憶內容、歸屬主體和元數據Memmy 對內容做向量化將原始文本、元數據和向量一并存儲。檢索鏈路負責根據當前問題召回相關記憶。調用方提交一個查詢文本Memmy 把查詢轉成向量在向量索引中做相似度搜索同時按照元數據過濾條件縮小范圍最后返回排序后的記憶列表。遺忘鏈路負責控制記憶生命周期。開發者可以設置過期時間也可以主動刪除不再需要的記憶記錄。這個鏈路很容易被忽略但長期運行的系統如果只寫不退記憶庫會迅速膨脹檢索質量和存儲成本都會惡化。三條鏈路對應三個基礎 APIPOST /memories、GET /memories/search、DELETE /memories/{id}。后面的接入實驗會圍繞這三個接口展開。3. 用容器啟動 Memmy 并跑通基礎 API這一節進入實操。目標是本地啟動 Memmy 服務寫入一條測試記憶再通過檢索接口查回這條記憶。所有示例以通用 HTTP API 為例實際路徑和請求體格式以項目 README 和接口文檔為準。3.1 容器編排示例先創建一個最小化的docker-compose.yml把 Memmy 服務和底層存儲一起啟動。這里使用 PostgreSQL 和 pgvector 作為示例因為生產場景最常見。version: 3.9 services: memmy: image: memos/memmy:latest container_name: memmy ports: - 8000:8000 environment: MEMORY_STORAGE: postgres DATABASE_URL: postgresql://memmy:memmypostgres:5432/memmy EMBEDDING_PROVIDER: local EMBEDDING_MODEL: bge-small-zh depends_on: - postgres postgres: image: pgvector/pgvector:pg16 container_name: memmy-postgres environment: POSTGRES_USER: memmy POSTGRES_PASSWORD: memmy POSTGRES_DB: memmy ports: - 5432:5432 volumes: - memmy_pgdata:/var/lib/postgresql/data volumes: memmy_pgdata:使用本地 Embedding 模型的好處是請求不依賴外部 API數據不出內網但鏡像體積和內存占用會更大。如果使用云端 Embedding API則需要在環境變量中配置 API Key這屬于生產環境要考慮的密鑰管理問題。啟動命令docker compose up -d docker compose ps看到memmy和postgres兩個服務都是 healthy 或 running 狀態后再檢查 API 是否可訪問curl http://localhost:8000/health正常響應會返回一段 JSON包含服務狀態、版本號和存儲引擎信息。這一步能確認服務進程起來了但還不能確認記憶讀寫鏈路正常所以還需要做一次基礎寫入。3.2 寫入一條帶元數據的記憶假設業務系統里有兩個 Agent一個是客服助手一個是訂單助手。客服助手發現用戶偏好短信通知這個信息需要寫入公共記憶供訂單助手在發送通知時使用。向 Memmy 寫入記憶的請求體可以是{ agent_id: agent_support, user_id: user_1001, content: 用戶偏好使用短信接收訂單狀態通知不偏好郵件通知。, metadata: { project: order_service, memory_type: preference, level: user }, ttl: 2592000 }ttl字段單位是秒這里設置 30 天過期。對于偏好類記憶過期時間要結合實際業務判斷如果希望長期有效可以不設置 ttl 或設置更長時間。調用接口curl -X POST http://localhost:8000/memories \ -H Content-Type: application/json \ -d { agent_id: agent_support, user_id: user_1001, content: 用戶偏好使用短信接收訂單狀態通知不偏好郵件通知。, metadata: { project: order_service, memory_type: preference, level: user }, ttl: 2592000 }正常響應會返回記憶記錄 id。如果返回 400 或者 422優先檢查字段名和類型是否和文檔一致尤其是metadata是否只允許扁平結構。3.3 按語義檢索相關記憶訂單助手在處理發通知請求時需要知道用戶的通知偏好。此時檢索查詢應該是自然語言問題而不是精確 SQLcurl -X GET http://localhost:8000/memories/search?query用戶希望如何接收訂單通知user_iduser_1001limit5返回結果通常包含記憶正文、相關度分數、元數據和寫入時間{ results: [ { id: mem_8f3a2c, content: 用戶偏好使用短信接收訂單狀態通知不偏好郵件通知。, score: 0.93, metadata: { project: order_service, memory_type: preference, level: user }, created_at: 2025-01-12T10:30:00Z } ] }通過user_id做過濾能避免把 A 用戶的偏好召回給 B 用戶這是多租戶場景最基本的隔離手段。相關度分數用于排序但生產環境不能只看分數還要結合元數據里的業務條件做二次過濾。3.4 檢查點與常見失敗現象實驗跑通后用三個檢查點確認鏈路完整檢查點操作預期結果服務健康curl /health返回 200 和狀態 JSON寫入成功POST /memories返回記憶 id檢索命中GET /memories/search返回包含該記憶的列表常見失敗現象有三種。第一種是寫入成功但檢索不到通常是因為 Embedding 模型沒有正確加載索引需要看服務日志里是否出現向量維度不一致的報錯。第二種是檢索結果相關度極低先確認查詢文本和記憶正文語言是否一致混合語言場景下向量檢索效果會明顯下降。第三種是user_id過濾不生效一般是傳入參數名和后端字段名不一致檢查 API 文檔確認是user_id還是userId。4. 把 Memmy 接入多 Agent 框架時如何設計數據流多 Agent 框架通常自帶上下文傳遞機制比如任務鏈中的state對象、消息總線、或者是工具調用上下文。接入 Memmy 之后關鍵不是新增一個 HTTP 調用而是重新設計記憶的讀寫時機。4.1 記憶讀取插在 Agent 執行鏈的哪個位置推薦在 Agent 拿到用戶輸入之后、構造大模型 prompt 之前增加一個記憶檢索步驟。偽代碼如下def build_prompt_with_memory(user_input, user_id, agent_id): # 1. 從 Memmy 檢索和當前輸入相關的記憶 memories memmy_client.search( queryuser_input, user_iduser_id, agent_idagent_id, limit8 ) # 2. 將記憶格式化為上下文片段 memory_context format_memories(memories) # 3. 組裝 prompt prompt f 以下是和當前任務相關的歷史記憶 {memory_context} 當前用戶輸入 {user_input} 請結合記憶回答用戶問題。 return prompt這里的核心原則是記憶檢索發生在 prompt 構造之前只加載相關片段不加載全部記憶。這樣可以控制 token 長度也能保證 Agent 只基于當前任務相關的信息做決策。4.2 記憶寫入要區分穩定信息與臨時狀態不是所有對話內容都值得寫入長期記憶。寫多了會讓記憶庫充滿噪聲檢索質量下降寫少了又丟失有價值的信息。推薦按照以下標準判斷信息類型是否寫入原因用戶明確表達的偏好寫入跨會話穩定業務規則確認寫入后續 Agent 需要遵守任務中間結果視情況寫入短鏈任務可以不寫大模型生成的泛化建議不寫噪聲太多一次性的臨時參數不寫無復用價值寫入動作建議放在 Agent 執行完成并且確認結果成功之后而不是每生成一句話就寫一次。批量寫入或者定時總結式寫入在真實項目中比實時逐條寫入更穩定。4.3 用 metadata 控制共享邊界Memmy 的一個關鍵能力是通過元數據控制記憶的可見范圍。多 Agent 場景里至少要建立如下幾類隔離維度metadata 鍵作用示例scope記憶層級global/project/userproject項目歸屬order_serviceagent_id允許讀取的 Agentagent_ordermemory_type記憶類型preference/rule/decision檢索時把當前 Agent 的上下文條件傳進去就能實現類似數據庫行級權限的效果。比如訂單 Agent 只能檢索projectorder_service且scope不包含private的記憶客服 Agent 同理。這樣設計之后多個 Agent 共享的是公共記憶私有記憶仍然隔離在各自的命名空間里。相比把所有記憶都暴露給所有 Agent 的方式這種方式更適合業務系統落地。4.4 訂閱與事件通知的擴展用法有些場景下Agent 需要感知記憶變化。比如用戶修改偏好后正在執行的訂單流程需要立刻使用新偏好而不是等下一次檢索才生效。Memmy 若提供事件訂閱能力可以在記憶寫入或更新時觸發回調。接入模式類似消息隊列memmy_client.subscribe( event_typememory.updated, user_iduser_1001, callbackhandle_memory_updated ) def handle_memory_updated(event): # 更新本地 Agent 緩存或重新執行任務 refresh_context(event.memory_id)這種設計能減少重復輪詢適合對時效性要求高的流程。學習階段可以先不接訂閱理解檢索和寫入兩個核心鏈路即可。5. 生產環境落地 Memmy 必須處理的六個問題從本地跑通到生產可用中間還隔著一段很長的工程距離。下面六類問題是多 Agent 系統接記憶服務時最容易踩坑的地方。5.1 向量檢索與業務過濾的順序默認情況下Memmy 先做向量相似度召回再根據元數據過濾。這種順序的問題是如果某個用戶的歷史記憶非常多而相關性排序又優先業務過濾就可能在后面裁掉高相關但權限不符的結果。推薦做法是在建立索引時就設計好分區鍵把user_id、project_id這類租戶字段作為固定過濾條件而不是只放在 metadata 里。這樣數據庫能先縮小檢索范圍再在范圍內做排序既提升性能也增強隔離。5.2 Embedding 模型選擇與維度兼容本地模型和云端模型各有取舍。本地模型的數據私密性好但效果需要自己評估云端模型效果通常更穩定但存在調用成本和網絡延遲。重要風險點如果后期更換 Embedding 模型新模型生成的向量維度可能和舊向量不一致。這會導致檢索接口報向量維度錯誤或更隱蔽的相似度失真問題。切換模型前必須做數據遷移或全量重建索引。5.3 記憶過期和歸約策略一味增加 ttl 不是好方案。記憶庫中大量重復、過期、沖突的記錄會讓檢索召回結果變差。生產環境建議增加三層策略寫入時去重先按user_id和metadata.memory_type查一次如果已有相同內容做更新而不是新增。定期歸約把多條相似記憶合并成一條總結性記憶。過期清理對超過 ttl 且不再訪問的記錄用離線任務批量刪除或歸檔。5.4 權限與安全邊界Memmy 服務本身如果暴露到內網接口鑒權不能只依賴網絡策略。推薦在 Gateway 層增加 token 校驗每個 Agent 使用獨立 API KeyMemmy 側根據調用方身份限制可寫入和可讀取的范圍。場景風險建議不加鑒權直接訪問任意 Agent 可讀寫所有記憶至少加 Bearer Token共享同一個 key無法追溯數據來源每個 Agent 獨立 key明文存儲敏感信息記憶中的個人信息泄露加密存儲或脫敏5.5 高可用與降級Memmy 一旦成為 Agent 系統的一部分它的故障會影響整個 Agent 鏈路。生產環境要考慮降級方案Memmy 不可用時Agent 可以退化為只使用當前 prompt 內的上下文并記錄一條告警日志而不是直接拋異常終止流程。try: memories memmy_client.search(...) except MemmyUnavailableError: logger.warning(memmy unavailable, fallback to empty memory) memories []這樣的降級邏輯能保證核心業務不被記憶服務拖垮。5.6 記憶一致性與多副本沖突如果 Memmy 多副本部署需要確認寫入是強一致還是最終一致。多 Agent 并發寫入同一條記憶時要定義沖突策略。最簡單的方式是使用更新時間戳后寫入覆蓋先寫入更可靠的方案是增加版本號寫入時攜帶版本版本不匹配則重試或合并。6. 從 Memmy 延伸到多 Agent 記憶體系的四種架構形態Memmy 可以獨立使用也可以作為多 Agent 系統記憶層的核心組件。根據項目規模可以把架構分成四種形態。6.1 單體記憶庫形態所有 Agent 共用同一個 Memmy 實例通過agent_id和metadata區分歸屬。適合中小型項目Agent 數量在十個以內業務隔離要求不高。優點是運維簡單缺點是一旦一個 Agent 寫入大量低質量記憶會影響所有 Agent 的檢索效果。6.2 按服務分庫形態每個業務域部署獨立的 Memmy 實例比如訂單域一套、客服域一套。適合業務邊界清晰、數據不允許跨域訪問的場景。優點是故障隔離好缺點是跨域記憶共享需要另外開發同步機制。6.3 中央庫加邊緣緩存形態Memmy 作為中央記憶服務每個 Agent 節點本地維護一個高頻緩存定期從中央庫拉取相關記憶。適合 Agent 分布式部署、對延遲敏感的場景。緩存命中時不走網絡大幅降低檢索延遲緩存失效時回源查詢。6.4 記憶分層形態在 Memmy 之上再做一層記憶管理層把短期記憶、工作記憶、長期記憶分開存儲。比如短期記憶用 Redis長期記憶用 Memmy通過上層調度器判斷當前任務需要哪一層記憶。這種形態適合復雜的自主 Agent 系統工程成本也最高。下表總結了四種形態的適用場景架構形態適用規模隔離能力運維成本推薦場景單體記憶庫小中低快速驗證、中小項目按服務分庫中高中業務邊界清晰中央庫加邊緣緩存中大中中高延遲敏感分布式部署記憶分層大高高復雜自主 Agent7. 記憶質量治理比寫入更難的三個實踐接入 Memmy 只是開始。真正讓多 Agent 系統表現出“記得住、記得準、忘得掉”的能力需要持續治理記憶質量。7.1 建立記憶審查鏈路Agent 自動寫入的記憶不能直接進入長期庫建議經過一層規則過濾或人工抽查。規則過濾可以包括長度閾值、敏感詞檢測、必填 metadata 校驗。對高價值記憶比如業務規則、用戶契約可以設置為需要人工確認后才能生效。7.2 記憶沖突檢測同一個用戶的喜好可能在不同時間發生變化舊記憶和新記憶會沖突。建議在檢索返回時帶上記憶的timestamp和version上層 Agent 結合時間信息判斷該采信哪條。更高級的做法是讓 Memmy 提供沖突檢測接口當待寫入的新記憶和已有記憶語義相近但內容矛盾時返回提示給調用方。7.3 定期評估檢索效果維護一組標準測試問題每個問題對應期望召回的記憶片段。每周跑一次檢索統計命中率變化。當命中率下降時重點檢查是否寫入了大量低質量記憶、Embedding 模型是否需要更換、metadata 過濾條件是否過寬或過窄。評估清單示例查詢“用戶期望怎么接收通知”能否召回“偏好短信通知”這條記憶。只傳入user_id時是否返回了其他用戶的數據。刪除過期記憶后檢索結果列表是否明顯變干凈。新寫入的記憶在多長時間后能被檢索到。高相關度但權限不符的記憶是否被正確過濾。8. 學習路徑與落地順序建議把 Memmy 引入項目時不要一上來就追求完整記憶體系。下面這條路徑適合大多數團隊。8.1 第一階段跑通最小閉環先部署 Memmy寫一個測試 Agent調用寫入和檢索兩個接口確認記憶能跨會話存活。這一階段只驗證基礎設施不接業務邏輯。8.2 第二階段接入真實 Agent把 Memmy 接進一個業務 Agent在 prompt 構造前增加記憶檢索在 Agent 執行完成后增加記憶寫入。重點觀察記憶寫入后是否影響后續回答質量以及在 prompt 中插入記憶后 token 消耗的變化。8.3 第三階段建立隔離和權限增加user_id、project_id過濾為每個 Agent 配置獨立憑證設計 metadata 規范。這個階段的目標是讓記憶系統具備基本的生產安全性。8.4 第四階段治理與監控引入記憶過期、歸約、沖突檢測和效果評估。這一階段的核心是建立數據治理機制讓記憶庫在長期運行中保持穩定。階段核心任務完成標志第一階段部署與接口驗證寫入并檢索成功第二階段接入真實 AgentAgent 能使用歷史記憶第三階段隔離與權限多租戶數據互不可見第四階段治理與監控記憶庫長期運行質量可控9. 關于 Memmy 的幾個常見理解誤區最后梳理幾個容易誤解的點幫助你把概念搞清楚。誤區一Memmy 是一個通用數據庫。Memmy 的重點是語義檢索與記憶生命周期管理不是通用 KV 或關系庫。適合存自然語言形態的記憶片段不適合存強結構化業務表。誤區二用向量檢索就不需要元數據。向量檢索解決“語義相似”的問題元數據解決“權限和范圍”的問題。真實場景兩者缺一不可。誤區三記憶越多越好。記憶越多檢索噪聲越大存儲成本越高沖突概率也越高。記憶系統需要設計遺忘和歸約這和人類記憶的機制一致。誤區四接入 Memmy 就一定要替換現有 prompt。Memmy 是補充而不是替代。短期會話內的臨時信息仍然可以放在上下文里Memmy 負責管理需要跨會話、跨 Agent 復用的長期記憶。多 Agent 系統的成熟度很大程度取決于記憶層的成熟度。Memmy 把記憶從“prompt 里的一段文本”升級成“一個可管理的基礎設施”思路值得借鑒。實際落地時建議先跑通最小閉環再逐步加入隔離、權限、過期和治理策略讓記憶系統在業務復雜度上升的過程中始終可控。