From b06c768f1194ffbd44b13995c0f4d68e80109355 Mon Sep 17 00:00:00 2001 From: Blizzard Date: Fri, 19 Jun 2026 22:18:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=95=BF=E6=9C=9F=E8=AE=B0=E5=BF=86?= =?UTF-8?q?=E6=8A=BD=E5=8F=96=E8=AE=BE=E8=AE=A1=E4=BC=98=E5=8C=96md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memory_industry_analysis.md | 228 ++++++++++++++++++++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 memory_industry_analysis.md diff --git a/memory_industry_analysis.md b/memory_industry_analysis.md new file mode 100644 index 0000000..265d865 --- /dev/null +++ b/memory_industry_analysis.md @@ -0,0 +1,228 @@ +# 生产级 AI Agent 长期记忆 — 行业主流方案 + +## 行业共识:四层记忆架构 + +2025 年以来,行业在长期记忆上已经形成了**四层分类共识**(模仿认知科学): + +| 层 | 类型 | 内容 | 生命周期 | +|---|---|---|---| +| L1 | **工作记忆** | 当前对话的上下文窗口 | 会话内 | +| L2 | **短期/情景记忆** | 近期对话摘要、事件日志 | 数小时 ~ 数天 | +| L3 | **语义记忆** | 提炼出的事实、偏好、知识 | 持久(可衰减) | +| L4 | **程序记忆** | 学到的行为规则、约束、SOP | 持久 | + +> **sundynix-agentix 当前只覆盖了 L1(context window)+ L2(history)+ L3 的最简形态(KV profile)。** + +--- + +## 四大主流方案详解 + +### 1️⃣ OpenAI ChatGPT — "Dreaming" 机制 + +**思路**:不靠向量检索,靠**后台异步合成摘要**。 + +``` +用户对话 → 结束后异步触发 "Dreaming" + ↓ +分析历史 → 合成/更新 Memory Summary(结构化事实列表) + ↓ +下次对话 → 整个 Memory Summary 注入 context window +``` + +**架构特点**: +- **存储**:结构化事实列表(非向量),存为 user-scoped 文档 +- **写入**:后台异步 "Dreaming" 进程,周期性回顾历史、合成偏好 +- **读取**:**全量注入** context window(不做检索,依赖结构化摘要足够紧凑) +- **治理**:自动失效旧记忆("traveling to Singapore" → "went to Singapore"),用户可查看/编辑/删除 +- **不用 RAG**:刻意避免向量检索的延迟和复杂度,用轻量摘要替代 + +> [!NOTE] +> sundynix-agentix 的方案与 ChatGPT 早期版本(2024.4 Saved Memories)非常接近——都是**逐轮 LLM 抽取 + 全量注入**。 +> ChatGPT 后来演进到 Dreaming 是因为发现逐轮抽取会导致"记忆腐烂"(noisy/stale),需要**周期性整理合并**。 + +--- + +### 2️⃣ Mem0 — 行业最主流的记忆中间件 + +**思路**:三阶段流水线 + 混合存储。被认为是当前**事实上的行业标准**。 + +``` +对话消息 → Extract → Consolidate → Store + ↓ + ┌───────────┴───────────┐ + Vector Store Graph Store (Mem0g) + (语义检索) (关系推理) + ↓ +查询时 → Retrieve (语义相似 + 图谱关联) → 注入 prompt +``` + +**三阶段流水线**: + +| 阶段 | 做什么 | 关键区别 | +|---|---|---| +| **Extract** | LLM 从对话中抽取结构化事实和关系 | 类似 sundynix 的 `extractMemory` | +| **Consolidate** | LLM 将新事实与已有记忆**对账**,输出 ADD / UPDATE / DELETE / NOOP | ⚠️ sundynix 缺失这一层 | +| **Store** | 分别写入 Vector Store + Graph Store + KV Store | sundynix 只有 KV | + +**Consolidate 是核心差异**: + +``` +已有记忆: "用户喜欢 Vue" +新抽取: "用户说最近在学 React,打算迁移" + +Mem0 Consolidate → UPDATE: "用户从 Vue 迁移到 React" +sundynix → 如果 key 不同 → 两条并存("前端框架:Vue" + "技术学习:React") + 如果 key 恰好相同 → 覆盖(但依赖 LLM 用同一个 key,不可控) +``` + +**检索方式**: +- **不是全量注入**,而是用当前 query embedding 做 top-K 语义检索 +- 同时走 Graph Store 做关系关联检索("用户在 X 公司" → 关联出 "X 公司用 Go 技术栈") +- 大幅减少 token 浪费 + +--- + +### 3️⃣ Letta(原 MemGPT)— 操作系统式自管理记忆 + +**思路**:Agent 像操作系统一样**自己管理**自己的内存层级。 + +``` +┌─────────────────────────────────────────┐ +│ Context Window ("RAM") │ +│ ┌─────────┐ ┌──────────┐ ┌─────┐ │ +│ │ System │ │ Recall │ │User │ │ +│ │ Prompt │ │ Memory │ │Msg │ │ +│ │(可编辑) │ │(检索结果) │ │ │ │ +│ └─────────┘ └──────────┘ └─────┘ │ +└─────────────┬───────────────────────────┘ + │ Agent 主动调用内存管理工具 + ↓ +┌─────────────────────────────────────────┐ +│ Archival Memory ("Disk") — 向量存储 │ +│ Agent 可以 search / insert / delete │ +└─────────────────────────────────────────┘ +``` + +**关键设计**: +- Agent 自己决定什么时候存记忆(不是外部异步抽取) +- Agent 自己决定什么时候查记忆(通过 tool call) +- System prompt 是**可编辑的**,Agent 可以修改自己的"人格"和"核心记忆" +- Archival Memory 是无限的向量存储,Agent 按需检索 + +**与 sundynix 的对比**:sundynix 是外部驱动(orchestrator 异步抽取),Letta 是 Agent 自驱动。 + +--- + +### 4️⃣ Zep / Graphiti — 双时态知识图谱 + +**思路**:面向**时间敏感**场景,用图谱追踪事实的时间演变。 + +``` +对话/文档 → Graphiti 引擎 → 三层子图: + ├─ Episode 子图:原始事件(无损保留,带时间戳) + ├─ Semantic Entity 子图:提取的实体和关系(语义检索) + └─ Community 子图:实体聚类(高层概览) +``` + +**双时态模型(Bi-temporal)**: + +每条事实记录两个时间维度: + +| 维度 | 含义 | 示例 | +|---|---|---| +| **Valid Time** | 事实在现实中为真的时间 | "2024-01 ~ 2025-03 用户在 A 公司" | +| **Ingestion Time** | 系统何时发现这个事实 | "2025-04 从对话中得知" | + +``` +2024-01: 用户说 "我在 A 公司做后端" +2025-03: 用户说 "我上个月从 A 离职了" + +Zep 存储: + (用户) -[就职于]-> (A公司) valid: 2024-01 ~ 2025-02, invalidated_at: 2025-03 + (用户) -[离职于]-> (A公司) valid: 2025-03 ~ + +普通 KV 存储: + 公司: A公司 → 被覆盖为空,或两条矛盾并存 +``` + +- 可以回答"用户去年这个时候在做什么?" +- 旧事实**失效但不删除**,保留完整时间线 +- 企业级场景(合规、审计、保单变更)的首选 + +--- + +## 对比总览 + +| 维度 | sundynix 现状 | ChatGPT | Mem0 | Letta | Zep | +|---|---|---|---|---|---| +| **存储** | PG 扁平 KV | 结构化文档 | Vector + Graph + KV | Vector (Archival) | 双时态知识图谱 | +| **抽取** | 逐轮 LLM 抽取 | 后台周期 Dreaming | Extract 阶段 | Agent 自主存储 | Graphiti 引擎 | +| **去重/合并** | exact key match | Dreaming 合成 | **Consolidate (ADD/UPDATE/DELETE)** | Agent 自管理 | 双时态失效 | +| **检索** | **全量注入** | 全量注入(紧凑摘要) | **语义 top-K + 图谱关联** | Agent 主动搜索 | 语义 + 时间 + 图谱 | +| **时间维度** | ❌ | 有(自动过时) | ❌ | ❌ | ✅ 双时态 | +| **遗忘** | ❌ | ✅ 自动 | ✅ DELETE 操作 | ✅ Agent 决定 | ✅ 失效不删 | +| **用户控制** | ❌ | ✅ 查看/编辑/删除 | 有 API | 有 API | 有 API | +| **复杂度** | ★☆☆☆☆ | ★★☆☆☆ | ★★★☆☆ | ★★★★☆ | ★★★★★ | + +--- + +## sundynix-agentix 的差距与改造路线 + +### 与行业标准(Mem0 模式)的 3 个关键差距 + +```mermaid +flowchart LR + A["1. 缺 Consolidate 层
无法 ADD/UPDATE/DELETE
只有盲目 upsert"] --> D["记忆腐烂
冗余/过时/矛盾"] + B["2. 全量注入
不做相关性检索"] --> E["token 浪费
噪声干扰"] + C["3. 无时间/置信度
维度"] --> F["无法遗忘
无法区分强弱偏好"] +``` + +### 建议改造路线(利用已有基础设施) + +项目已有 **Milvus + Neo4j + Postgres**,完全可以不引入新依赖,渐进实现 Mem0 级别的能力: + +#### Phase 1 — 加 Consolidate 层(改 `memory_extract.go`,约 50 行) + +把现在的 "抽取 → 盲目 upsert" 改为 "抽取 → LLM 对账 → 决策执行": + +```go +// 现在的流程: +fresh := filterNewPrefs(parsePrefs(txt), existing) // exact match 去重 +for _, p := range fresh { + o.upsertMemory(ctx, uid, p.Key, p.Value) // 盲 upsert +} + +// 改为 Mem0 式 Consolidate: +// 1. 把新抽取 + 已有画像一起交给 LLM +// 2. LLM 输出操作列表:[{op:"ADD/UPDATE/DELETE", key, value, reason}] +// 3. 按操作执行 +``` + +#### Phase 2 — 按需检索代替全量注入(复用 Milvus,改 `compile.go`) + +```go +// 现在 (compile.go:27-31):全量注入 +if rc.Profile != "" { + sys.WriteString("\n\n关于当前用户的已知信息:\n") + sys.WriteString(rc.Profile) // 全部偏好 +} + +// 改为:memory_get 传入 query,Milvus 语义检索 top-5 相关偏好 +// memory store 存偏好时同时 embedding → Milvus memory collection +// 读取时用 query embedding → top-K → 只注入相关的 +``` + +#### Phase 3 — 图谱记忆(复用 Neo4j) + +``` +memory_upsert 时同时写入 Neo4j: + (User:uid) -[偏好 {key, since, confidence}]-> (Value:value) + +检索时可以做关系推理: + "用户的公司" → "公司的技术栈" → 关联出相关偏好 +``` + +> [!TIP] +> **最务实的改造优先级**:Phase 1(Consolidate)> Phase 2(语义检索)> Phase 3(图谱)。 +> Phase 1 改动最小(只改 `memory_extract.go` 的抽取 prompt 和处理逻辑), +> 但效果最显著——直接解决记忆腐烂这个最大的 Day-2 问题。