Chainlit集成Mem0使用一个拥有个性化AI记忆的网页聊天应用

前言

Mem0 简介,可以看我上一篇文章《解决LLM的永久记忆的解决方案-Mem0实现个性化AI永久记忆功能》。本篇文章是对Mem0 实战使用的一个示例。通过Chainlit 快速实现ui界面和open ai的接入,通过使用Mem0 实现对聊天者的对话记录的记忆。

设计实现基本原理

  • 用户每次发送消息时,会通过ai的调用,总结用户发送的消息,并将总结后的消息进行向量化的存储
  • 在总结消息后到向量化存储的过程中,会先用总结后的消息,进行向量化检索,检查出最相关的前5条数据,并把用户最新总结的消息和从数据库查询出来最相关的5条数据交给ai,让AI根据相关度来判断是否选择调用 数据库增加方法、修改方法或者删除方法。
  • 用户记忆搜索的逻辑,就是从更具用户ID和用户问题,从向量数据库查询相关的记录(可以设置具体返回几条最相关)以提示词的方式交给 AI,作为AI的记忆。
  • Mem0 还支持neo4j图数据库,通过提取三元组的数据,和对三元组数据的查询作为AI的记忆,提示AI记忆检索的广度。

快速上手

创建一个文件,例如“chainlit_chat”

mkdir chainlit_chat

进入 chainlit_chat文件夹下,执行命令创建python 虚拟环境空间(需要提前安装好python sdkChainlit 需要python>=3.8。,具体操作,由于文章长度问题就不在叙述,自行百度),命令如下:

python -m venv .venv
  • 这一步是避免python第三方库冲突,省事版可以跳过
  • .venv是创建的虚拟空间文件夹可以自定义

接下来激活你创建虚拟空间,命令如下:

#linux or mac
source .venv/bin/activate
#windows
.venv\Scripts\activate

在项目根目录下创建requirements.txt,内容如下:

chainlit
mem0

在项目根目录下创建.env环境变量,配置如下:

OPENAI_BASE_URL="open地址或者代理地址"
OPENAI_API_KEY="your-api-key"
  • OPENAI_BASE_URL 是 openai的api 的base地址,如果你能直接使用openai,这可以不设置,也可以设置成openai兼容的代理地址,注意代理服务要能兼容openai向量化接口
  • OPENAI_API_KEY 替换成你自己的API 密匙

执行以下命令安装依赖:

pip install -r .\requirements.txt
  • 安装后,项目根目录下会多出.chainlit.files文件夹和chainlit.md文件

在项目根目录下创建app.py文件,代码如下:

import chainlit as clfrom personalai_tutor import PersonalAITutor@cl.on_chat_start
async def on_chat_start():ai_tutor = PersonalAITutor()cl.user_session.set("ai_tutor", ai_tutor)@cl.on_message
async def on_message(message: cl.Message):ai_tutor = cl.user_session.get("ai_tutor")msg = cl.Message(content="")response = await ai_tutor.ask(question=message.content, user_id="tarzan")async for part in response:if token := part.choices[0].delta.content or "":await msg.stream_token(token)await msg.update()

在项目根目录下创建personalai_tutor.py文件,代码如下:

import threading
from typing import Optional, Listfrom mem0 import Memory
from mem0.configs.prompts import MEMORY_ANSWER_PROMPT
from openai import AsyncOpenAIMEMORY_DEDUCTION_PROMPT = """
从所提供的文本中推断出事实、偏好和记忆。
只需将事实、偏好和记忆以要点形式返回即可:
自然语言文本:{user_input}
User/Agent详细信息:{metadata}推断:推断事实、偏好和记忆的限制:
-事实、偏好和记忆应该简明扼要。
-不要以“这个人喜欢披萨”开头。相反,从“喜欢披萨”开始。
-不记得提供的用户/代理详细信息。只记住事实、偏好和回忆。推断出的事实、偏好和记忆:
"""def _format_query_with_memories(messages, relevant_memories):memories_text = "\n".join(memory["memory"] for memory in relevant_memories)return f"- Relevant Memories/Facts: {memories_text}\n\n- User Question: {messages[-1]['content']}"def _prepare_messages(messages: List[dict]) -> List[dict]:if not messages or messages[0]["role"] != "system":return [{"role": "system", "content": MEMORY_ANSWER_PROMPT}] + messagesmessages[0]["content"] = MEMORY_ANSWER_PROMPTreturn messagesclass PersonalAITutor:def __init__(self):"""Initialize the PersonalAITutor with memory configuration and OpenAI client."""config = {'llm': {'config': {'openai_base_url': 'https://dashscope.aliyuncs.com/compatible-mode/v1','api_key': 'api_key','model': 'qwen-plus'}},'vector_store': {'provider': 'chroma','config': {'path': 'chroma',}},'embedder': {'config': {'openai_base_url': 'https://open.bigmodel.cn/api/paas/v4','api_key': 'api_key','model': 'embedding-3'}}}self.memory = Memory.from_config(config)self.client = AsyncOpenAI(base_url='https://dashscope.aliyuncs.com/compatible-mode/v1',api_key='api_key')def ask(self, question: Optional[str] = None, agent_id: Optional[str] = None, run_id: Optional[str] = None,metadata: Optional[dict] = None,filters: Optional[dict] = None,user_id=None, limit: Optional[int] = 10):"""Ask a question to the AI and store the relevant facts in memory:param run_id::param limit::param filters::param metadata::param agent_id::param question: The question to ask the AI.:param user_id: Optional user ID to associate with the memory."""if not any([user_id]):raise ValueError("One of user_id must be provided")messages = [{"role": "system", "content": "你是一个私人的AI助理。"},{"role": "user", "content": question}]prepared_messages = _prepare_messages(messages)if prepared_messages[-1]["role"] == "user":self._async_add_to_memory(question, user_id, agent_id, run_id, metadata, filters)relevant_memories = self._fetch_relevant_memories(question, user_id, agent_id, run_id, filters, limit)print('relevant_memories', relevant_memories)prepared_messages[-1]["content"] = _format_query_with_memories(messages, relevant_memories)print('prepared_messages', prepared_messages)stream = self.client.chat.completions.create(model="qwen-plus",stream=True,messages=prepared_messages)return streamdef get_user_memories(self, user_id=None):"""Retrieve all memories associated with the given user ID.:param user_id: Optional user ID to filter memories.:return: List of memories."""return self.memory.get_all(user_id=user_id)def get_knowledge(self, app_id=None):"""Retrieve all memories associated with the given user ID.:param app_id: Optional user ID to filter memories.:return: List of memories."""return self.memory.get_all(app_id=app_id)def _async_add_to_memory(self, question, user_id, agent_id, run_id, metadata, filters):# 如果用户发送的消息以英文为主,可以不传prompt,会使用自带的英文提示词prompt = MEMORY_DEDUCTION_PROMPT.format(user_input=question, metadata=metadata)def add_task():self.memory.add(data=question,user_id=user_id,agent_id=agent_id,run_id=run_id,metadata=metadata,filters=filters,prompt=prompt)threading.Thread(target=add_task, daemon=True).start()def _fetch_relevant_memories(self, question, user_id, agent_id, run_id, filters, limit):# TODO: 过总结过去的谈话来做得更好return self.memory.search(query=question,user_id=user_id,agent_id=agent_id,run_id=run_id,filters=filters,limit=limit,)
  • 代码实现使用时国内通义千文和智谱清言的兼容open ai的接口
  • llm的接口是用的通义千文、向量化接口是用的智谱清言的接口
  • 因为通义千文没有提供和openai向量化处理兼容的接口,原本想只用智谱清言接口实现的,当时实践发现,智谱清言在tool函数识别选择调用的准确率太低,于是换成了阿里的qwen-plus,几乎准确率100%。
  • Mem0默认先从env环境变量里取base_urlapi_key的值,再从 config配置 的openai_base_urlapi_key的值。所以使用config文件设置openai_base_urlapi_key时,不要在设置环境变量了。

运行应用程序

要启动 Chainlit 应用程序,请打开终端并导航到包含的目录app.py。然后运行以下命令:

 chainlit run app.py -w   
  • -w标志告知 Chainlit 启用自动重新加载,因此您无需在每次更改应用程序时重新启动服务器。您的聊天机器人 UI 现在应该可以通过http://localhost:8000访问。
  • 自定义端口可以追加--port 80

启动后界面如下:

在这里插入图片描述

  • 里面关于我的记录,都是上周我和ai对话记录的信息,默认我设置只返回,和我提问最相关的十条记录。

相关文章推荐

《Chainlit快速实现AI对话应用的界面定制化教程》
《Chainlit接入FastGpt接口快速实现自定义用户聊天界面》
《使用 Xinference 部署本地模型》
《Fastgpt接入Whisper本地模型实现语音输入》
《Fastgpt部署和接入使用重排模型bge-reranker》
《Fastgpt部署接入 M3E和chatglm2-m3e文本向量模型》
《Fastgpt 无法启动或启动后无法正常使用的讨论(启动失败、用户未注册等问题这里)》
《vllm推理服务兼容openai服务API》
《vLLM模型推理引擎参数大全》
《解决vllm推理框架内在开启多显卡时报错问题》
《Ollama 在本地快速部署大型语言模型,可进行定制并创建属于您自己的模型》

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

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

相关文章

828华为云征文|部署多媒体流媒体平台 Plex

828华为云征文|部署多媒体流媒体平台 Plex 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 性能模式1.3 计费模式 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Plex3.1 Plex 介绍3.2 Docker 环境搭建3.3 Plex 部署3.4 Plex 使…

张家辉新作《重生》内地票房逆袭

由张家辉领衔主演的电影《重生》在票房大获成功,击败多部同期中西强片,成为今年暑期档的最大黑马。张家辉在片中饰演的角色原本拥有幸福家庭,为了复仇走上亡命之徒的道路,影片中他再度展现了影帝级别的演技,受到网民和…

CCF推荐A类会议和期刊总结(计算机网络领域)- 2022

CCF推荐A类会议和期刊总结(计算机网络领域)- 2022 在中国计算机学会(CCF)的推荐体系中,A类会议和期刊代表着计算机网络领域的顶尖水平。这些会议和期刊不仅汇集了全球顶尖的研究成果,还引领着该领域的前沿发…

合碳智能 × Milvus:探索化学合成新境界——逆合成路线设计

合碳智能(C12.ai)成立于2022年,致力于运用AI和具身智能技术,为药物研发实验室提供新一代智能化解决方案,推动实验室从自动化迈向智能化,突破传统实验模式与人员的依赖,解决效率和成本的瓶颈&…

解决浏览器自动将http网址转https

删除浏览器自动使用https的方式 在浏览器地址栏输入:chrome://net-internals/#hsts PS:如果是edge浏览器可输入:edge://net-internals/#hsts 在Delete domain security policies搜索框下,输入要删除的域名,然后点击delete 解决方法&#…

回收玻璃减薄中的氢氟酸

回收玻璃减薄中的氢氟酸是一个重要的环保和资源再利用环节。在玻璃减薄过程中,氢氟酸作为主要的化学蚀刻剂,与玻璃基板表面的二氧化硅等成分发生反应,实现玻璃的减薄。然而,随着反应的进行,氢氟酸的浓度会逐渐降低&…

MyQql性能诊断与实践

获取更多免费资料,见下图

证书学习(四)X.509数字证书整理

目录 一、X.509证书 介绍1.1 什么是 X.509证书?1.2 什么是 X.509标准?1.3 什么是 PKI?二、X.509证书 工作原理2.1 PKI 的基础——加密算法2.2 PKI 证书编码三、X.509证书 结构3.1 证书字段3.2 证书扩展背景: 我们在日常的开发过程中,经常会遇到各种各样的电子证书文件,其…

新电脑Win11系统想要降级为Win10怎么操作?

前言 现在的电脑大部分都是Windows 11系统,组装机还好一些,如果想要使用Windows 10,只需要在安装系统的时候选择Windows 10镜像即可。 但是对于新笔记本、厂商的成品机、一体机来说,只要是全新的电脑,基本上都是Wind…

快速入门游戏领域,开发游戏需要哪些技术?

在这个充满创意和技术的时代,游戏行业成为众多创新人才追求梦想的热土。对于准备踏入这个充满挑战与机遇的领域的新人来说,了解游戏开发流程是至关重要的。 游戏市场蓬勃发展,游戏行业未来行情可观,在这个充满创意和技术的时代&a…

8. GIS数据分析师岗位职责、技术要求和常见面试题

本系列文章目录: 1. GIS开发工程师岗位职责、技术要求和常见面试题 2. GIS数据工程师岗位职责、技术要求和常见面试题 3. GIS后端工程师岗位职责、技术要求和常见面试题 4. GIS前端工程师岗位职责、技术要求和常见面试题 5. GIS工程师岗位职责、技术要求和常见面试…

vue3 前端实现pdf打印预览 printjs

在utils建print.ts文件 interface PrintFunction {extendOptions: Function;getStyle: Function;setDomHeight: Function;toPrint: Function; }const Print function (dom, options?: object): PrintFunction {options options || {};// ts-expect-errorif (!(this instanc…

电脑技巧:如何在Win11电脑上调整设置,让屏幕更加护眼?

目录 一、调整屏幕亮度 二、启用夜间模式 三、调整色彩设置 四、使用第三方护眼软件 五、保持良好的用眼习惯 总结 随着长时间使用电脑的人越来越多,护眼问题也变得越来越重要。Win11作为更新的操作系统,提供了更多的设置选项来帮助我们保护眼睛。本文将详细介绍如何在…

清华计算几何--凸Polygon的相交问题

凸Polygon和相交定义 本节只讨论凸Polygon的问题,不涉及凹Polygon. 相交包含了边相交和完全包含。 凸Polygon相交的两个问题 Detection(检测) 判断两个凸Polygon是否相交,至于相交部分是什么不关心. Construction(构造) 求出两个凸Polygon具体相交…

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时&#x…

Linux:归档及压缩

tar命令 • tar 集成备份工具 – -c:创建归档 – -x:释放归档 – -f:指定归档文件名称,必须在所有选项的最后 – -z、-j、-J:调用 .gz、.bz2、.xz 格式工具进行处理 – -t:显示归档中的文件清单 – -C:指定…

MES的“尽头”是什么?

01 MES的发展历程 要了解MES首先需要知道其发展历程。制造执行系统(MES)是随着制造业的发展逐步演变和成熟起来的。以下是MES发展的几个主要阶段: 第一阶段:数据收集与报告(1980年代 - 1990年代) 制造业…

[苍穹外卖]-05Redis快速入门

Redis入门 Redis是一个基于内存的key-value结构数据库 基于内存存储, 读写性能高适合存储热点数据(热点商品,咨询,新闻)企业应用广泛中文官网: Redis中文网英文网: https://rsdis.io 下载安装: Redis安装包分为Windows版本和Linux版本, Redis的windows版属于绿色软件, 解压后…

OCR技术视角:智能文档管理中的票据自动化识别与处理

在数字化转型的浪潮中,企业对于高效、自动化的文档管理需求日益增长。票据作为企业运营中不可或缺的部分,其识别与管理的智能化成为了提升工作效率的关键。本文将深入探讨智能文档系统中票据识别功能的原理、技术优势以及在不同行业中的应用实践&#xf…

观察者模式observer

允许一个对象将其状态的改变通知其他对象 当Editor调用openFile()和saveFile()时,它会通过EventManager的notify方法,通知所有订阅了这些事件的监听器。