拆解 Agent Memory:从认知心理学映射到工业级工程落地

拆解 Agent Memory:从认知心理学映射到工业级工程落地 前言大多数 Agent Memory 设计的误区是过早堆砌数据库、消息队列、向量引擎等中间件从而混淆核心业务逻辑与工程优化组件。Agent Memory 的核心不是简单的一读一写接口而是Memory Service 的 Recall/Write 两大主业务入口真正的工程复杂度在 Write 侧内部的记忆提取、验证、去重、冲突解决与生命周期治理。所有中间件只为让这两个入口更快、更准、更可靠、更易扩展。本文围绕核心本质、数据模型、生命周期、召回架构与落地路径展开。一、Agent Memory 核心本质1.1 核心运行流程一次标准 Agent 请求记忆模块只参与三个核心步骤用户请求 → ① Recall 读取记忆 → LLM/工具执行任务 → ② 完成任务 → ③ Write 写入/更新记忆 → 响应用户1.2 两大主业务入口不是全部能力Recall读取记忆检索相关历史记忆为当前任务提供上下文依据。Write写入记忆筛选本次对话有效信息并完成候选记忆的生成与写入。Write 不是单次POST /memory它内部是一条完整闭环Memory ├── Recall ← 主业务入口 └── Write ← 主业务入口 ├── Extract ├── Validate ├── Resolve ├── Dedup ├── Conflict └── Store因此不能把 Memory 理解成GET /memoryPOST /memory就完成了。PostgreSQL、Redis、Milvus、OpenSearch、Kafka、Embedding、Reranker 等组件最终都服务于这两个入口及其内部能力。1.3 Memory Service 四大能力Recall检索精准匹配、召回相关历史记忆优先级最高。Write写入生成候选记忆并完成提取、验证、去重、冲突解决与持久化。Manage管理更新、删除、冲突修复、过期清理。运维管控版本管理、权限控制、操作审计。二、各中间件核心职责各组件各司其职但不应以单一检索能力机械划分组件边界PostgreSQL 作为唯一事实源负责记忆持久化与版本治理Milvus 提供 Dense、Sparse 及 Hybrid 检索能力承担主要语义与混合召回Redis 负责结构化热点数据缓存OpenSearch 作为可选的专业全文检索组件在复杂关键词、全文分析及高级搜索需求出现时补强Kafka 负责写入后的异步任务与索引构建解耦。组件职责核心价值落地阶段PostgreSQL唯一事实源持久化 Memory、版本、关系、权限、审计返回 Active Version Data保证记忆数据一致性与可治理性V1 必备MilvusDense Vector / Sparse Vector 索引语义、关键词及 Hybrid Search保存 Memory ID 与检索字段统一承担主要语义/混合召回避免重复引入搜索组件V2Redis结构化热点 Memory、Preference、最近/高频访问数据缓存降低 PG 访问压力提升高频精确查询速度V2/V5OpenSearch可选的专业全文检索复杂关键词、短语、模糊、多字段、过滤、聚合等当 Milvus 的 Sparse/Hybrid Search 无法满足复杂搜索需求时补强按需 / V3Reranker对 Dense/Sparse/Keyword 等召回候选进行二次相关性判断与排序提高最终 Recall PrecisionV3KafkaWrite 后台任务、索引构建、Embedding、异步治理等事件投递解耦主链路削峰与异步处理V5LangGraph管理当前 Agent 任务 State、流程和临时上下文不负责长期 Memory 持久化区分任务状态与长期记忆始终2.8 Memory 与 RAG 的边界Memory 与 RAG 都向 Agent 提供上下文但解决的问题不同Memory 解决“过去发生过什么以及 Agent 应该长期记住什么”RAG 解决“外部知识源中有什么以及当前任务需要查什么”。二者的核心区别不是“一个是用户数据、一个是知识数据”而是信息的来源、生命周期和更新机制不同。维度Agent MemoryRAG核心问题Agent 应该记住什么外部知识库中有什么信息来源用户交互、历史任务、Agent 行为、验证经验、显式偏好文档、代码、手册、规范、数据库、网页等信息性质个性化、历史性、经验性、关系性外部知识、事实性、参考性典型内容用户偏好、项目环境、历史故障、解决经验、操作规则SDK 手册、API 文档、技术规范、项目文档生命周期动态演化、版本化、冲突治理、过期/归档随知识源更新、重新索引、删除或版本更新作用域User / Agent / Project 等Knowledge Base / Tenant / Document 等主要召回方式结构化 语义 关键词 Scope/状态过滤关键词 向量 Metadata Filter Reranker最终作用让 Agent知道过去、了解协作对象、延续经验让 Agent获取当前任务所需的外部知识例如Memory用户偏好代码示例默认使用 C20 Project Fact当前项目部署在 RK3568 Episodic上次排查 CUDA 首次 Run 约 788ms最终通过 warmup 解决 Procedural以后遇到 CUDA 首次 Run 慢先检查是否包含 CUDA Context / cuDNN 初始化并进行 warmup 验证这些信息来自 Agent 与用户/项目过去的交互并且需要长期治理因此属于Memory。RAGRK3568 官方技术手册 ONNX Runtime CUDA EP 文档 OpenHarmony API 文档 C 标准文档 项目 SDK 手册 企业技术规范这些信息来自外部知识源Agent 在当前任务中按需检索因此属于RAG。2.8.1 Memory 与 RAG 可以同时参与一次请求二者不是互斥关系而是可以共同构建 Agent ContextUser Query │ ┌──────────┴──────────┐ ↓ ↓ Memory Recall RAG Recall │ │ │ │ 用户/项目/历史/经验 文档/代码/规范/知识 │ │ └──────────┬──────────┘ ↓ Context Builder ↓ LLM例如用户问 “RK3568 上 ONNX Runtime CUDA 首次 Run 为什么慢”Memory 可以召回Episodic之前曾遇到首次 Run 约 788ms 的问题 Procedural先进行 warmup再比较后续 Run latencyRAG 可以召回ONNX Runtime CUDA EP 文档 CUDA Context 初始化相关资料 cuDNN 初始化相关资料最终 Agent 将Memory “我以前怎么处理过” RAG “外部资料怎么说明”两者结合后才能形成更完整的回答。2.8.2 一个重要边界Memory 不应该替代 RAG不能因为某次对话中 Agent 看过一份官方文档就把整个文档内容复制成 Memory。更合理的是RAG官方文档原始知识 ↓ Agent 使用 ↓ 如果产生稳定、可复用的个人/项目经验 ↓ Memory“以后遇到类似问题应该怎么处理”因此RAG 保存和检索外部知识Memory 保存 Agent 在长期交互过程中形成的个性化事实、历史经验、偏好与可复用方法。两者可以互相产生信息但数据所有权和生命周期必须保持独立。三、长期记忆四类模型当前 V1 核心模型当前平台第一版采用四类长期记忆模型。这四类不是随意分类也不是为了凑数而是认知科学理论在 AI 工程落地中的必然映射直接回答 Agent 长期记忆中最核心的四个问题Semantic世界/实体/项目/用户是什么事实与关系Preference用户希望 Agent 怎么行为偏好与约束Episodic过去具体发生过什么历史上下文与事件Procedural以后遇到类似问题该怎么做方法论与规则四类的核心价值在于数据结构、更新方式、检索方式、生命周期都不同。3.0 为什么采用四类长期 Memory理论参考与工程划分当前平台采用Semantic、Preference、Episodic、Procedural四类长期 Memory。其中Semantic 与 Episodic 属于 Tulving 多重记忆系统理论中的陈述性外显记忆Procedural 属于该框架下的非陈述性内隐记忆。而Preference 并非传统认知心理学中与前三者并列的标准记忆类型而是为表达用户/项目持续行为偏好而抽象出的工程模型。因此本系统的四类划分可以理解为认知科学提供理论参考Agent 工程需求决定最终的数据模型。四类 Memory 分别解决 Agent 长期协作中的四个核心问题Semantic “知道什么是什么有什么关系” Preference “应该按照什么方式服务这个用户/项目” Episodic “过去发生过什么” Procedural “以后遇到类似问题应该怎么做”四类并不是互斥的数据分类。同一段交互可以同时产生多个 Memory Candidate并通过memory_relations建立关联。3.0.1 四类 Memory 的工程基因四类 Memory 真正需要区分的不是名字而是数据结构、更新语义、召回条件、生命周期和治理方式不同。记忆类型核心内容数据结构倾向更新策略核心召回方式典型实现Semantic事实、实体属性、关系属性表 / 主谓宾 / 关系表Update / Versioning / AppendEntity / Attribute / Relation SemanticPostgreSQL / MilvusPreference用户/Agent/Project 的持续偏好与约束Key-Value ScopeOverride / VersioningScope Key 精确匹配PostgreSQL / Redis CacheEpisodic具体历史事件、任务经历、结果结构化 Episode SummaryAppend / Versioning / ArchiveSemantic Keyword Metadata FilterPostgreSQL / MilvusProcedural方法、规则、SOP、经验Rule / Procedure / Step / ConditionRefine / VersioningStructured Semantic Keyword / Rule MatchPostgreSQL / Milvus / Rule Engine这里的“典型实现”只是工程选择不是类型与数据库的一一绑定关系。例如 Preference 是一种 Memory 类型而 Redis 只是它的缓存实现Preference ↓ PostgreSQL ↓ Redis Cache而不是Preference Redis同样Episodic 可以使用 Milvus 做语义召回但其真实数据仍然应该由 PostgreSQL 管理。3.0.2 为什么需要四类而不是一种统一 Memory如果所有信息都简单存成{content:...,embedding:[...]}虽然可以快速实现一个向量 Memory但很难表达不同信息的不同更新语义。例如Semanticproject → deploy_to → RK3568重点是当前事实是什么。Preferencecoding.cpp_standard scope user value C20重点是作用域覆盖关系。EpisodicEpisode: 问题CUDA 首次 Run 很慢 行动增加 warmup 结果后续 Run 恢复正常重点是过去发生了什么。ProceduralProcedure: 遇到 CUDA 首次 Run 慢 ↓ 检查是否包含 CUDA Context 初始化 ↓ 执行 warmup ↓ 比较 warmup 前后 latency重点则是未来如何处理类似问题。因此四类 Memory 的区别本质上是不同的知识形态需要不同的状态模型和更新语义。3.0.3 四类 Memory 的关系四类 Memory 并不是一条严格的线性流水线而是可以相互关联Semantic / \ ↓ ↓ Preference Episodic ↓ Procedural例如一次实际排障可能同时产生Semantic 项目使用 ONNX Runtime 1.29 │ ├──────────────┐ ↓ ↓ Episodic Procedural 某次 CUDA 首次 类似问题优先 Run 约 788ms 进行 warmupPreference 也可能参与其中Preference 用户偏好性能问题优先给出可验证的 benchmark这些 Memory 通过memory_relations建立关联而不是强制将一次交互归入唯一类型。3.0.4 为什么 V1 选择这四类四类不是理论上“唯一正确”的分类而是当前 Agent Memory 系统的一个工程最小完备集。它覆盖了 Agent 长期协作中最常见的四种信息Semantic → 长期事实 Preference → 长期偏好 Episodic → 历史经历 Procedural → 可复用方法相比只建立一个统一的Memory表这种划分可以明确不同类型的数据结构 ↓ 更新方式 ↓ 召回方式 ↓ 冲突处理 ↓ 生命周期因此V1 采用四类并不是为了“凑四种 Memory”而是为了让后续的数据模型和业务逻辑具有明确的语义边界。同时四类也不是最终形态。随着系统规模和业务复杂度增加可以进一步拆分Entity Memory当 Semantic 中实体、关系和图谱复杂度明显上升时独立出来。Social Memory需要建模多用户、多 Agent、组织关系和信任关系时引入。Reflection Memory需要专门记录 Agent 对失败任务、决策和行为进行反思时引入。因此四类是当前 V1 的工程边界而不是对人类记忆系统的完整模拟。3.1 核心区别类型回答的问题典型内容变化方式主要用途Semantic知道什么、关系是什么用户、项目、环境、实体事实与关系更新事实理解用户/项目/世界Preference喜欢什么C20、中文、输出格式覆盖偏好个性化Episodic发生过什么某次故障排查、某次任务新增历史延续任务Procedural应该怎么做排查流程、显式方法、验证经验迭代规则复用能力三句话看起来都是“记忆”但数据库操作完全不同而且它们并不互斥“我主要使用 C20。”——事实/偏好“昨天我们解决了 CUDA 首次 Run 788ms。”——历史事件“以后遇到 CUDA 首次 Run 慢先做 warmup。”——方法论### 3.2 为什么不能全部叫 Memory三句话看起来都是“记忆”但数据库操作完全不同而且它们并不互斥“我主要使用 C20。”——事实/偏好“昨天我们解决了 CUDA 首次 Run 788ms。”——历史事件“以后遇到 CUDA 首次 Run 慢先做 warmup。”——方法论3.3 Semantic事实与关系记忆Semantic 保存的是相对稳定、可独立于具体对话存在的事实与关系不局限于“用户画像”。典型范围包括User Fact用户主要使用 C Project Fact项目部署平台为 RK3568 Environment Fact运行环境使用 CUDA 12 Entity Fact模型输入特征为 Log-Mel Relationship Fact项目 → 使用 → ONNX Runtime数据天然适合主谓宾三元组或关系表{subject:project,predicate:deploy_to,object:RK3568}三个特点不依赖某次对话记“项目目标平台是 RK3568”而非“某天用户说过”。可被后续信息修改需要current value version history。检索由实体/属性/关系驱动无需复杂向量检索直接按project_id predicate查询。3.4 Preference偏好记忆事实与偏好不是一回事Semantic: 用户使用 C → 客观事实 Preference: 示例都用 C20 → 如何服务这个用户Preference 本质是Configuration Personalization。最大特点是Scope作用域覆盖由宽到窄Global → User → Agent → Project → Task但必须注意Task 层通常不是长期 Memory而是任务期间的覆盖配置。例如“这次回答用英文”不应反向修改user.language English。Task 级配置更适合进入 LangGraph State并在任务结束时过期长期 Memory 主要负责 Global/User/Agent/Project 层级。数据模型天然适合key value scope{key:coding.cpp_standard,value:C20,scope:user}3.5 Episodic场景记忆记录“某件事具体发生过什么”不能只保存原始聊天记录需要Conversation → Summary → Structured Episode有价值的结构化字段应保留Goal / Problem / Context / Actions / Decision / Result / Outcome因为 Agent 之后真正需要回答的是“这个问题当时是怎么解决的”而非“过去聊过很多关于 CUDA 的内容”。Episodic 也是 Procedural 的重要抽象来源之一但二者不是先后强制关系。3.6 Procedural流程经验记忆Procedural 描述“以后怎么做”。它不要求必须“多次成功案例之后才产生”来源包括用户显式提供的方法 历史 Episode 抽象 Agent/Tool 验证出的经验 外部规则/策略不同来源应保留不同confidence与source便于后续治理。Procedural 可迁移到未来任务的方法/规则因此 Procedural 是“方法论/经验层”让 Agent 具备可复用的经验能力。3.7 四种 Memory 的关系是一条链但不是互斥分类四者层层递进Semantic 提供事实底座Preference 决定服务方式Episodic 沉淀历史事件Procedural 提炼可复用经验共同构成完整长期记忆。但必须强调四类长期记忆之间不是互斥的“四选一”。同一段对话可能同时产生多种记忆后续通过关联关系连接而不是强制归入某一类。3.8 从对话到记忆Memory Extraction Pipeline核心问题不是“四类记忆是什么”而是一段对话进来后如何判断它属于哪类记忆。关键结论不要让 LLM 对整段对话做四选一分类对象不是 Conversation而是 Extractor 生成的每个 Memory Candidate。一段对话可以产生多个 Candidate每个 Candidate 独立分类允许多标签及关联。One Conversation → Multiple Memory Candidates正确的 Pipeline用户对话 ↓ Conversation Normalizer ↓ Memory Extractor → 生成多个 Memory Candidate ↓ 每个 Candidate 独立分类Semantic / Preference / Episodic / Procedural可多标签 ↓ Validator → Dedup → Conflict → Persist命中多个类别时建立memory_relations关联关系而不是强制四选一。四个判断标准Semantic 相对稳定、跨任务仍然成立的事实或关系。Preference 对未来 Agent 行为具有持续影响的用户偏好/指令。Episodic 对未来交互可能有价值的历史事件/任务经历。Procedural 可迁移到未来任务的方法/规则来源可为显式提供、事件抽象、验证经验或外部策略。多标签分类策略对每个 Memory Candidate依次判断以下问题可同时命中 1. 是否描述相对稳定的事实或关系 → 标记 Semantic 2. 是否表达对未来 Agent 行为的持续偏好/指令 → 标记 Preference 3. 是否是有边界、有复用价值的历史事件 → 标记 Episodic 4. 是否是可迁移到未来任务的方法/规则 → 标记 Procedural 命中多个类别时保留多标签并建立关联关系。示例“上次发现 CUDA 首次 Run 788ms加 warmup 恢复以后遇到类似问题先 warmup。” → Episodic历史事件 → Procedural可迁移方法 两个 Candidate 通过 memory_relations 关联。3.9 Conversation 与 Long-term Memory 的边界核心前提Conversation History ≠ Long-term Memory三者必须分开Conversation记“原话”是原始数据源。Memory记“提炼后的长期认知”需要动态治理Candidate → Active → Updated → Superseded → Archived → Deleted。LangGraph State记“现在做到哪里”也承载任务级临时配置如本次输出的语言/格式覆盖。因此 Memory Service 不应负责保存原始聊天而应消费 Conversation/Event再提炼长期记忆数据模型拆成conversations / messages与memories / memory_versions / memory_relations / memory_events。完整对话之所以重要是因为它可以作为 Memory 的原始依据在提取错误或模型升级后重新提取、验证、修正记忆。四、标准记忆生命周期与完整请求链路4.1 全生命周期Recall → 业务使用 → 生成 Memory Candidate → Extract / Validate / Resolve → Dedup → Conflict → 落地 PG唯一事实源 → 构建索引Milvus/OpenSearch → 生命周期治理更新/归档/过期4.2 单次完整 Agent 请求链路用户请求 → Recall 多源召回 → 融合/过滤/排序 → 结合 RAG 构建 Prompt → LLM 执行任务 → 生成 Memory Candidate → Extract / Validate / Resolve → Dedup / Conflict → 落地 PGActive Version→ 同步更新索引五、记忆召回精准架构传统“Redis→Milvus→OpenSearch→PG”瀑布式降级链路并不严谨。更准确的定义是索引负责“找到谁”PostgreSQL 负责“这个 Memory 现在到底是什么”。其中 OpenSearch 为可选组件仅在需要复杂全文检索、高级关键词查询、聚合分析或搜索分析时才引入。Recall Request │ ┌─────┼─────┐ ▼ ▼ ▼ 结构化召回 语义召回 关键词召回可选 (Redis/PG) (Milvus) (OpenSearch) │ │ │ └─────┼─────┘ ▼ Fusion多源融合 ▼ Filter过滤无效项 ▼ Reranker精准排序 ▼ Memory IDs / metadata ▼ PostgreSQL唯一事实源返回 Active Version Data ▼ Context Builder召回应明确分为三类其中关键词召回为可选Structured RecallRedis / PG适配精确查询、热点记忆、偏好、最近/高频访问。Semantic RecallMilvus适配模糊自然语言语义匹配。Keyword Recall可选OpenSearch适配精准关键词、专有名词、设备型号仅在需要复杂全文检索、高级关键词查询、Aggregation 或 Search Analytics 时引入。Structured RecallRedis / PG适配精确查询、热点记忆、偏好、最近/高频访问。Semantic RecallMilvus适配模糊自然语言语义匹配。Keyword RecallOpenSearch适配精准关键词、专有名词、设备型号。Redis 不应被当作一个普通 Recall Engine它定位是结构化 hot memory 缓存PostgreSQL 也不是“兜底”而是唯一事实源负责返回某个 Memory 当前有效版本的真实数据。六、工业级落地分阶段方案严格按「先核心、后优化、再工业化」迭代避免初期堆砌组件。阶段新增内容核心目标V1FastAPI Memory Service PostgreSQL定义记忆领域模型、PG 表结构、Recall/Write 主入口及基础 Write PipelineV2Embedding Milvus语义化记忆召回V3OpenSearch 混合检索 Reranker语义 关键词双模式精准召回V4LLM 记忆提取、校验、去重、冲突修复记忆写入智能化V5Kafka、Redis 结构化热点缓存、定时调度、可观测体系解耦、并发、监控、工业化高可用七、项目启动第一优先级核心工作停止架构名词堆砌与 PPT 设计优先落地工程核心定义完整 Memory 领域模型单条记忆结构与全部字段。梳理记忆完整生命周期产生、提取、验证、落地、召回、更新、冲突、过期、删除。基于模型设计 PG 数据表、索引、版本机制。实现基础 Memory Service 与 LangGraph 适配层明确区分任务级 State 与长期 Memory。核心结论模型是所有架构的根基。模型不清晰所有中间件堆砌均无意义。