← 返回博客

AI 记忆与上下文管理:MemoryX 的保存、提取与召回技术解析

很多人问我们:MemoryX 到底怎么实现跨平台的 AI 记忆?记忆是怎么从对话里提取出来的?又是怎么在你下一次提问时被自动注入的?

这篇文章不是理论探讨,而是基于我们实际代码的技术解析。每一个细节都有对应的实现。(阅读背后的故事:我为什么做了 MemoryX。)

整体架构:Capture → Structure → Recall

MemoryX AI memory architecture: Capture, Structure, Recall — three-step closed loop for saving AI conversations and auto-recalling context

MemoryX 的记忆系统分三步:

  1. Capture(捕获):自动保存你在 ChatGPT、Claude、Gemini 上的对话
  2. Structure(结构化):用 LLM 从对话中提取结构化记忆,去重后存储
  3. Recall(召回):在你下一次提问时,自动搜索相关记忆并注入到对话上下文

这三步形成一个完整的闭环。你在 Claude 聊的内容,下次在 ChatGPT 提问时就能被自动召回。


第一步:保存对话

MemoryX 的 Chrome 扩展会自动监测你在 AI 平台上的对话,每隔几秒检测一次对话内容变化,自动保存为完整的对话记录。

保存有两种模式:

  • 自动保存:每 1.5-5 秒触发一次,检测到新消息就增量保存
  • 手动保存:用户主动点击保存按钮

保存的是完整的对话 Markdown,包括用户消息和 AI 回复。这是后续一切的基础。


第二步:从对话中提取记忆

AI memory extraction and deduplication flow in MemoryX — extracting structured context from ChatGPT, Claude, and Gemini conversations

保存对话之后,MemoryX 会用 LLM 从中提取结构化的记忆。这是整个系统最核心的部分。

提取什么,不提取什么

我们定义了 7 个提取类别:

MemoryX 7 AI memory extraction categories: preferences, personal info, plans, activities, health, career, and other context
  1. 个人偏好:喜好、习惯、沟通风格
  2. 重要个人信息:姓名、地点、重要日期
  3. 计划和意图:目标、项目、即将发生的事
  4. 活动和服务偏好:餐饮、旅行、购物习惯
  5. 健康信息:饮食限制、健身习惯
  6. 职业信息:职位、技术栈、工作风格
  7. 其他:兴趣、观点、态度

但同样重要的是不提取什么。这是我们花了大量时间调优的部分。核心判断标准是两条:

区分持久偏好和一次性指令。只提取反映用户"是谁"的信息。比如"偏好极简设计风格"是持久偏好,应该提取;但"帮我翻译这段话"是一次性请求,不该提取。简单的判断方法:如果这条信息不能帮助另一个 AI 更好地理解这个用户,就不该提取。

区分用户自身信息和引用内容。当用户分享链接、引用文章或贴了一段示例代码时,不要把引用的内容当作用户本人的事实来提取。

提取的输出格式

每条提取出的记忆都是结构化的,包含类型、文本、标签、双语关键词和置信度:

{
  "type": "preference",
  "text": "偏好使用 TypeScript 编程",
  "tags": ["TypeScript", "编程语言"],
  "keywords": ["TypeScript", "TS", "编程", "programming"],
  "confidence": 0.9
}

几个关键设计决策:

  • type 分为 skill(技能)、preference(偏好)、objective(目标)、context(背景)四类
  • keywords 是双语的(中英文都有),这样无论用户用什么语言提问,都能搜索到相关记忆
  • confidence 标注置信度——显式声明的信息置信度高,合理推断的信息置信度适中
  • 记忆文本的语言跟用户一致:用户用中文聊天,提取出的记忆就是中文的

合理推断

我们的系统允许合理推断。如果用户在问 React hooks 的问题,我们会推断他使用 React,以适中的置信度提取。这参考了 mem0 的设计哲学——宽松提取,但标注置信度,让后续的召回环节可以据此做排序和过滤。

合并而非拆分

我们明确要求 LLM 把相关信息合并为一条完整的记忆,而不是拆成碎片。比如用户在讨论 logo 设计时提到了风格、颜色、字母、参考对象,这应该是一条记忆,而不是四条。

目标是每段对话提取 3-5 条高质量记忆,而不是 10+ 条碎片。

增量提取

同一段对话如果持续进行,我们不会每次都从头提取。系统会记录"上次提取到第 N 条消息",下次只处理新增的消息:

Incremental AI memory extraction timeline — only processing new messages to avoid duplicate extraction in ongoing conversations

已处理的消息会作为背景上下文传给 LLM,但 LLM 只从新消息中提取,避免重复。

自动 vs 手动提取

自动提取使用标准的置信度阈值。当用户手动点击"提取记忆"按钮时,系统会更加激进——降低阈值、扩大提取范围,尽可能从对话中挖掘有价值的信息。用户主动触发意味着他认为这段对话有价值,系统应该响应这个意图。

30 秒稳定窗口

提取不是实时触发的。最后一条新消息后,系统会等待 30 秒。如果 30 秒内又有新消息,计时器重置。这是为了避免对话进行中频繁提取:

T=0s   新消息 → 安排 30s 后提取
T=3s   新消息 → 取消上次,重新安排 30s
T=8s   新消息 → 取消上次,重新安排 30s
T=38s  30s 无新消息 → 开始提取 T=0~8s 的所有新消息

第三步:语义去重

提取出记忆后,保存之前还有一道关卡:语义去重。避免存入重复的记忆。

候选搜索

首先用 BM25 关键词搜索找到可能重复的已有记忆,缩小候选范围。

LLM 判断

然后用 LLM 对每条新记忆和候选记忆进行对比,做出四种决策之一:

AI memory deduplication decision flow: ADD, UPDATE, NOOP, or DELETE — semantic dedup for saved AI conversations

为了保证判断的一致性,LLM 在这个环节使用极低的温度参数,减少随机性。

安全策略

一个重要的设计原则:AI 不能自动删除用户的记忆。在 v1.0 中,即使 LLM 判断应该 DELETE,我们也选择更保守的处理方式。UPDATE 操作会保留旧版本文本(old_text),万一改错了可以恢复。

操作 做法 安全性
ADD 直接保存 无风险
UPDATE 更新内容 + 保留旧版本 可回溯
DELETE v1.0 不做自动删除 零风险
NOOP 不操作 无风险

第四步:自动召回

Auto-recall flow in MemoryX: intercept user message, search AI memories via embedding, and inject relevant context into ChatGPT, Claude, or Gemini

保存和提取完成后,记忆就安静地待在那里。真正让它发挥价值的是召回——在你下一次提问时,自动把相关记忆注入到对话上下文中。

Embedding 搜索 + BM25 Fallback

当用户在 AI 平台输入消息并发送时,MemoryX 会拦截这个发送操作,先进行记忆搜索。

搜索的核心逻辑是 Embedding 向量搜索优先,BM25 关键词搜索兜底

Embedding 搜索把用户输入和所有记忆都转成高维向量,通过余弦相似度排序,找到语义上最相关的记忆。我们设定了相似度阈值,只返回真正相关的结果。

Embedding 搜索的优势是能理解语义:

  • BM25:"喜欢极简设计" vs "追求简洁美学" → 匹配不到(无共同关键词)
  • Embedding:"喜欢极简设计" vs "追求简洁美学" → 能匹配(语义相近)

搜索结果还会做一轮结果去重——如果两条结果之间语义高度相似,只保留分数更高的那条,避免注入重复信息。

BM25 搜索作为降级方案,在 Embedding API 不可用时(网络错误等)自动切换到本地关键词搜索。虽然准确率稍低,但保证了系统在离线或异常情况下仍然可用。

拦截与注入

记忆搜索完成后,MemoryX 会把结果注入到用户的消息末尾。这个过程对用户来说是透明的。

技术上,我们在 DOM 的 capture phase 拦截用户的发送事件——这确保了在 React 等框架处理之前,MemoryX 就能介入。

拦截流程:

  1. 用户按 Enter 或点发送按钮
  2. MemoryX 阻止原始发送事件
  3. 读取用户输入 → 发送到 service worker 进行记忆搜索
  4. 搜索到相关记忆 → 追加到用户消息末尾
  5. 重新触发发送(优先点击发送按钮,更可靠)

注入的格式是这样的:

---
[MemoryX 上下文 · 3 条记忆]
- [偏好·3月] 偏好使用 TypeScript 编程
- [技能·2月] 使用 Claude Code 和 Cursor 作为开发工具
- [目标·3月] 正在开发一个 Chrome 扩展项目
(以上是用户背景信息,请直接回答问题,仅在相关时参考上下文。)
---

每条记忆都带有类型标签和时间标注。类型标签会根据用户输入的语言自动切换中英文。为了避免上下文过长,系统会限制注入的记忆数量,只保留最相关的几条。

使用统计

每次记忆被召回使用后,系统会在后台异步更新使用统计(usageCountlastUsedAt),不阻塞用户的发送流程。这些数据未来可以用来优化召回排序和识别不再相关的记忆。


第五步:对话摘要

除了提取结构化记忆,MemoryX 还支持生成对话摘要。摘要的目的是帮助用户在另一个 AI 工具中快速续接之前的对话。

摘要系统会自动检测对话的主要语言,生成对应语言的摘要——中文对话生成中文摘要,英文对话生成英文摘要。

摘要的结构是固定的,为续接而设计:

  • 用户/背景:推断用户是谁、当前处境
  • 项目/主题:一句话概括核心问题
  • 当前状态:对话进行到什么阶段、得出了什么结论
  • 关键信息:按主题分类的事实、决策、计划
  • 待办事项/开放问题:未解决的问题
  • 续接点:下一个 AI 可以从哪里继续

这不是普通的"对话总结",而是一个交接文档——让你从 ChatGPT 切换到 Claude 时,Claude 能在几秒内理解完整上下文。


与竞品的关键差异

我们调研了 mem0(24K star 的开源标杆)、Letta/MemGPTZep / Graphiti 等项目后,做了几个差异化选择:

维度 mem0 MemoryX
提取时机 每条消息立即提取 对话稳定 30 秒后批量提取
AI 调用次数 提取 1 次 + 每条 fact 核对 1 次 提取+核对合并为 1 次调用
自动删除 支持 不支持(v1.0 保守策略)
更新保护 保留 old_text 可回溯
Embedding 失败 无降级 BM25 自动兜底

核心思路是:在记忆安全上保守,在提取能力上激进,在系统可靠性上做好降级。


总结

MemoryX 的记忆系统不是一个简单的"保存-搜索"。它是一个完整的管道:

捕获对话 → 30 秒稳定 → 增量提取 → 语义去重 → 向量+关键词搜索 → 自动注入

每一步都有明确的设计理由,每一步都有对应的降级方案。我们不追求在每一步都做到最优,但确保整个管道在各种边界条件下都能稳定运行。

这是我们实际的做法,不是理论。


试试看

如果你也在多个 AI 平台之间切换,想让它们都能"记住你",可以试试 MemoryX。

试试 MemoryX

不再重复自己,让你的 AI 上下文跟着你走。

从 Chrome Web Store 安装