乐于分享
好东西不私藏

给本地AI装「记性」:AI助手加长期记忆

给本地AI装「记性」:AI助手加长期记忆

我用本地助手最大的挫败感,不是它笨,而是它「不认识我」。

昨天我告诉它「我在北京工作、专注本地部署场景、不喜欢废话」,今天开一个新会话,它又客客气气地问我「请问您的使用场景是?」。每次都失忆,每次都从零开始自我介绍——这种关系,谈不上「助手」,顶多是个反复重置的搜索框。

云端大模型靠什么记住你?靠把你过去的对话历史一股脑塞回上下文。可这条路对本地小模型是死路:8GB 卡上的 9B 模型,上下文本来就紧张,你还要把上万 token 的历史每次都灌进去,速度崩、显存崩、效果也崩。

所以本地助手要长期记忆,不能靠「塞历史」,得靠「记要点」。这就是今天的主角——mem0

一、mem0 是什么,为什么能全本地跑

mem0(开源 Python 包 mem0ai,当前版本 v2.0.7,Apache 2.0 许可)做的事,一句话概括:它不保存你说过的每句话,而是从对话里抽取出关键事实,存成向量;下次需要时,只把相关的三五条捞回来注入

它天生是给「记忆」这件事设计的中间层。默认它会调云端 LLM 和 embedding,但关键在于——它的 LLM、embedder、向量库三个部件全都可以指向本地

  • LLM 指向本地 Ollama(负责判断哪些是值得记的事实)
  • embedder 指向本地 Ollama 的 embedding 模型(把事实转成向量)
  • 向量库用本地 Qdrant 或 Chroma(把向量存起来)

三个部件全在本机,零 API key,数据一个字节都不出机器。对我们这些既想要记忆、又不想把私人信息发给云端的人来说,这才是能用的方案。

二、装起来:三行命令

先装包,再让 Ollama 备好两个模型——一个当大脑,一个当「翻译成向量」的工具:

pip install mem0ai ollama

# 一个 LLM(负责抽取事实)
ollama pull qwen3.5:9b

# 一个 embedding 模型(负责转向量)
ollama pull nomic-embed-text

ollama pull 用最新版 Ollama 即可,不用纠结版本号。qwen3.5:9b 权重约 6.6GB,nomic-embed-text 很小,两个加起来 8GB 显存装得下——这套组合是我给 8GB 卡定的甜区,后面会算账。

三、可跑代码:给助手第一段记忆

下面这段是完整能跑的。核心是一个 config 字典,把三个部件都指向本地:

from mem0 import Memory

config = {
"vector_store": {
"provider""chroma",          # 也可换成 "qdrant"
"config": {
"collection_name""my_assistant",
"path""./mem0_db",           # Chroma 落地目录
"embedding_model_dims"768,   # 必须和 embedder 输出维度一致
        },
    },
"llm": {
"provider""ollama",
"config": {
"model""qwen3.5:9b",
"ollama_base_url""http://localhost:11434",
        },
    },
"embedder": {
"provider""ollama",
"config": {
"model""nomic-embed-text",
"ollama_base_url""http://localhost:11434",
        },
    },
}

m = Memory.from_config(config)

# 写入记忆
m.add("我在北京工作", user_id="张三")
m.add("我只有一张 8GB 显卡,别推荐大模型", user_id="张三")
m.add("回答尽量简短,不要客套", user_id="张三")

# 取出这个人的全部记忆
print(m.get_all(user_id="张三"))

跑完你会看到,mem0 把这几句话消化成了结构化的记忆条目——注意它存的不是原句,而是抽取后的事实(比如「工作地点:北京」「硬件:8GB 显卡」)。这一步就是本地 qwen3.5:9b 在干活。

四、把记忆接回对话:只注入相关的几条

光存不够,得让助手在回答时用上。逻辑是:用户提问 → 先去记忆库检索最相关的几条 → 只把这几条拼进 prompt → 再问模型

import ollama

defchat_with_memory(question, user_id="张三"):
# 1) 检索相关记忆(不是全部,是最相关的几条)
    hits = m.search(question, user_id=user_id, limit=5)
    memories = "\n".join(f"- {h['memory']}"for h in hits["results"])

# 2) 只把这几条注入 prompt
    prompt = f"""已知关于这位用户的事实:
{memories}

用户提问:{question}
请结合上面的事实回答。"""


    resp = ollama.chat(model="qwen3.5:9b",
                       messages=[{"role""user""content": prompt}])
    answer = resp["message"]["content"]

# 3) 把这轮对话再交给 mem0,让它决定要不要记新东西
    m.add(f"用户问:{question}\n助手答:{answer}", user_id=user_id)
return answer

print(chat_with_memory("给我推荐个本地模型"))

关键在第 1 步的 limit=5:无论记忆库里存了 5 条还是 5000 条,每次注入的永远只有最相关的几条。这跟「把全部历史塞回去」是两种完全不同的哲学。

五、为什么这件事对小模型「尤其」关键

这不是锦上添花,对本地小模型是生死线。

mem0 官方做过一个对比实验,结论很扎心:同一个 4B 小模型,给它「精简后的记忆」,它能稳定产出合法的 JSON 结构;而给它「原始的长对话历史」,它直接崩掉、输出乱套

原因不难理解——小模型的注意力是稀缺资源。你塞进去一万 token 的历史,真正有用的可能就三句话,剩下的全是噪声,模型在噪声里迷路(这就是我之前那篇讲长上下文时提过的「中间忘记」现象,模型越小越严重)。而 mem0 先替它把噪声筛掉,只留下干净的几条事实,小模型反而能干得漂亮。

大模型靠蛮力也能从长历史里捞信息,小模型不行——它必须被喂「精挑细选」的记忆。 这就是 mem0 这类工具在本地场景比在云端更有价值的根本原因。

六、8GB 显存账本

把这套跑起来到底吃多少显存?我按 8GB 卡的组合算一遍:

部件
选型
显存 / 开销
LLM
qwen3.5:9b
(q4_K_M)
约 6.6GB
Embedding
nomic-embed-text
很小,可挤在余量里
向量库
Chroma(进程内)
走内存/磁盘,不占显存
合计
8GB 内可跑

这里有个省事的点:Chroma 可以完全在 Python 进程内跑,不需要 Docker,落地成一个本地文件夹就行,适合个人助手和轻量场景。如果你要多进程共享、或数据量很大,再换成 Qdrant(需要单独起服务)。

七、mem0 的两个部件选型对照

维度
Chroma
Qdrant
起步成本
极低,进程内、免 Docker
要单独起服务
适合场景
个人助手、原型、轻量
多进程、数据量大、生产
数据落地
本地文件夹
独立数据库
上手难度
最简单
中等

个人玩、装记性——先上 Chroma,别一上来就折腾 Docker。

八、最容易踩的坑:维度对不上

这是我第一次跑时卡了最久的地方,也是绝大多数人会中招的坑:

config 里的 embedding_model_dims 必须和你的 embedding 模型实际输出维度严格一致。nomic-embed-text 输出的是 768 维,所以上面配的就是 768。如果你写成 1536(那是别的模型的维度),或者换了个 embedding 模型却忘了改这个数字,向量库要么报错、要么静默存进脏数据,检索结果全乱。

记住一个原则:换 embedder,必查维度,同步改 embedding_model_dims 这一条能帮你省下一晚上。

九、什么时候用 mem0,什么时候不用

装记性也不是万能钥匙,分清楚场景:

  • ✅ 个人助手记住你的偏好 / 身份 / 长期设定 → mem0 的主场
  • ✅ 客服、陪伴类 Agent 记住每个用户 → 按 user_id 隔离,天生契合
  • ✅ 小模型 + 需要跨会话记忆 → 越是小模型越该用
  • ❌ 一次性总结一份长文档 → 那是长上下文 / 分段处理的活,不需要记忆库
  • ❌ 一整个知识库的检索问答 → 那是 RAG 的活,走我之前写过的那套知识库方案更合适

简单说:mem0 管「关于用户的事实」,RAG 管「关于文档的知识」。两者可以并存,但别混用。

十、行动建议

  • ✅ 想让本地助手认识你:今天就 pip install mem0ai ollama,把上面第三、四节的代码跑一遍,先存三条关于自己的事实
  • ✅ 8GB 卡用户:直接用 qwen3.5:9b + nomic-embed-text + Chroma 这套,进程内免 Docker,最省心
  • ✅ 建 Agent / 客服机器人:用 user_id 给每个用户单独建记忆,天然多租户
  • ⚠️ 换 embedding 模型时:第一件事就是核对并改 embedding_model_dims,否则全盘皆错
  • ❌ 别拿它当 RAG 用:文档检索走知识库,事实记忆走 mem0

给助手装上记性之后,你会发现关系变了——它开始「接得住上文」,不再每次让你重新自我介绍。


#mem0 #本地AI #Agent记忆 #向量库 #8GB显卡