大模型本身是无状态的一次请求结束后模型不会记住你是谁刚刚做过什么如果想让模型知道之前发生了什么我们不得不把历史消息丢给大模型让大模型看到之前的消息这个也只能解决短期的上下文消息不能解决Agent的长期协作问题。一个好用的Agent不能每次都问用户喜欢什么它需要记住用户的偏好记住用户的历史决策以及相关任务状态并且在未来合适的时候能够把这些消息找回来再次丢给大模型让模型可以在当前事件上做出正确的决策。这个就是Agent记忆层的它不是简单的记录了聊天的历史信息需要把历史交互压缩成可检索可追述可演化的长期上下文。之前我们在开发Agent时候一般都是自己写代码来做记忆层包括长期记忆和短期记忆。今天我们来学习一款开源的Agent记忆框架Mem0看看他的实现方式是什么是不是可以直接拿到我们的Agent中使用有没有我们可以借鉴的方法。Agent 如何接入 Mem0github地址 :https://github.com/mem0ai/mem0有59.9k的star官网地址https://mem0.ai/接入Mem0这个记忆框架官方给出了三种方式官方的云端API自建部署服务直接使用sdk这三种方式各有优劣我们直接看 官方给出的对比图这三种记忆方式的代码逻辑都是一样的只是使用方式不一样。个人本地的Agent可以直接使用SDK数据保存在本地如果是企业使用的话可以选择自建host服务。不想自己部署折腾的可以使用官方的云端API。这篇文章我们主要拆解开源SDK的实现大体的架构如下:在开源 Python SDK 里核心入口是 mem0/memory/main.py 里的 Memory 和 AsyncMemory。初始化 Memory() 时它会创建几类组件llm负责从对话中抽取值得记住的事实。embedding_model负责把记忆文本和查询文本向量化。vector_store主记忆库默认是 Qdrant也可以换 pgvector、Redis、Milvus、Pinecone 等。SQLiteManager本地 SQLite保存记忆变更历史和最近消息窗口。entity_store懒加载的实体索引库用来把实体和记忆 ID 连起来。reranker可选负责对召回结果二次排序。记忆这块主要关注点就是写入和检索的流程下面我们来逐一拆解。写入流程从对话到长期记忆核心源码在mem0/memory/main.py其中有一个add()方法用来添加记忆我们来看下它的主要流程是什么这个就是把一个聊天内容整理成长期记忆的过程。Agent把一段新的对话交给add()方法不能只给用户的消息和模型的回复还需要提供一个归属字段例如 user_id,agent_id,run_id这些这样才能区分这个记忆属于谁不然后面检索的时候就无法区分。memory.add( [ { role: user, content: 我下个月要去东京想住精品酒店。我不吃生鱼片帮我以后推荐餐厅时避开寿司 omakase。 }, { role: assistant, content: 好的我之后给你推荐东京餐厅时会避开寿司 omakase并优先考虑适合精品酒店行程的餐厅。 } ], user_idu_123, metadata{app: travel-agent})Mem0 在收到这个消息后不会直接把这个消息保存下来它会先去SQLlite数据库中拿到这个用户的最近的10条消息再去 Vector Store 里找10条相关旧记忆这样系统就知道了聊天的上下文消息以及以前是否聊过这个话题Mem0 把“新对话 最近消息 相关旧记忆”交给 LLMLLM会对这些数据进行整理它要判断这段对话是否有需要长期保存的事实比如用户偏好计划长期目标等。如果只是寒暄这些意义的聊天就不会抽取出新的有记忆LLM会返回一段整理好的文本下面是一个简化版例子来理解它的提示词。真实 prompt 更长会包含很多质量要求和边界条件但核心意思大概是这样你是一个 Memory Extractor。你的任务不是回答用户而是从新对话里抽取值得长期保存的事实。请同时阅读 user 和 assistant 的消息- user 消息里可能有偏好、计划、经历、长期目标- assistant 消息里可能有推荐、方案、安排、已经给出的建议下面是系统已经知道的相关旧记忆只能用来去重和关联不要从旧记忆里重新生成新记忆[ {id: old-1, text: 用户计划 7 月去日本旅行}, {id: old-2, text: 用户喜欢轻松、不赶路的旅行安排}]下面是最近几条对话用来理解上下文user: 上次说的日本行我想把京都多留两天。assistant: 可以那行程可以改成东京 3 天、京都 4 天、大阪 2 天。输出格式要求是只返回能被解析的 JSON不要解释、不要推理过程。结构类似这样{memory: [ { id: 0, text: 一条从新对话里抽取出的长期记忆, attributed_to: user, linked_memory_ids: [相关旧记忆 id] }, { id: 1, text: 另一条从新对话里抽取出的长期记忆, attributed_to: assistant, linked_memory_ids: [] } ]}LLM处理后新的记忆大概会返回这些内容{ memory: [ { id: 0, text: User plans to visit Tokyo next month, attributed_to: user }, { id: 1, text: User prefers boutique hotels, attributed_to: user }, { id: 2, text: User does not eat raw fish and wants future restaurant recommendations to avoid sushi omakase, attributed_to: user } ]}接下来Mem0 会把这些LLM返回的新记忆变成向量它会做一次简单去重如果同样的记忆已经存在就跳过不再重复保存。新记忆会写进 Vector Store 里面。这里的 Vector Store 不是固定某一个数据库而是 Mem0 的向量数据库接口。它默认用的是 Qdrant本地数据默认放在 /tmp/qdrant主记忆 collection 叫 mem0。我们也可以修改默认的配置使用其他的向量数据库那么数据就会保存到指定配置的数据库中。记忆保存后 Mem0 会在 SQLite 里记一条 history它的作用就是记录最近的历史消息方便下一次写入的时候继续理解上下文最后Mem0 会从新记忆里抽取实体写进 Entity StoreADD-only不急着覆盖旧记忆Mem0 v3 的写入策略偏 ADD-only。也就是说新事实默认作为新记忆加入而不是直接覆盖旧记忆。这种和摘要式记忆不同摘要记忆会覆盖原始信息时间信息也会被消除掉例如 用户之前是喜欢喝咖啡后来喜欢喝茶如果只保留一条不断更新的摘要记忆里面就只有一条信息用户喜欢喝茶如果 用户问 我是什么时候开始喜欢喝茶的这个记忆是没有的。ADD-only 的好处是保留事实演化轨迹让时间推理、多跳检索和冲突处理更有空间。如果一直ADD-only 碰到用户偏好和事实就一直添加会不会导致记忆膨胀呢。Memo0在保存记忆的时候 做了两层处理LLM 在看到相关旧记忆后尽量不重复抽取SDK 对新记忆文本计算md5hash如果 hash 已经存在于相关旧记忆或同一批次里已经出现就跳过写入虽然抽取记忆使用了 ADD-only 的机制但是业务系统还是需要显示的记忆维护能力Mem0 同时也提供了update和delete记忆的的方法记忆主存储向量库Vector Store 里面每条记忆会包含下面的信息记忆文本data向量 embedding作用域信息user_id、agent_id、run_id元数据创建时间、更新时间、hash、角色、过期日期等BM25 辅助字段词形还原后的text_lemmatized真正落库时Mem0 会优先走批量路径对抽取出的记忆文本调用embed_batch再一次性insert到向量库。如果 provider 不支持或调用失败才降级成逐条 embedding、逐条 insert。历史记录也是同样的思路优先batch_add_history失败再逐条写。这个细节说明 Mem0 的实现不是 demo 级封装而是考虑了生产场景里的吞吐和失败降级。SQLite 里有两张关键表history和messages。history记录每条 memory 的 ADD、UPDATE、DELETE 事件保存旧值、新值、时间、角色、actor 信息messages保存最近消息窗口并且每个 session scope 只保留最新 10 条。这样Mem0 既能追踪某条记忆如何变化也能在下一次抽取时利用近期对话降低重复。实体索引让记忆之间产生连接Mem0 还有一个独立的 Entity Store。它会从记忆文本中抽取实体例如人名、组织、地点、产品名、被引号包裹的关键词、复合名词短语等然后建立实体 - linked_memory_ids - 多条相关记忆这个和我们常见的知识图谱建立的实体关系不一样它并没有建立实体之间的关系而是将抽离出来的实体和 记忆的数据建立了关系系统可以通过实体查到以往的历史记忆数据。实体写入也有去重逻辑。Mem0 会先按规范化文本做精确匹配比如去掉多余空格、转小写如果没有精确命中再对实体文本做向量搜索分数达到阈值才认为是同一个实体。命中后不是新增实体而是更新这个实体 payload 里的linked_memory_ids。这样一个实体可以逐渐连接越来越多的记忆形成“实体到事件”的索引。一条 Entity Store 里的记录大概可以理解成这样{ id: entity-vector-id-001,vector: embedding(Project Atlas),payload: { data: Project Atlas, entity_type: PROPER, linked_memory_ids: [ memory-id-001, memory-id-002 ], user_id: user-123 }}这里的id是这条实体记录的IDvector是实体文本的向量数据用来做相似搜索里面写成embedding(Project Atlas)只是为了方便阅读真实数据库里会是多维数组 payload.data是实体文的内容linked_memory_ids是最关键的字段表示这个实体关联了哪些长期记忆。user_id、agent_id、run_id这类作用域字段也会一起保存用来保证检索时记忆不会乱串。检索流程Agent 在生成回答前调用memory.search(...)检索相关的长期记忆内容补充给模型消息。Mem0在查询的时候会把用户问题转换成多路查询然后将结果融合排序。想要检索召回的数据质量高就不能简单只做向量检索Mem0 的检索使用三种方式Semantic Scoreembedding 相似度适合语义问题。BM25 Score关键词匹配适合精确词、日期、术语。Entity Boost实体命中后给相关记忆加权适合围绕人、项目、地点、产品的查询。如果配置了 reranker还可以在候选结果上做二次排序处理。在进行BM25 查询的时候会做词形还原可以让关键词匹配更加稳一点。实体检索的时候会先从查询信息里面抽取实体出来Mem0 这里的实体抽取走的是 spaCy NLP 模型 规则没有走大模型调用。抽取实体后把实体文本向量化最后再去Entity Store 里找相似实体。找到之后就可以根据实体关联的记忆id召回相关的原始数据。在检索的时候 查询参数会传一个参数 top k实际检索的时候不会只取top k在内部查询的时候会把这个数量扩大4倍先形成一个候选池前面多召回一点后面在进行融合打分避免过早的丢掉相关记忆。最终融合在score_and_rank里完成。候选记忆先经过语义分数阈值过滤低于 threshold 的结果直接丢弃通过过滤后计算final_score (semantic_score bm25_score entity_boost) / max_possible这里三个分数来源不同semantic_score来自主记忆 Vector Store 的语义相似度。简单说就是这条 memory 和 query 在意思上有多像。它先过threshold太低的候选会直接丢掉。bm25_score来自关键词检索。底层数据库会先给一个 BM25 原始分数Mem0 再把它压到 0 到 1 之间方便和语义分数相加。关键词接近这个分数越高如果底层向量库不支持keyword_search这一项就是 0。entity_boost来自 Entity Store。Mem0 从 query 里抽实体去 Entity Store 里找相似实体。如果某个实体关联了这条 memory这条 memory 就会被加一点分。这个加分最高按ENTITY_BOOST_WEIGHT这个变量控制当前默认是 0.5所以它是加权增强不是直接压过语义检索。max_possible可以理解成归一化的分母用来把总分归一化到 0 到 1 附近。它会根据这次实际启用了哪些检索方式动态变化启用的信号max_possible只有语义检索1.0语义 BM252.0语义 Entity Boost1.5语义 BM25 Entity Boost2.5举个例子如果一条 memory 的语义分数是0.72BM25 归一化后是0.60实体增强是0.30这次三路信号都启用了那么final_score (0.72 0.60 0.30) / 2.5 0.648这样做的话语义、关键词、实体这几个查询结果都能影响排序但最后用 max_possible 做了归一化。不然的话开了 BM25 或实体加成之后分数单纯因为多加了几项就变大并不代表它真的更相关如何把 Mem0 接入自己的 Agent如果我们需要把这个记忆框架接入到Agent中 其实非常简单Agent 回复用户前先检索记忆把相关记忆注入 system/contextAgent 回复后再把这轮对话交给 Mem0 抽取并保存。如果需要将Mem0接入Agent中可以考虑以下原则把作用域设计清楚个人偏好用user_id单次任务用run_idAgent 自身行为或能力沉淀用agent_id。把检索放在推理前先search再把 Top-K 记忆作为上下文给业务 LLM。把写入放在回复后先完成用户响应再异步add避免记忆抽取影响业务回复的速度。用 metadata 做业务隔离例如project_id、workspace_id、category方便后续过滤。高精度场景启用 reranker客服、医疗、法务、企业知识库等场景reranker 通常比单纯向量召回更稳。另外还有一个重要的问题Agent的每一轮回复都需要使用memory.add()方法来抽取长期记忆吗我们可以想象一下 如果是一个写作AgentAgent输出了一个草稿或者说是正文这个内容就很多如果放到Mem0里面去提取实体会提取多少实体出来而这些 我觉得 不应该变成长期记忆。不是所有的Agent都适合Mem0这种长期记忆架构写作Agent这种 在保存记忆之前需要先塞选内容只把合适的内容写入长期记忆。或者说可以将这个memory.add() 封装成工具让Agent按需使用。总结Agent 记忆层的本质就一句话把发生过的事儿存下来保证将来能再翻出来用。Mem0这个框架就是用 LLM 从对话里面抽取关键信息用向量库保存内容SQLite 记录记忆的里信息和最近10条聊天的上下文抽取实体把记忆和实体关联起来。对开发者来说接 Mem0 最需要花心思的不是怎么写几行代码来接入而是想清楚下面这几件事什么内容值得写入记忆怎么隔离不同用户的记忆什么时候需要去查询记忆这几个问题搞明白了Memo0这个记忆框架就会变得非常简单。更多信息见学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
Mem0 vs WorkBuddy:Agent 记忆层的两条路线,谁才是终极答案?
大模型本身是无状态的一次请求结束后模型不会记住你是谁刚刚做过什么如果想让模型知道之前发生了什么我们不得不把历史消息丢给大模型让大模型看到之前的消息这个也只能解决短期的上下文消息不能解决Agent的长期协作问题。一个好用的Agent不能每次都问用户喜欢什么它需要记住用户的偏好记住用户的历史决策以及相关任务状态并且在未来合适的时候能够把这些消息找回来再次丢给大模型让模型可以在当前事件上做出正确的决策。这个就是Agent记忆层的它不是简单的记录了聊天的历史信息需要把历史交互压缩成可检索可追述可演化的长期上下文。之前我们在开发Agent时候一般都是自己写代码来做记忆层包括长期记忆和短期记忆。今天我们来学习一款开源的Agent记忆框架Mem0看看他的实现方式是什么是不是可以直接拿到我们的Agent中使用有没有我们可以借鉴的方法。Agent 如何接入 Mem0github地址 :https://github.com/mem0ai/mem0有59.9k的star官网地址https://mem0.ai/接入Mem0这个记忆框架官方给出了三种方式官方的云端API自建部署服务直接使用sdk这三种方式各有优劣我们直接看 官方给出的对比图这三种记忆方式的代码逻辑都是一样的只是使用方式不一样。个人本地的Agent可以直接使用SDK数据保存在本地如果是企业使用的话可以选择自建host服务。不想自己部署折腾的可以使用官方的云端API。这篇文章我们主要拆解开源SDK的实现大体的架构如下:在开源 Python SDK 里核心入口是 mem0/memory/main.py 里的 Memory 和 AsyncMemory。初始化 Memory() 时它会创建几类组件llm负责从对话中抽取值得记住的事实。embedding_model负责把记忆文本和查询文本向量化。vector_store主记忆库默认是 Qdrant也可以换 pgvector、Redis、Milvus、Pinecone 等。SQLiteManager本地 SQLite保存记忆变更历史和最近消息窗口。entity_store懒加载的实体索引库用来把实体和记忆 ID 连起来。reranker可选负责对召回结果二次排序。记忆这块主要关注点就是写入和检索的流程下面我们来逐一拆解。写入流程从对话到长期记忆核心源码在mem0/memory/main.py其中有一个add()方法用来添加记忆我们来看下它的主要流程是什么这个就是把一个聊天内容整理成长期记忆的过程。Agent把一段新的对话交给add()方法不能只给用户的消息和模型的回复还需要提供一个归属字段例如 user_id,agent_id,run_id这些这样才能区分这个记忆属于谁不然后面检索的时候就无法区分。memory.add( [ { role: user, content: 我下个月要去东京想住精品酒店。我不吃生鱼片帮我以后推荐餐厅时避开寿司 omakase。 }, { role: assistant, content: 好的我之后给你推荐东京餐厅时会避开寿司 omakase并优先考虑适合精品酒店行程的餐厅。 } ], user_idu_123, metadata{app: travel-agent})Mem0 在收到这个消息后不会直接把这个消息保存下来它会先去SQLlite数据库中拿到这个用户的最近的10条消息再去 Vector Store 里找10条相关旧记忆这样系统就知道了聊天的上下文消息以及以前是否聊过这个话题Mem0 把“新对话 最近消息 相关旧记忆”交给 LLMLLM会对这些数据进行整理它要判断这段对话是否有需要长期保存的事实比如用户偏好计划长期目标等。如果只是寒暄这些意义的聊天就不会抽取出新的有记忆LLM会返回一段整理好的文本下面是一个简化版例子来理解它的提示词。真实 prompt 更长会包含很多质量要求和边界条件但核心意思大概是这样你是一个 Memory Extractor。你的任务不是回答用户而是从新对话里抽取值得长期保存的事实。请同时阅读 user 和 assistant 的消息- user 消息里可能有偏好、计划、经历、长期目标- assistant 消息里可能有推荐、方案、安排、已经给出的建议下面是系统已经知道的相关旧记忆只能用来去重和关联不要从旧记忆里重新生成新记忆[ {id: old-1, text: 用户计划 7 月去日本旅行}, {id: old-2, text: 用户喜欢轻松、不赶路的旅行安排}]下面是最近几条对话用来理解上下文user: 上次说的日本行我想把京都多留两天。assistant: 可以那行程可以改成东京 3 天、京都 4 天、大阪 2 天。输出格式要求是只返回能被解析的 JSON不要解释、不要推理过程。结构类似这样{memory: [ { id: 0, text: 一条从新对话里抽取出的长期记忆, attributed_to: user, linked_memory_ids: [相关旧记忆 id] }, { id: 1, text: 另一条从新对话里抽取出的长期记忆, attributed_to: assistant, linked_memory_ids: [] } ]}LLM处理后新的记忆大概会返回这些内容{ memory: [ { id: 0, text: User plans to visit Tokyo next month, attributed_to: user }, { id: 1, text: User prefers boutique hotels, attributed_to: user }, { id: 2, text: User does not eat raw fish and wants future restaurant recommendations to avoid sushi omakase, attributed_to: user } ]}接下来Mem0 会把这些LLM返回的新记忆变成向量它会做一次简单去重如果同样的记忆已经存在就跳过不再重复保存。新记忆会写进 Vector Store 里面。这里的 Vector Store 不是固定某一个数据库而是 Mem0 的向量数据库接口。它默认用的是 Qdrant本地数据默认放在 /tmp/qdrant主记忆 collection 叫 mem0。我们也可以修改默认的配置使用其他的向量数据库那么数据就会保存到指定配置的数据库中。记忆保存后 Mem0 会在 SQLite 里记一条 history它的作用就是记录最近的历史消息方便下一次写入的时候继续理解上下文最后Mem0 会从新记忆里抽取实体写进 Entity StoreADD-only不急着覆盖旧记忆Mem0 v3 的写入策略偏 ADD-only。也就是说新事实默认作为新记忆加入而不是直接覆盖旧记忆。这种和摘要式记忆不同摘要记忆会覆盖原始信息时间信息也会被消除掉例如 用户之前是喜欢喝咖啡后来喜欢喝茶如果只保留一条不断更新的摘要记忆里面就只有一条信息用户喜欢喝茶如果 用户问 我是什么时候开始喜欢喝茶的这个记忆是没有的。ADD-only 的好处是保留事实演化轨迹让时间推理、多跳检索和冲突处理更有空间。如果一直ADD-only 碰到用户偏好和事实就一直添加会不会导致记忆膨胀呢。Memo0在保存记忆的时候 做了两层处理LLM 在看到相关旧记忆后尽量不重复抽取SDK 对新记忆文本计算md5hash如果 hash 已经存在于相关旧记忆或同一批次里已经出现就跳过写入虽然抽取记忆使用了 ADD-only 的机制但是业务系统还是需要显示的记忆维护能力Mem0 同时也提供了update和delete记忆的的方法记忆主存储向量库Vector Store 里面每条记忆会包含下面的信息记忆文本data向量 embedding作用域信息user_id、agent_id、run_id元数据创建时间、更新时间、hash、角色、过期日期等BM25 辅助字段词形还原后的text_lemmatized真正落库时Mem0 会优先走批量路径对抽取出的记忆文本调用embed_batch再一次性insert到向量库。如果 provider 不支持或调用失败才降级成逐条 embedding、逐条 insert。历史记录也是同样的思路优先batch_add_history失败再逐条写。这个细节说明 Mem0 的实现不是 demo 级封装而是考虑了生产场景里的吞吐和失败降级。SQLite 里有两张关键表history和messages。history记录每条 memory 的 ADD、UPDATE、DELETE 事件保存旧值、新值、时间、角色、actor 信息messages保存最近消息窗口并且每个 session scope 只保留最新 10 条。这样Mem0 既能追踪某条记忆如何变化也能在下一次抽取时利用近期对话降低重复。实体索引让记忆之间产生连接Mem0 还有一个独立的 Entity Store。它会从记忆文本中抽取实体例如人名、组织、地点、产品名、被引号包裹的关键词、复合名词短语等然后建立实体 - linked_memory_ids - 多条相关记忆这个和我们常见的知识图谱建立的实体关系不一样它并没有建立实体之间的关系而是将抽离出来的实体和 记忆的数据建立了关系系统可以通过实体查到以往的历史记忆数据。实体写入也有去重逻辑。Mem0 会先按规范化文本做精确匹配比如去掉多余空格、转小写如果没有精确命中再对实体文本做向量搜索分数达到阈值才认为是同一个实体。命中后不是新增实体而是更新这个实体 payload 里的linked_memory_ids。这样一个实体可以逐渐连接越来越多的记忆形成“实体到事件”的索引。一条 Entity Store 里的记录大概可以理解成这样{ id: entity-vector-id-001,vector: embedding(Project Atlas),payload: { data: Project Atlas, entity_type: PROPER, linked_memory_ids: [ memory-id-001, memory-id-002 ], user_id: user-123 }}这里的id是这条实体记录的IDvector是实体文本的向量数据用来做相似搜索里面写成embedding(Project Atlas)只是为了方便阅读真实数据库里会是多维数组 payload.data是实体文的内容linked_memory_ids是最关键的字段表示这个实体关联了哪些长期记忆。user_id、agent_id、run_id这类作用域字段也会一起保存用来保证检索时记忆不会乱串。检索流程Agent 在生成回答前调用memory.search(...)检索相关的长期记忆内容补充给模型消息。Mem0在查询的时候会把用户问题转换成多路查询然后将结果融合排序。想要检索召回的数据质量高就不能简单只做向量检索Mem0 的检索使用三种方式Semantic Scoreembedding 相似度适合语义问题。BM25 Score关键词匹配适合精确词、日期、术语。Entity Boost实体命中后给相关记忆加权适合围绕人、项目、地点、产品的查询。如果配置了 reranker还可以在候选结果上做二次排序处理。在进行BM25 查询的时候会做词形还原可以让关键词匹配更加稳一点。实体检索的时候会先从查询信息里面抽取实体出来Mem0 这里的实体抽取走的是 spaCy NLP 模型 规则没有走大模型调用。抽取实体后把实体文本向量化最后再去Entity Store 里找相似实体。找到之后就可以根据实体关联的记忆id召回相关的原始数据。在检索的时候 查询参数会传一个参数 top k实际检索的时候不会只取top k在内部查询的时候会把这个数量扩大4倍先形成一个候选池前面多召回一点后面在进行融合打分避免过早的丢掉相关记忆。最终融合在score_and_rank里完成。候选记忆先经过语义分数阈值过滤低于 threshold 的结果直接丢弃通过过滤后计算final_score (semantic_score bm25_score entity_boost) / max_possible这里三个分数来源不同semantic_score来自主记忆 Vector Store 的语义相似度。简单说就是这条 memory 和 query 在意思上有多像。它先过threshold太低的候选会直接丢掉。bm25_score来自关键词检索。底层数据库会先给一个 BM25 原始分数Mem0 再把它压到 0 到 1 之间方便和语义分数相加。关键词接近这个分数越高如果底层向量库不支持keyword_search这一项就是 0。entity_boost来自 Entity Store。Mem0 从 query 里抽实体去 Entity Store 里找相似实体。如果某个实体关联了这条 memory这条 memory 就会被加一点分。这个加分最高按ENTITY_BOOST_WEIGHT这个变量控制当前默认是 0.5所以它是加权增强不是直接压过语义检索。max_possible可以理解成归一化的分母用来把总分归一化到 0 到 1 附近。它会根据这次实际启用了哪些检索方式动态变化启用的信号max_possible只有语义检索1.0语义 BM252.0语义 Entity Boost1.5语义 BM25 Entity Boost2.5举个例子如果一条 memory 的语义分数是0.72BM25 归一化后是0.60实体增强是0.30这次三路信号都启用了那么final_score (0.72 0.60 0.30) / 2.5 0.648这样做的话语义、关键词、实体这几个查询结果都能影响排序但最后用 max_possible 做了归一化。不然的话开了 BM25 或实体加成之后分数单纯因为多加了几项就变大并不代表它真的更相关如何把 Mem0 接入自己的 Agent如果我们需要把这个记忆框架接入到Agent中 其实非常简单Agent 回复用户前先检索记忆把相关记忆注入 system/contextAgent 回复后再把这轮对话交给 Mem0 抽取并保存。如果需要将Mem0接入Agent中可以考虑以下原则把作用域设计清楚个人偏好用user_id单次任务用run_idAgent 自身行为或能力沉淀用agent_id。把检索放在推理前先search再把 Top-K 记忆作为上下文给业务 LLM。把写入放在回复后先完成用户响应再异步add避免记忆抽取影响业务回复的速度。用 metadata 做业务隔离例如project_id、workspace_id、category方便后续过滤。高精度场景启用 reranker客服、医疗、法务、企业知识库等场景reranker 通常比单纯向量召回更稳。另外还有一个重要的问题Agent的每一轮回复都需要使用memory.add()方法来抽取长期记忆吗我们可以想象一下 如果是一个写作AgentAgent输出了一个草稿或者说是正文这个内容就很多如果放到Mem0里面去提取实体会提取多少实体出来而这些 我觉得 不应该变成长期记忆。不是所有的Agent都适合Mem0这种长期记忆架构写作Agent这种 在保存记忆之前需要先塞选内容只把合适的内容写入长期记忆。或者说可以将这个memory.add() 封装成工具让Agent按需使用。总结Agent 记忆层的本质就一句话把发生过的事儿存下来保证将来能再翻出来用。Mem0这个框架就是用 LLM 从对话里面抽取关键信息用向量库保存内容SQLite 记录记忆的里信息和最近10条聊天的上下文抽取实体把记忆和实体关联起来。对开发者来说接 Mem0 最需要花心思的不是怎么写几行代码来接入而是想清楚下面这几件事什么内容值得写入记忆怎么隔离不同用户的记忆什么时候需要去查询记忆这几个问题搞明白了Memo0这个记忆框架就会变得非常简单。更多信息见学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】