"你昨天不是告诉我这个很重要吗?怎么今天就忘了?"

这是我第一次意识到,大模型和人类一样,也会"失忆"。

作为一个长期和 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 产品实践中的踩坑和思考。