很多人第一次做 Agent,会很快撞到同一面墙:模型很聪明,但它不“记得”你。
- 你让它记住“我喜欢用 TypeScript,回答尽量短”,下一轮它又忘了。
- 你希望客服机器人记住“用户上次工单的背景”,它却要你重复一遍。
- 你想做“个性化助手”,但上下文窗口有限,越聊越贵、越聊越慢。
Mem0 的定位就是解决这件事:把“记忆”从一次对话的上下文里抽出来,做成一层独立能力,给你的助手/Agent 提供 可检索、可更新、可积累 的长期信息。
本文基于 Mem0 官方仓库与示例,做一份偏落地的介绍与上手指南(见:mem0ai/mem0)。
Mem0 是什么?一句话理解
你可以把 Mem0 理解成 Agent 的“记忆中枢”:
- 输入:你和用户的对话(messages)、以及你选择要保留的信息
- 输出:在新一轮对话开始前,给你一组“可能有用的记忆”(relevant memories)
- 作用:让模型在不塞满上下文的前提下,表现得更“长期一致”
从工程角度看,Mem0 想把这条链路标准化:
- 产生对话/事件
- 抽取适合长期保留的信息(偏好、事实、约束、历史动作)
- 写入记忆库
- 下次用户发问时,先检索出相关记忆
- 把记忆注入系统提示词/上下文,再去调用 LLM
官方把它称为 “Universal memory layer for AI Agents”(见:mem0ai/mem0)。
什么时候值得用“长期记忆”?
如果你的应用满足下面任意一条,Mem0 这类记忆层通常会带来立竿见影的收益:
- 强个性化:偏好(语言/风格)、禁忌(不谈某些话题)、工作习惯(常用框架/代码风格)
- 强连续性:多轮办事(报销/工单/学习计划/健身计划),需要跨会话延续状态
- 强成本约束:不想每次把“用户档案+历史总结”都塞进上下文
- 强一致性要求:比如 B2B 客服需要“记住公司的政策版本”“用户的合同条款”
反过来,如果你的应用只是一次性问答、没有个性化诉求,或者知识库完全可以用 RAG 解决,那么记忆层不一定是第一优先级。
Mem0 的核心概念:三类“记忆”
Mem0 在仓库介绍中强调了 Multi-Level Memory(多层记忆):User / Session / Agent(见:mem0ai/mem0)。
用产品语言翻译一下:
- User 记忆:用户稳定偏好/长期信息(“我叫张三”“我喜欢用中文”“我对隐私很敏感”)
- Session 记忆:本次会话内的阶段性状态(“我们已经确定了需求 A/B”“你已经上传了文件 X”)
- Agent 记忆:你的系统自己的运行状态(“上次调用了哪些工具”“某任务已完成到哪一步”)
你不必一开始就把三层都做得很复杂。最实用的落地路线往往是:先把 User 记忆做起来,让用户体验到“它真的记得我”,再逐步引入更细的 Session/Agent 状态。
快速上手(Python):一段可跑通的最小示例
下面示例改写自仓库 README 的基本用法(见:mem0ai/mem0)。思路是:每次用户发言前先 search,生成回答后再 add 写入记忆。
1) 安装
pip install mem0ai
2) 最小可跑 Demo
from openai import OpenAI
from mem0 import Memory
openai_client = OpenAI()
memory = Memory()
def chat_with_memories(message: str, user_id: str = "default_user") -> str:
# 1) 检索可能相关的记忆(把“历史”变成“可选的、可检索的”)
relevant = memory.search(query=message, user_id=user_id, limit=3)
memories_str = "\n".join(f"- {entry['memory']}" for entry in relevant["results"])
# 2) 把记忆注入系统提示词,让模型“像记得一样”回答
system_prompt = (
"你是一个有帮助的 AI 助手。请结合用户问题与用户记忆来回答。\n"
f"User Memories:\n{memories_str}"
)
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": message},
]
response = openai_client.chat.completions.create(
model="gpt-4.1-nano-2025-04-14",
messages=messages,
)
assistant = response.choices[0].message.content
# 3) 把本轮对话写入记忆库(是否“抽取”由 Mem0 负责/或由你配置策略)
messages.append({"role": "assistant", "content": assistant})
memory.add(messages, user_id=user_id)
return assistant
def main():
print("Chat with AI (type 'exit' to quit)")
while True:
user_input = input("You: ").strip()
if user_input.lower() == "exit":
print("Goodbye!")
break
print(f"AI: {chat_with_memories(user_input)}")
if __name__ == "__main__":
main()
3) 这段代码里最关键的两点
user_id是“记忆隔离”的边界:不要让不同用户共用同一个user_id,否则就会发生“串台记忆”。- 记忆不是“越多越好”:最有效的记忆通常是稳定、可复用的信息(偏好/长期事实/业务约束)。把每句闲聊都存进去,反而会让检索变噪。
从“能跑”到“好用”:记忆层的落地建议
把 Mem0 用好,更多是产品与工程策略,而不是多写几行代码。
1) 先定义“什么算记忆”
一个简单好用的准则:
- 可以长期复用:未来很多次都用得上
- 对结果有明显影响:会改变模型的回答/行为
- 不会频繁变化:或即便变化,也有明确的更新规则
常见适合存的内容:
- 用户偏好:语言、语气、长度、格式(Markdown/表格/代码)
- 个人信息:称呼、时区、常用技术栈(注意隐私与合规)
- 业务约束:公司政策版本、禁用词、输出边界
- 目标/计划:学习目标、健身计划、写作主题偏好
2) 设计“更新”而不是“追加”
很多记忆是会被新信息覆盖的,比如“我现在常用的框架”。如果一直追加,会出现冲突。
实践里常用两种做法:
- 显式更新:你在应用侧检测到“这是对旧偏好的修正”,就更新/替换同类记忆
- 保留时间维度:允许冲突,但存“最近一次”为准,并在检索注入时优先最新
3) 把记忆注入到提示词时,别“喂太多”
把记忆当作“可选提示”,不是“固定上下文”。通常只需要:
- top-k(比如 3~10 条)最相关
- 每条尽量短(偏“事实/偏好”而不是长段落)
TypeScript / Web 应用怎么接?
仓库 README 给了 npm 安装方式(见:mem0ai/mem0):
npm install mem0ai
在 Web/Next.js 里,一般把“记忆检索与写入”放在服务端(API Route / Server Action):
- 请求进来:用
user_id(例如你系统里的用户主键)先检索记忆 - 调用 LLM:把记忆拼到 system prompt 或者专门的
context字段 - 响应返回:把本轮 messages 交给 mem0 写入
具体 API 细节建议直接以官方文档为准(见:docs.mem0.ai)。
部署与选型:托管 vs 自建
Mem0 提供托管平台与开源自建两种路线(仓库介绍见:mem0ai/mem0;官网:mem0.ai):
- 托管:省运维,适合快速上线与中小团队
- 自建:更可控(数据、网络、合规),适合对隐私/内网有要求的场景
你可以从“托管快速验证价值”开始,再决定是否自建迁移。
常见坑(建议你上线前自查)
- 用户隔离:
user_id一定要稳定且唯一;匿名用户要么禁用记忆,要么绑定临时 id - 隐私与安全:不要把密码、密钥、身份证等敏感信息写进记忆;必要时做脱敏/过滤
- 记忆污染:用户一句“你记一下:我最喜欢蓝色”(其实是玩笑)可能被当真。建议对“可写入内容”加规则或二次确认
- 效果评估:上线前用固定用例对比“有/无记忆”的成功率与幻觉率,避免因为记忆注入而引入新偏差
总结
Mem0 的价值不在于“让模型背下所有对话”,而在于把真正重要、可复用的信息沉淀成长期记忆,并在关键时刻检索出来,帮助模型更一致、更个性化、更省 token。
如果你只记住一句:把记忆当成“用户档案 + 关键事实”的结构化输入,而不是聊天记录的堆积,你就已经在正确的路上了。
更多信息与后续深入配置请参考:
- GitHub 仓库: mem0ai/mem0
- 官方文档: docs.mem0.ai