AI 记忆与上下文管理:MemoryX 的保存、提取与召回技术解析
很多人问我们:MemoryX 到底怎么实现跨平台的 AI 记忆?记忆是怎么从对话里提取出来的?又是怎么在你下一次提问时被自动注入的?
这篇文章不是理论探讨,而是基于我们实际代码的技术解析。每一个细节都有对应的实现。(阅读背后的故事:我为什么做了 MemoryX。)
整体架构:Capture → Structure → Recall
MemoryX 的记忆系统分三步:
- Capture(捕获):自动保存你在 ChatGPT、Claude、Gemini 上的对话
- Structure(结构化):用 LLM 从对话中提取结构化记忆,去重后存储
- Recall(召回):在你下一次提问时,自动搜索相关记忆并注入到对话上下文
这三步形成一个完整的闭环。你在 Claude 聊的内容,下次在 ChatGPT 提问时就能被自动召回。
第一步:保存对话
MemoryX 的 Chrome 扩展会自动监测你在 AI 平台上的对话,每隔几秒检测一次对话内容变化,自动保存为完整的对话记录。
保存有两种模式:
- 自动保存:每 1.5-5 秒触发一次,检测到新消息就增量保存
- 手动保存:用户主动点击保存按钮
保存的是完整的对话 Markdown,包括用户消息和 AI 回复。这是后续一切的基础。
第二步:从对话中提取记忆
保存对话之后,MemoryX 会用 LLM 从中提取结构化的记忆。这是整个系统最核心的部分。
提取什么,不提取什么
我们定义了 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 条消息",下次只处理新增的消息:
已处理的消息会作为背景上下文传给 LLM,但 LLM 只从新消息中提取,避免重复。
自动 vs 手动提取
自动提取使用标准的置信度阈值。当用户手动点击"提取记忆"按钮时,系统会更加激进——降低阈值、扩大提取范围,尽可能从对话中挖掘有价值的信息。用户主动触发意味着他认为这段对话有价值,系统应该响应这个意图。
30 秒稳定窗口
提取不是实时触发的。最后一条新消息后,系统会等待 30 秒。如果 30 秒内又有新消息,计时器重置。这是为了避免对话进行中频繁提取:
T=0s 新消息 → 安排 30s 后提取
T=3s 新消息 → 取消上次,重新安排 30s
T=8s 新消息 → 取消上次,重新安排 30s
T=38s 30s 无新消息 → 开始提取 T=0~8s 的所有新消息 第三步:语义去重
提取出记忆后,保存之前还有一道关卡:语义去重。避免存入重复的记忆。
候选搜索
首先用 BM25 关键词搜索找到可能重复的已有记忆,缩小候选范围。
LLM 判断
然后用 LLM 对每条新记忆和候选记忆进行对比,做出四种决策之一:
为了保证判断的一致性,LLM 在这个环节使用极低的温度参数,减少随机性。
安全策略
一个重要的设计原则:AI 不能自动删除用户的记忆。在 v1.0 中,即使 LLM 判断应该 DELETE,我们也选择更保守的处理方式。UPDATE 操作会保留旧版本文本(old_text),万一改错了可以恢复。
| 操作 | 做法 | 安全性 |
|---|---|---|
| ADD | 直接保存 | 无风险 |
| UPDATE | 更新内容 + 保留旧版本 | 可回溯 |
| DELETE | v1.0 不做自动删除 | 零风险 |
| NOOP | 不操作 | 无风险 |
第四步:自动召回
保存和提取完成后,记忆就安静地待在那里。真正让它发挥价值的是召回——在你下一次提问时,自动把相关记忆注入到对话上下文中。
Embedding 搜索 + BM25 Fallback
当用户在 AI 平台输入消息并发送时,MemoryX 会拦截这个发送操作,先进行记忆搜索。
搜索的核心逻辑是 Embedding 向量搜索优先,BM25 关键词搜索兜底。
Embedding 搜索把用户输入和所有记忆都转成高维向量,通过余弦相似度排序,找到语义上最相关的记忆。我们设定了相似度阈值,只返回真正相关的结果。
Embedding 搜索的优势是能理解语义:
- BM25:"喜欢极简设计" vs "追求简洁美学" → 匹配不到(无共同关键词)
- Embedding:"喜欢极简设计" vs "追求简洁美学" → 能匹配(语义相近)
搜索结果还会做一轮结果去重——如果两条结果之间语义高度相似,只保留分数更高的那条,避免注入重复信息。
BM25 搜索作为降级方案,在 Embedding API 不可用时(网络错误等)自动切换到本地关键词搜索。虽然准确率稍低,但保证了系统在离线或异常情况下仍然可用。
拦截与注入
记忆搜索完成后,MemoryX 会把结果注入到用户的消息末尾。这个过程对用户来说是透明的。
技术上,我们在 DOM 的 capture phase 拦截用户的发送事件——这确保了在 React 等框架处理之前,MemoryX 就能介入。
拦截流程:
- 用户按 Enter 或点发送按钮
- MemoryX 阻止原始发送事件
- 读取用户输入 → 发送到 service worker 进行记忆搜索
- 搜索到相关记忆 → 追加到用户消息末尾
- 重新触发发送(优先点击发送按钮,更可靠)
注入的格式是这样的:
---
[MemoryX 上下文 · 3 条记忆]
- [偏好·3月] 偏好使用 TypeScript 编程
- [技能·2月] 使用 Claude Code 和 Cursor 作为开发工具
- [目标·3月] 正在开发一个 Chrome 扩展项目
(以上是用户背景信息,请直接回答问题,仅在相关时参考上下文。)
--- 每条记忆都带有类型标签和时间标注。类型标签会根据用户输入的语言自动切换中英文。为了避免上下文过长,系统会限制注入的记忆数量,只保留最相关的几条。
使用统计
每次记忆被召回使用后,系统会在后台异步更新使用统计(usageCount 和 lastUsedAt),不阻塞用户的发送流程。这些数据未来可以用来优化召回排序和识别不再相关的记忆。
第五步:对话摘要
除了提取结构化记忆,MemoryX 还支持生成对话摘要。摘要的目的是帮助用户在另一个 AI 工具中快速续接之前的对话。
摘要系统会自动检测对话的主要语言,生成对应语言的摘要——中文对话生成中文摘要,英文对话生成英文摘要。
摘要的结构是固定的,为续接而设计:
- 用户/背景:推断用户是谁、当前处境
- 项目/主题:一句话概括核心问题
- 当前状态:对话进行到什么阶段、得出了什么结论
- 关键信息:按主题分类的事实、决策、计划
- 待办事项/开放问题:未解决的问题
- 续接点:下一个 AI 可以从哪里继续
这不是普通的"对话总结",而是一个交接文档——让你从 ChatGPT 切换到 Claude 时,Claude 能在几秒内理解完整上下文。
与竞品的关键差异
我们调研了 mem0(24K star 的开源标杆)、Letta/MemGPT、Zep / Graphiti 等项目后,做了几个差异化选择:
| 维度 | mem0 | MemoryX |
|---|---|---|
| 提取时机 | 每条消息立即提取 | 对话稳定 30 秒后批量提取 |
| AI 调用次数 | 提取 1 次 + 每条 fact 核对 1 次 | 提取+核对合并为 1 次调用 |
| 自动删除 | 支持 | 不支持(v1.0 保守策略) |
| 更新保护 | 无 | 保留 old_text 可回溯 |
| Embedding 失败 | 无降级 | BM25 自动兜底 |
核心思路是:在记忆安全上保守,在提取能力上激进,在系统可靠性上做好降级。
总结
MemoryX 的记忆系统不是一个简单的"保存-搜索"。它是一个完整的管道:
捕获对话 → 30 秒稳定 → 增量提取 → 语义去重 → 向量+关键词搜索 → 自动注入
每一步都有明确的设计理由,每一步都有对应的降级方案。我们不追求在每一步都做到最优,但确保整个管道在各种边界条件下都能稳定运行。
这是我们实际的做法,不是理论。
试试看
如果你也在多个 AI 平台之间切换,想让它们都能"记住你",可以试试 MemoryX。
- 安装 Chrome 扩展:Chrome Web Store
- 加入 Discord 社区,聊聊你的使用场景和反馈:discord.gg/5Bfd7ryKFM