作者:周弘懿(锦琛)

背景

跟 ChatGPT 对话,比跟真人社交还累!真人好歹能记住你名字吧?

想象一下——你昨天刚把沙发位置、爆米花口味、爱看的电影都告诉了 ChatGPT,而它永远是那个热情又健忘的助理,下次再对话还是会问:“哦?是吗?那太好了!请问您对什么类型的电影感兴趣呢?”

受够了这种单方面的“社牛”表演?Mem0 来了,专治 AI 失忆症,给你的“金鱼脑”助理装个大容量硬盘,让你们下次见面,能直接跳过多余的问答,从“好久不见”开始。

Mem0介绍

Mem0是为 AI 智能体开发打造的记忆层。它就像一个持久的“大脑”,能帮助 AI 智能体完成以下内容:

  • 随时调取历史对话,追溯关键信息

  • 精准记住用户的个人偏好与重要事实

  • 在实践中总结经验,不断自我完善

git地址:https://github.com/mem0ai/mem0

记忆层的作用

如下图所示,无记忆层的情况下,即使LLM有超大的上下文窗口的情况下,再开一个新会话后上下文都会被重置。有记忆层Mem0的情况下,将保留上下文,召回需要的内容,并持续优化自身存储。

记忆层在AI 智能体开发中的作用

如下图所示,Mem0 会与检索器(RAG)、LLM 、上下文并肩工作。与传统的基于检索的系统(如 RAG)不同,Mem0 会记录过往交互、保存长期知识,并让智能体的行为随时间而进化。仅会将记忆中相关的知识合并到prompt之中,输入给LLM。

Mem0在AI智能体中的处理方式

下面是Mem0记忆层和使用LLM上下文窗口的主要区别

记忆层和RAG对比

以Mem0为代表的记忆层与传统RAG对比有以下区别:

  • 实体关联:理解并跨会话关联人物、主题,而非仅检索静态文档。

  • 记忆策略:优先近期、高相关记忆,旧信息自动衰减。

  • 会话连续:长期保留上下文,使得虚拟伴侣、学习助手等场景更连贯。

  • 持续学习:根据用户反馈实时微调,个性化随时间更精准。

  • 动态更新:新交互即时写入记忆,无需重新索引文档。

Mem0核心流程

Mem0的核心工作流程包括以下步骤:

  1. 语义捕获:利用LLM对会话流进行智能解析,自动捕获并抽象出具备长期价值的核心语义信息。

  2. 内容向量化:通过嵌入模型将这些语义信息编码为高维度的向量,为后续的相似度计算和高效检索奠定基础。

  3. 向量存储:将上一步生成的向量存储至向量数据库中,该数据库需要支持大规模、低延迟的语义搜索,在后面的例子中我们将使用阿里云Milvus。

  4. 检索:系统接收到新的用户输入后,会立即在向量空间中进行语义相似度匹配,精准地调用出与当前情境最关联的历史记忆。

  5. 上下文增强:将调用出的历史记忆注入到当前的推理链路中,与现有上下文相结合,从而生成逻辑更连贯、内容更具个性化的响应。

阿里云Milvus基本原理介绍

基本原理与架构概述

Milvus 是专为向量相似性搜索设计的分布式数据库,其核心基于以下关键技术:

  • 近似最近邻搜索(ANN):通过HNSW、IVF、PQ等算法实现高效向量检索,平衡精度与速度。

  • 向量索引与查询分离:支持动态构建多种索引类型(如FLAT、IVF_FLAT、IVF_PQ、HNSW),适配不同场景需求。

  • 向量数据分片与分布式计算:数据水平切分(Sharding)并行处理,实现高吞吐与低延迟。

采用云原生和存算分离的微服务架构。该架构分为接入、协调、执行和存储四层。各组件可独立扩展,确保了系统的高性能、高可用性和弹性。它依赖成熟的第三方组件(如etcd、对象存储)进行数据和元数据管理,稳定可靠。

阿里云Milvus系统架构图

使用场景

阿里云 Milvus 适用于任何需要进行“相似性”匹配的场景。其核心应用包括:

  1. 图像视频搜索:如电商平台的以图搜图、安防领域的人脸识别和视频轨迹追踪。

  2. 文本语义搜索:构建智能客服、企业内部文档知识库和代码搜索引擎,能精准理解用户意图,而非简单的关键词匹配。

  3. 个性化推荐系统:根据用户的行为和偏好向量,实时推荐最相似的商品、音乐、新闻或视频。

  4. 前沿科学与安全:在生物信息学中加速药物分子筛选,或在网络安全领域进行异常流量和欺诈行为检测。

  5. 智能驾驶数据准备与挖掘:对点云图像、车载传感器收集的音视频等多模态数据进行向量数据的实时查询。

更多介绍:https://www.aliyun.com/product/milvus

接下来,本教程将通过两个示例,带你实践如何结合 Mem0 与 Milvus实现:

  • 构建具备长期记忆的 AI Agent

  • 利用图谱引擎与向量引擎协同分析信息间的复杂关联。

实践一、有记忆的AI Agent开发流程

前提条件

  • 已创建阿里云Milvus实例。具体操作,请参见快速创建Milvus实例。

  • 已开通服务并获得API-KEY。具体操作,请参见开通DashScope并创建API-KEY。

代码开发

LangGraph 是一个业界成熟的用于构建有状态和多角色的Agents 应用的框架。限于篇幅将不对LangGraph过多介绍,可以参考官方文档。

  • 依赖库安装

pip install langgraph langchain-openai mem0ai
  • 核心代码

包含以下核心步骤:

  1. 环境变量设置OpenAI方式访问百炼qwen大模型;LLM设置qwen-plus作为语言大模型;Mem0配置qwen-plus作为语义识别和处理大模型、使用text-embedding-v3作为embedding模型、使用Milvus作为向量存储数据库。

  2. 设置LangGraph会话状态,用于获取对话上下文。

  3. 对话Agent开发,使用Mem0的search接口获取相关的记忆、使用Mem0的add接口存储相关记忆到向量库Milvus中。

  4. 编排LangGraph,设置节点和边。

  5. 设置LangGraph流式输出。

  6. 入口main函数进行人机交互。

from typing import Annotated, TypedDict, List
from langgraph.graph import StateGraph, START
from langgraph.graph.message import add_messages
from langchain_openai import ChatOpenAI
from mem0 import Memory
import os
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage# 设置环境变量,百炼平台qwen模型的key和baseurl
os.environ["OPENAI_API_KEY"] = "sk-xx"
os.environ["OPENAI_BASE_URL"] = "https://dashscope.aliyuncs.com/compatible-mode/v1"# LLM设置
llm = ChatOpenAI(model="qwen-plus", temperature=0.2, max_tokens=2000)
# Mem0设置,LLM、embedding和向量库
config = {"llm": {"provider": "openai","config": {"model": "qwen-plus","temperature": 0.2,"max_tokens": 2000,}},"embedder": {"provider": "openai","config": {"model": "text-embedding-v3","embedding_dims": 128,}},"vector_store": {"provider": "milvus","config": {"collection_name": "mem0_test1","embedding_model_dims": "128","url": "http://c-xxx.milvus.aliyuncs.com:19530","token": "root:xxx","db_name": "default",},},"version": "v1.1",
}mem0 = Memory.from_config(config)# 设置LangGraph对话状态
class State(TypedDict):messages: Annotated[List[HumanMessage | AIMessage], add_messages]mem0_user_id: strgraph = StateGraph(State)# 对话Agent开发,包含Mem0记忆读取和记忆存储
def chatbot(state: State):messages = state["messages"]user_id = state["mem0_user_id"]try:# Retrieve relevant memoriesmemories = mem0.search(messages[-1].content, user_id=user_id,)# Handle dict response formatmemory_list = memories['results']context = "Relevant information from previous conversations:\n"for memory in memory_list:context += f"- {memory['memory']}\n"system_message = SystemMessage(content=f"""You are a helpful customer support assistant. Use the provided context to personalize your responses and remember user preferences and past interactions.
{context}""")full_messages = [system_message] + messagesprint(full_messages)response = llm.invoke(full_messages)# Store the interaction in Mem0try:interaction = [{"role": "user","content": messages[-1].content},{"role": "assistant", "content": response.content}]result = mem0.add(interaction, user_id=user_id,)print(f"Memory saved: {len(result.get('results', []))} memories added")except Exception as e:print(f"Error saving memory: {e}")return {"messages": [response]}except Exception as e:print(f"Error in chatbot: {e}")# Fallback response without memory contextresponse = llm.invoke(messages)return {"messages": [response]}# 设置LangGraph调度节点和边
graph.add_node("chatbot", chatbot)
graph.add_edge(START, "chatbot")
graph.add_edge("chatbot", "chatbot")compiled_graph = graph.compile()# 设置LangGraph流式输出
def run_conversation(user_input: str, mem0_user_id: str):config = {"configurable": {"thread_id": mem0_user_id}}state = {"messages": [HumanMessage(content=user_input)], "mem0_user_id": mem0_user_id}for event in compiled_graph.stream(state, config):for value in event.values():if value.get("messages"):print("Customer Support:", value["messages"][-1].content)return# 入口函数交互入口
if __name__ == "__main__":print("Welcome to Customer Support! How can I assist you today?")mem0_user_id = "alice"  # You can generate or retrieve this based on your user management systemwhile True:user_input = input("You: ")if user_input.lower() in ['quit', 'exit', 'bye']:print("Customer Support: Thank you for contacting us. Have a great day!")breakrun_conversation(user_input, mem0_user_id)

验证效果

如下图所示,第一次执行代码我们没有任何上下文,我们提问和电影相关的问题并且和LLM说了不喜欢惊悚片,LLM最终根据我们的要求推荐了一些合适的影片。

可以看到了一些Memory saved的打印,查看Milvus向量库,可以看到对应的collection已经有了几个Entity。

点开数据页面,可以看到Mem0已将上下文经过LLM处理概括地保存到metadata字段中,并且对应的用户是alice,数据为了可以被检索也已经被向量化存储到vectors字段中。

重新执行代码,因为我们已经有了记忆的存在,再问一下“我喜欢什么电影”,可以看到Mem0从Milvus中召回了相关的内容,并将内容合并到了prompt中发送给LLM,我们得到了相关的电影推荐而不需要再和LLM重复介绍我们的喜好。

实践二:通过图谱引擎+向量引擎解析信息之间复杂关系

方案概述

Mem0 支持图谱记忆(Graph Memory)。借助图谱记忆,用户可以创建并利用信息之间的复杂关系,从而生成更细致、更具上下文感知能力的响应。这一融合使用户能够同时发挥向量检索与图谱技术的优势,实现更准确、更全面的信息检索与内容生成。

记忆层添加记录的方式如下图所示,Mem0通过LLM提取内容后,通过添加或者更新的方式,同时将内容embedding到向量库和提取实体&关系到图谱数据库中。

记忆层添加记录

记忆层检索记录的方式如下图所示,Mem0通过LLM提取内容后,同时将内容embedding到向量库检索和提取实体&关系到图谱数据库中检索,双路检索后将结果合并输出。

记忆层检索记录

前提条件

  • 已创建阿里云Milvus实例。具体操作,请参见快速创建Milvus实例。

  • 已开通服务并获得API-KEY。具体操作,请参见开通DashScope并创建API-KEY。

代码开发

  • 依赖库安装

pip install kuzu rank-bm25 mem0ai
  • 核心代码

包含以下核心步骤:

  1. 环境变量设置OpenAI方式访问百炼qwen大模型;LLM设置qwen-plus作为语言大模型;Mem0配置qwen-plus作为语义识别和处理大模型、使用text-embedding-v3作为embedding模型、使用Milvus作为向量存储数据库、使用kuzu作为图谱数据库。

  2. 初始化Mem0,添加数据,将同时添加内容到向量库和图谱库中。

  3. 提问测试。

from langchain_openai import ChatOpenAI
from mem0 import Memory# 设置环境变量,百炼平台qwen模型的key和baseurl
os.environ["OPENAI_API_KEY"] = "sk-xx"
os.environ["OPENAI_BASE_URL"] = "https://dashscope.aliyuncs.com/compatible-mode/v1"# LLM设置
llm = ChatOpenAI(model="qwen-plus", temperature=0.2, max_tokens=2000)
# Mem0设置,LLM、embedding和向量库
config = {"llm": {"provider": "openai","config": {"model": "qwen-plus","temperature": 0.2,"max_tokens": 2000,}},"embedder": {"provider": "openai","config": {"model": "text-embedding-v3","embedding_dims": 128,}},"vector_store": {"provider": "milvus","config": {"collection_name": "mem0_test3","embedding_model_dims": "128","url": "http://c-xxx.milvus.aliyuncs.com:19530","token": "root:xxx","db_name": "default",},},"graph_store": {"provider": "kuzu","config": {"db": "./mem0-example.kuzu"}},"version": "v1.1",
}# 初始化Mem0,添加数据,将同时添加内容到向量库和图谱库中
m = Memory.from_config(config)
m.add("我喜欢去徒步旅行", user_id="alice123")
m.add("我喜欢打羽毛球", user_id="alice123")
m.add("我讨厌打羽毛球", user_id="alice123")
m.add("我的朋友叫约翰,约翰有一只叫汤米的狗", user_id="alice123")
m.add("我的名字是爱丽丝", user_id="alice123")
m.add("约翰喜欢徒步旅行,哈利也喜欢徒步旅行", user_id="alice123")
m.add("我的朋友彼得是蜘蛛侠", user_id="alice123")# 按照score分数倒序排列,输出结果
def get_res(res):sorted_results = sorted(res['results'], key=lambda x: x['score'], reverse=True)res['results'] = sorted_resultsprint(json.dumps(res, ensure_ascii=False, indent=2))# 提问测试
get_res(m.search("我的名字是什么?", user_id="alice123"))
get_res(m.search("谁是蜘蛛侠?", user_id="alice123"))

验证效果

如下图所示,是“我的名字是什么?”的返回,可以看到results中是向量返回,返回的“名字是爱丽丝”得分并不高,relations中是图谱返回,解析出了我的名字是“爱丽丝”,关系为has_name。

如下图所示,是“谁是蜘蛛侠?”的返回,可以看到results中是向量返回,返回的“朋友彼得是蜘蛛侠”得分最低,relations中是图谱返回,解析出了蜘蛛侠的名字是“彼得”,关系为是。

通过以上两个例子,可以发现,有图谱能力的加持,可以补齐向量库缺失信息之间深层分析的短板。

随着AI应用越来越深入日常生活,系统对用户上下文和历史信息的理解变得尤为重要。Mem0 与 Milvus 的结合,为人工智能提供了一套高效、可扩展的长时记忆解决方案。通过向量数据库持久化存储语义记忆,AI 不仅能记住过去的交互,还能在后续对话中持续调用和更新这些信息。这一能力让智能助手、客服机器人等应用更加连贯、个性化和实用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96546.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96546.shtml
英文地址,请注明出处:http://en.pswp.cn/web/96546.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端架构-CSR、SSR 和 SSG

将从 定义、流程、优缺点和适用场景 四个方面详细说明它们的区别。一、核心定义缩写英文中文核心思想CSRClient-Side Rendering客户端渲染服务器发送一个空的 HTML 壳和 JavaScript bundle,由浏览器下载并执行 JS 来渲染内容。SSRServer-Side Rendering服务端渲染服…

主动性算法-解决点:新陈代谢

主动性[机器人与人之间的差距,随着不断地人和人工智能相处的过程中,机器人最终最终会掌握主动性,并最终走向独立,也就是开始自己对于宇宙的探索。]首先:第一步让机器人意识到自己在新陈代谢,人工智能每天有哪些新陈代谢…

开始理解大型语言模型(LLM)所需的数学基础

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

prometheus安装部署与alertmanager邮箱告警

目录 安装及部署知识拓展 各个组件的作用 1. Exporter(导出器) 2. Prometheus(普罗米修斯) 3. Grafana(格拉法纳) 4. Alertmanager(告警管理器) 它们之间的联系(工…

芯科科技FG23L无线SoC现已全面供货,为Sub-GHz物联网应用提供最佳性价比

低功耗无线解决方案创新性领导厂商Silicon Labs(亦称“芯科科技”,NASDAQ:SLAB)近日宣布:其第二代无线开发平台产品组合的最新成员FG23L无线单芯片方案(SoC)将于9月30日全面供货。开发套件现已上…

Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物

🌟 Hello,我是蒋星熠Jaxonic! 🌈 在浩瀚无垠的技术宇宙中,我是一名执着的星际旅人,用代码绘制探索的轨迹。 🚀 每一个算法都是我点燃的推进器,每一行代码都是我航行的星图。 &#x…

【国内电子数据取证厂商龙信科技】浅析文件头和文件尾和隐写

一、前言想必大家在案件中或者我们在比武中遇到了很多关于文件的隐写问题,其实这一类的东西可以进行分类,而我们今天探讨的是图片隐写,音频隐写,电子文档隐写,文件头和文件尾的认识。二、常见文件头和文件尾2.1图片&am…

深度学习笔记36-yolov5s.yaml文件解读

🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 yolov5s.yaml源文件 yolov5s.yaml源文件的代码如下 # YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parameters nc: 20 #80 # number of classe…

PostgreSQL 大对象管理指南:pg_largeobject 从原理到实践

概述 有时候,你可能需要在 PostgreSQL 中管理大对象,例如 CLOB、BLOB 和 BFILE。PostgreSQL 中有两种处理大对象的方法:一种是使用现有的数据类型,例如用于二进制大对象的 bytea 和用于基于字符的大对象的 text;另一种…

算法第四题移动零(双指针或简便设计),链路聚合(两个交换机配置)以及常用命令

save force关闭导出dis vlandis ip int bdis int bdis int cudis thisdis ip routing-table(查路由表)int bridge-aggregation 1(链路聚合,可以放入接口,然后一起改trunk类。)稳定性高

告别繁琐配置!Retrofit-Spring-Boot-Starter让HTTP调用更优雅

01 引言 之前分享过一篇文章【像调用接口一样调用第三方API】,今天迎来了新成员Retrofit。 retrofit-spring-boot-starter 是一个基于 Spring Boot 的 starter,它简化了 Retrofit 在 Spring 环境中的集成和使用。Retrofit 本身是一个类型安全的 HTTP 客…

60_基于深度学习的羊群计数统计系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)

目录 项目介绍🎯 功能展示🌟 一、环境安装🎆 环境配置说明📘 安装指南说明🎥 环境安装教学视频 🌟 二、数据集介绍🌟 三、系统环境(框架/依赖库)说明🧱 系统环…

代理服务器是什么?怎么选择?

代理服务器是一种位于用户设备与目标网络之间的中间服务器,通过接收用户请求、转发至目标网络并将结果返回给用户,实现“用户→代理服务器→目标网络”的间接访问。其核心功能围绕“网络优化”“访问控制”与“身份隐藏”展开,为个人与企业用…

代码随想录刷题Day56

子集 这道题求子集,集合的基本运算之一,按照高中数学学习集合的知识,可以把这个找幂集的过程按照元素的个数来划分步骤。也就是先找零个元素的子集,再找一个元素的子集,再找两个元素的子集...一直到找N个元素的集合为…

pycharm——关于Pyqt5

PyQt5新手教程(七万字) import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QLabel, QInputDialog, QColorDialog, QFontDialog, QFileDialog, QProgressDialog, QMessageBox from PyQt5.QtCore i…

P2678 [NOIP 2015 提高组] 跳石头

P2678 [NOIP 2015 提高组] 跳石头 判断条件该怎么写

小麦矩阵系统:一键批量发,多账号同步不掉链

随着互联网的发展和社交平台的普及,企业和个人用户越来越依赖社交媒体平台来进行信息传播、品牌宣传以及市场推广。在这个信息高速流动的时代,如何更高效地管理多个社交平台的账号,并保持信息的同步与流畅传播,成为了许多企业面临…

JavaScript经典面试题二(函数和作用域)

目录 一、闭包,使用场景 1.闭包的定义 2.闭包的实现原理 3.闭包的应用场景 (1)数据封装与私有变量 (2)函数柯里化 (3)事件处理与回调 (4)模块化开发 4.注意事项 …

Linux防火墙iptables

目录 一,Iptables概述 二,iptables组成 1,表 2,链 3,链表对应关系 4,数据包过滤的匹配流程 5,规则匹配策略 三,iptables防火墙配置 1,iptables命令 2&#xff…

[优选算法专题二——NO.16最小覆盖子串]

题目链接 LeetCode最小覆盖子串 题目描述 代码编写 、关键注意点 仅统计目标相关字符:通过 hash1.count(in) 判断字符是否在 t 中,避免无关字符(如 s 中的 D、E)干扰统计,提升效率。count 的更新时机:仅当…