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