"你昨天不是告诉我这个很重要吗?怎么今天就忘了?"
这是我第一次意识到,大模型和人类一样,也会"失忆"。
作为一个长期和 AI 打交道的产品经理,见过太多这样的情况:AI 在一次对话中表现地"记住"了你的偏好、需求、背景信息,但当你第二天再找它时,它已经完全不记得了。这不是 AI 的"性格冷漠",而是技术架构的天然缺陷。
今天,我想和你分享我们是如何用 Obsidian + LanceDB 的组合拳,打破 AI 失忆困境的。
一、为什么 AI 需要"持久记忆"?
1.1 上下文窗口的囚徒困境
当前大模型的上下文窗口已经很长,几十万 token 不在话下。但这里有一个根本性的矛盾:
- 上下文是有成本的:token 越多,响应越慢,成本越高
- 记忆是有损耗的:即使在单次对话中,早期的信息也会被"稀释"
- 会话是有边界的:模型训练时的知识≠运行时的人机对话记忆
换句话说, your AI assistant is smart, but it's like a goldfish - only 7 seconds of memory.
1.2 PM的痛苦:每次都要重新解释
- 我告诉 AI:"我们公司叫泽塔数据,主要业务范围是智能体研发和信创业务",第二天它就全忘了
- 我花半小时对齐了产品需求文档的结构,下次它又问"你想做什么类型的产品?"
- 我说偏好用 Markdown 格式输出,它每次还是给我纯文本
1.3 持久记忆的本质:让 AI 拥有"海马体"
为什么我们人就能记住《老友记》剧情十年,却很容易忘记昨晚吃的什么?因为记忆分短时记忆和长时记忆,而长时记忆的核心是有效的存储和检索。
AI 也需要:
- 存储:存"有意义的信息"
- 检索:不是关键词匹配,而是"语义相关"
二、传统方案的坑:为什么 SQLite 不够用?
2.1 最早我们用朴素方式
- 方案 A:对话结束写文本文件
- 方案 B:SQLite 存记忆表
问题 1:查不到
- "泽塔数据"和"我们公司"在 SQLite 里是两条毫无关联的记录
问题 2:结构化困境 - 记忆是非结构化的,但 SQL 需要明确表结构
- 强行结构化 = 丢失信息
问题 3:规模效应
- 100 条记忆还能维护,10000 条?检索效率和准确性断崖式下降
2.2 核心教训
不是记忆"存不住",而是记忆"调不出"。
就像把你丢进一个堆满文件的房间,但没有索引目录,让你找某个文件一样。
三、Obsidian + LanceDB:为什么是这套组合?
3.1 Obsidian:让记忆"活"起来
Obsidian 的强大在于双向链接和图谱网络:
- 每条笔记可以链接到其他笔记
- 笔记之间形成关系网络
- 模拟人类记忆的"关联"特性
本地化存储 = 数据主权在自己手里。
3.2 LanceDB:向量检索的新选择
核心优势:
- 语义相似:搜"公司"能匹配到"泽塔数据"
- 高性能:百万级向量毫秒级检索
- 本地化:数据存本地,隐私安全
- 易集成:Python/NodeJS 都能用
3.3 组合拳打法
用户对话 → 提取关键信息 → 同时写入:
↓
① Obsidian(人类可读、结构化整理)
↓
② LanceDB(向量存储、语义检索)
↓
下次对话时 ← LanceDB 检索记忆 ← 注入上下文窗口
- Obsidian 负责"整理":人工复核、结构化、知识图谱化
- LanceDB 负责"召回":语义匹配、快速检索、自动补全
四、实战:如何搭建?
4.1 技术栈
- 向量数据库:LanceDB
- 笔记软件:Obsidian
- Embedding 模型:Jina-Embeddings(免费开源)
- 编程语言:Python / NodeJS
4.2 核心代码(简化版)
import lancedb
from openai import OpenAI
# 1. 初始化数据库
db = lancedb. connect("./memory_ db")
# 2. 存储记忆
def store_ memory(text, metadata):
embedding = client.embeddings. create(
model="jina-embeddings- v2-base-",
input=text
)
db["memories"].add([{
"vector": embedding.data[0].embedding,
"text": text,
"metadata": metadata
}])
# 3. 检索记忆
def recall_ memory(query, top_ k=5):
query_ embedding = client.embeddings. create(
model="jina-embeddings- v2-base-",
input=query
)
results = db["memories"].search(
query_embedding.data[0].embedding
).limit(top_k)
return results
4.3 工作流
对话结束后:
① 提取关键信息(公司名、偏好、待办等)
② 生成 Obsidian 笔记(Markdown,双链)
③ 写入向量数据库
下次对话时:
① 向量匹配检索记忆
② 注入上下文窗口
③ AI"仿佛"想起了之前的事
五、踩坑总结
5.1 坑1:版本兼容性
LanceDB 已停止维护 macOS x86_64 版本,最新只支持 Apple Silicon。
解决方案:换 M 系列 Mac,或退回简单模式。
5.2 坑2:Embedding 成本
解决方案:用免费模型(Jina Embeddings)或本地部署,Embeddings模型的消耗不大,通算本地跑也没啥压力。
5.3 坑3:记忆"过载"
检索返回太多"相关但不必要"的记忆,稀释关键信息。
解决方案:权重机制 + 硬性过滤,提高相关度阈值。
5.4 坑4:隐私性
解决方案:本地化存储 + 数据脱敏 + 知情同意。
六、AI的持久记忆的意义
为什么 AI 需要持久记忆?
因为真正有用的 AI,不是回答问题的机器,而是理解你的伙伴。
当 AI 能够记住:
- 你是谁、你的公司做什么
- 你喜欢什么、不喜欢什么
- 你之前做过什么、踩过什么坑
它才能从"工具"变成"助手"。
Obsidian + LanceDB 的组合,给了一个可行路径:既保留人类可读的结构化笔记(Obsidian),又拥有机器可理解的语义检索能力( LanceDB)。
这不是唯一答案,但是一个经过验证的思路。
最后
如果你也在做 AI 产品的记忆系统或对此感兴趣,欢迎在评论区聊聊你的做法。
也欢迎关注我们的公众号【泽塔数据】,持续分享 AI 产品实践中的踩坑和思考。