入门mem0.NET

news2024/10/2 12:30:20

入门mem0.NET

安装包

如果你的项目使用了EntityFrameworkCore,那么你可以跟随这个教程走

<ItemGroup>
    <PackageReference Include="mem0.NET" Version="0.1.7" />
    <PackageReference Include="mem0.NET.Qdrant" Version="0.1.7" />
    <PackageReference Include="mem0.EntityFrameworkCore" Version="0.1.7" />
</ItemGroup>
  • mem0.NET是我们的核心类库,包含核心prompt和功能实现
  • mem0.NET.Qdrant 是Qdrant向量数据库的实现,目前仅支持Qdrant
  • mem0.EntityFrameworkCoreEntityFrameworkCore的实现,因为我们需要记录AI利用Function的操作记录,当然您也可以自己实现其他的。

开始使用

我们需要先创建一个DbContext或者在现有的DbContext上也可以,

创建MasterDbContext

using mem0.NET.Service.DataAccess;
using Microsoft.EntityFrameworkCore;

namespace mem0.NET.Service;

public class MasterDbContext(DbContextOptions<MasterDbContext> options) : Mem0DbContext<MasterDbContext>(options)
{
}

DbContext需要继承Mem0DbContext,

然后打开appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "Default": "Host=localhost;Port=5432;Database=test;Username=token;Password=dd666666"
  },
  "Mem0": {
    "OpenAIEndpoint": "https://api.token-ai.cn",
    "OpenAIKey": "sk-asdasdaskdalksjdla",
    "OpenAIChatCompletionModel": "gpt-4o-mini",
    "OpenAITextEmbeddingModel": "text-embedding-ada-002",
    "CollectionName": "mem0-test"
  },
  "Qdrant": {
    "Host": "127.0.0.1",
    "Port": 6334,
    "Https": false,
    "ApiKey": "dd666666"
  }
}

我们需要配置一下我们的连接字符串和向量数据库的连接字符串,然后Mem0使用的AI相关的配置,我们推荐使用https://api.token-ai.cn,提供了非常多的AI模型,

创建MemoryService.cs

using mem0.Core;
using mem0.NET.Services;

#pragma warning disable SKEXP0001

namespace mem0.NET.Service.Services;

public static class ServiceCollectionExtensions
{
    public static WebApplication MapMemoryService(this WebApplication app)
    {
        var memoryService = app.MapGroup("/api/v1/memory")
            .WithTags("Memory")
            .WithDescription("Memory management")
            .WithDisplayName("Memory");

        memoryService.MapPost("/memory", async (MemoryService memoryService,
            CreateMemoryInput input) =>
        {
            await memoryService.CreateMemoryAsync(input);
        }).WithDescription("创建记忆").WithDisplayName("创建记忆").WithTags("记忆").WithName("CreateMemory");

        memoryService.MapPost("memory_tool", async (MemoryService memoryService,
            CreateMemoryToolInput input) =>
        {
            await memoryService.CreateMemoryToolAsync(input);
        }).WithDescription("创建记忆工具").WithDisplayName("创建记忆工具").WithTags("记忆");

        memoryService.MapGet("history/{memoryId}",
                async (MemoryService memoryService, string memoryId, int page, int pageSize) =>
                    await memoryService.GetHistory(memoryId, page, pageSize))
            .WithDescription("获取历史").WithDisplayName("获取历史").WithTags("记忆");

        memoryService.MapGet("memory/{memoryId}", async (MemoryService memoryService, Guid memoryId) =>
                await memoryService.GetMemory(memoryId))
            .WithDescription("获取记忆")
            .WithDisplayName("获取记忆")
            .WithTags("记忆");

        memoryService.MapGet("memory", async (MemoryService memoryService,
                    string? userId,
                    string? agentId, string? runId, uint limit) =>
                await memoryService.GetMemoryAll(userId, agentId, runId, limit))
            .WithDescription("获取所有记忆")
            .WithDisplayName("获取所有记忆")
            .WithTags("记忆");

        memoryService.MapGet("search", async (MemoryService memoryService,
                    string query,
                    string? userId,
                    string? agentId, string? runId, uint limit) =>
                await memoryService.SearchMemory(query,
                    userId,
                    agentId, runId, limit))
            .WithDescription("搜索记忆")
            .WithDisplayName("搜索记忆")
            .WithTags("记忆");

        memoryService.MapPut("memory",
                async (MemoryService memoryService, UpdateMemoryInput input) => await memoryService.Update(input))
            .WithDescription("更新记忆")
            .WithDisplayName("更新记忆")
            .WithTags("记忆");

        memoryService.MapDelete("memory/{memoryId}",
                async (MemoryService memoryService, Guid memoryId) => await memoryService.Delete(memoryId))
            .WithDescription("删除记忆")
            .WithDisplayName("删除记忆")
            .WithTags("记忆");

        memoryService.MapDelete("memory", async (MemoryService memoryService, string? userId,
                    string? agentId, string? runId) =>
                await memoryService.DeleteAll(userId, agentId, runId))
            .WithDescription("删除所有记忆")
            .WithDisplayName("删除所有记忆")
            .WithTags("记忆");

        memoryService.MapDelete("reset", async (MemoryService memoryService) =>
                await memoryService.Reset())
            .WithDescription("重置记忆")
            .WithDisplayName("重置记忆")
            .WithTags("记忆");

        return app;
    }
}

我们将mem0.NET提供的接口全部外放到WebAPI中,并且使用了MiniAPIs超级简单的实现了。

然后我们打开Program.cs

using mem0.NET.Options;
using mem0.NET.Service.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection.Options;

namespace mem0.NET.Service;

public static class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();

        builder.Services.AddOptions<Mem0Options>()
            .Bind(builder.Configuration.GetSection("Mem0"));

        builder.Services.AddOptions<QdrantOptions>()
            .Bind(builder.Configuration.GetSection("Qdrant"));

        var options = builder.Configuration.GetSection("Mem0")
            .Get<Mem0Options>();
        
        var qdrantOptions = builder.Configuration.GetSection("Qdrant")
            .Get<QdrantOptions>();

        builder.Services.AddMem0DotNet(options)
            .WithMem0EntityFrameworkCore<MasterDbContext>(optionsBuilder =>
            {
                optionsBuilder.UseNpgsql(builder.Configuration.GetConnectionString("Default"));
            })
            .WithVectorQdrant(qdrantOptions);

        var app = builder.Build();

        using (var scope = app.Services.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService<MasterDbContext>();

            await dbContext.Database.EnsureCreatedAsync();
        }

        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }

        app.MapMemoryService();

        await app.RunAsync();
    }
}

我们需要先将AI配置和向量配置绑定到Options中

builder.Services.AddOptions<Mem0Options>()
            .Bind(builder.Configuration.GetSection("Mem0"));
builder.Services.AddOptions<QdrantOptions>()
            .Bind(builder.Configuration.GetSection("Qdrant"));

然后添加我们的Mem0核心服务

builder.Services.AddMem0DotNet(options)
       .WithMem0EntityFrameworkCore<MasterDbContext>(optionsBuilder =>
       {
        	optionsBuilder.UseNpgsql(builder.Configuration.GetConnectionString("Default"));
       })
      .WithVectorQdrant(qdrantOptions);

AddMem0DotNet中则是我们的核心服务,然后我们的WithMem0EntityFrameworkCore则是EntityFrameworkCore服务,

通过WithVectorQdrant则添加了向量数据库服务。

然后需要先部署好数据库和向量数据库,下面我们会使用docker-compose.yml进行部署,请先确认一下自己的环境。

部署数据库和向量数据库

docker-compose.yml

services:
  qdrant:
    image: registry.token-ai.cn/qdrant/qdrant:latest
    restart: always
    container_name: qdrant
    ports:
      - 6333:6333
      - 6334:6334
    expose:
      - 6333
      - 6334
      - 6335
    configs:
      - source: qdrant_config
        target: /qdrant/config/production.yaml
    volumes:
      - ./qdrant_data:/qdrant/storage
        
  postgres:
    image: registry.token-ai.cn/postgres:16
    restart: always
    container_name: qdrant_postgres
    environment:
      POSTGRES_USER: token
      POSTGRES_PASSWORD: dd666666
      POSTGRES_DB: mem0
    ports:
      - 5432:5432
    volumes:
      - ./postgres_data:/var/lib/postgresql/data

configs:
  qdrant_config:
    content: |
      log_level: INFO      

执行我们的启动脚本

docker compose up -d

启动项目

创建记忆

案例数据

{"data":"# C# 入门教程目录列表\n\n## 1. C# 概述\n   - C# 的历史与发展\n   - C# 的特点与优势\n   - C# 的应用领域\n\n## 2. 开发环境搭建\n   - 安装 Visual Studio\n   - 配置开发环境\n   - 创建第一个 C# 项目\n\n## 3. C# 基础语法\n   - 数据类型与变量\n   - 运算符与表达式\n   - 控制流语句(if, switch, for, while)\n\n## 4. 面向对象编程\n   - 类与对象\n   - 封装、继承与多态\n   - 接口与抽象类\n\n## 5. 常用类与集合\n   - 字符串与字符串操作\n   - 数组与集合(List, Dictionary等)\n   - LINQ 查询\n\n## 6. 异常处理\n   - 异常的概念\n   - try-catch-finally 语句\n   - 自定义异常\n\n## 7. 文件与数据操作\n   - 文件读写操作\n   - 数据序列化与反序列化\n   - 数据库连接与操作(ADO.NET)\n\n## 8. 多线程与异步编程\n   - 线程的基本概念\n   - 使用 Task 和 async/await\n   - 线程安全与锁\n\n## 9. C# 的高级特性\n   - 委托与事件\n   - Lambda 表达式\n   - 属性与索引器\n\n## 10. 项目实战\n   - 实现一个简单的控制台应用\n   - 开发一个 Windows 窗体应用\n   - 部署与发布应用程序\n\n## 11. 资源与学习路径\n   - 推荐书籍与在线课程\n   - C# 社区与论坛\n   - 实践项目与开源资源\n\n## 12. 总结与展望\n   - 学习 C# 的重要性\n   - 未来的学习方向与发展趋势\n"}

然后在等创建内存完成以后我们使用search接口查看一下搜索效果

结束

mem0的机制是什么?

mem0适合什么场景?

mem0的机制是什么?

Mem0的主要功能包括添加、更新、搜索、检索和跟踪存储在系统中的记忆历史。通过简单易用的API实现这一点,支持与各种应用的集成,确保跨平台的一致性和开发者的使用便利性。Mem0还提供不同的部署选项,包括自托管的开源版本和面向企业的托管解决方案。

当你在创建Memory的时候并不是直接添加到数据库当中,也不是直接添加到向量数据库当中,然后先利用AI将您的文本提取或说总结内容,然后利用总结的内容去向量数据库搜索,将得到的搜索结果结合您的文本一块通过定义好的提示词发送给AI,然后利用AI理解能力和执行Function的能力,让他帮我们根据新的记忆(您的文本)和旧的记忆(向量数据库操查询的数据)进行对比,然后默认提供了三个Function,一个是新增,一个是更新,一个是删除,然后自行理解去更新记忆和删除新增记忆,然后mem0的特点就在于这一点,不像普通的RAG只在创建的时候一次优化,而mem0则会在您不断的添加数据库和上传数据库的同时进行优化您之前已经上传的向量数据,并随着时间的推移不断改进,这在从客户支持到医疗保健再到内容推荐等领域都至关重要。

mem0ai/mem0: The memory layer for Personalized AI (github.com)

AIDotNet/mem0.NET (github.com)

mem0适合什么场景

Mem0 的机制特别适合于需要个性化和记忆功能的场景,这包括但不限于以下几个应用领域:

  1. 客户支持系统:通过记忆用户的过往交互,Mem0 可以帮助客户服务系统提供更加个性化的响应和建议,改善客户体验。

  2. 健康护理应用:在健康管理和患者护理领域,Mem0 可以存储和回顾患者的历史健康信息,帮助医疗专业人员提供针对性的医疗建议。

  3. 教育技术:Mem0 可以用于跟踪学生的学习进度和偏好,提供定制化的学习体验和资源。

  4. 电子商务:电商平台可以利用Mem0 记录用户的购物习惯和偏好,从而推荐更合适的产品,提高转化率。

  5. 内容推荐系统:对于流媒体服务,Mem0 可以帮助系统记忆用户的观看历史和喜好,用以提供更加准确的内容推荐。

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

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

相关文章

云动态摘要 2024-08-04

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 数据库上云优选 阿里云 2024-07-04 RDS、PolarDB、Redis、MongoDB 全系产品新用户低至首年6折起&#xff01; [免费体验]智能助手ChatBI上线 腾讯云 2024-07-02 基于混元大模型打造&…

java之IO篇——File、字节流、字符流

前言 IO流是用于读写文件中的数据&#xff0c;要读写文件之前可以创建文件获取文件对象再创建IO流&#xff0c;正文会先介绍File类&#xff0c;通过File类的构造方法获取文件的对象&#xff0c;创建文件或目录以及File类的一些方法获取文件对象的属性。后面还介绍了相关的IO流体…

Radxa ROCK 3C开发板编译Opencv,支持调用树莓派摄像头模块V2

目录 1、ROCK 3C和树莓派摄像头模块V2介绍2、ROCK 3C在rsetup开启支持3、测试指令4、编译Opencv4.1 增加swap&#xff0c;确保内存够用4.2 安装依赖和下载opencv4.3 编译参考链接 5、使用opencv调用树莓派摄像头模块V2 1、ROCK 3C和树莓派摄像头模块V2介绍 ROCK 3C 是一款基于…

刷题篇 - 01

目录 题目一&#xff1a; 题目二&#xff1a; 题目三&#xff1a; 题目四&#xff1a; 题目五&#xff1a; 题目六&#xff1a; 题目七&#xff1a; 题目一&#xff1a; 387. 字符串中的第一个唯一字符 - 力扣&#xff08;LeetCode&#xff09; public int firstUniqC…

订单定时状态处理业务(SpringTask)

文章目录 概要整体架构流程技术细节小结 概要 订单定时状态处理通常涉及到对订单状态进行定期检查&#xff0c;并根据订单的状态自动执行某些操作&#xff0c;比如关闭未支付的订单、自动确认收货等. 需求分析以及接口设计 需求分析 用户下单后可能存在的情况&#xff1a; …

鸿蒙(API 12 Beta2版)NDK开发【内存管理purgeable内存开发指导】

场景介绍 HarmonyOS提供Purgeable Memory内存管理机制&#xff0c;开发者可以使用相关接口创建PurgeableMemory对象&#xff0c;从而管理purgeable内存。 开发者可以通过本指导了解在HarmonyOS应用中&#xff0c;如何使用Native层相关接口操作purgeable内存。功能包括purgeab…

Jupyter-Notebook常用操作看这一篇就够啦

来源&#xff1a; “码农不会写诗”公众号 链接&#xff1a;Jupyter-Notebook常用操作看这一篇就够啦 文章目录 01 概括02 快捷键总结03 运行外部python文件04 魔法命令4.1 运行计时4.2 查看变量与函数4.3 其它常用指令 书接上文 Jupyter-Notebook是一个基于 Web 的交互式开发环…

第十四节、受伤、死亡的逻辑和动画

一、受伤的动画效果 1齿轮控制当前动画图层的权重 2、层级 当前动画层为add&#xff0c;所以不会覆盖之前的动画层&#xff0c;而是添加一个动画层 3、受伤闪烁 调用颜色的值&#xff0c;实现受伤闪烁 4、录制动画 点击时间轴&#xff0c;插入关键帧 伤害图层选择add&…

2024华数杯C题解题思路、参考论文已出(无偿分享)~

C题&#xff1a;老外游中国 “数模加油站”团队出品~ 问题1&#xff1a; 解题思路&#xff1a; 1、数据准备&#xff1a; 导入352个城市的csv文件&#xff0c;提取每个城市中的100个景点的信息。 将每个景点的评分数据提取出来&#xff0c;形成一个包含35200个景点评分的列…

centos虚拟机restart网络后隔一会断联

1. 前言 不知道各位有没有遇到过虚拟机网络设置的坑&#xff0c;往往前一段时间用的好好的&#xff0c;突然网络又不行了无法连接外部网络&#xff0c;而且使用 service network restart 一瞬间可以&#xff0c;但是过一会就断连了… 2. 解决方案 根据对虚拟机网络的学习了解…

五、一个quad同时支持pcie和sfp两种高速接口的ref时钟配置

项目描述 上位机将截图数据通过 XDMA 写入到 FPGA 侧的 DDR 内存区域 1 中通过 axi_lite 接口给 axi_read_start 信号&#xff0c;通知 AXI_read 模块启动读取数据&#xff0c;然后通过 GTP TX 模块发送出去。经过光纤回环&#xff0c;GTP RX 端接收到数据&#xff0c;送给 AX…

今天的一件小事,亲身感受:付费是提高效率的重要途径

今天需要修改一个单页网站源码&#xff0c;有一个小问题困住我3个小时了。 毕竟我也不是专业的&#xff0c;没有系统学习过这些&#xff0c;搜答案都不知道怎么搜哈哈 吃过午饭&#xff0c;想着不能这么耗下去了&#xff0c;于是及时去了某宝&#xff0c;找到一个修改代码的 …

搭建nexus上传jar包,并结合jenkins运行项目

一、搭建nexus 1、docker拉取镜像 需要将docker原更新一下 https://blog.csdn.net/qx020814/article/details/140908006?spm1001.2014.3001.5502 docker pull sonatype/nexus3 创建nexus挂载文件、增加权限&#xff1a; mkdir docker_nexus3 mkdir docker_nexus3/nexus-data c…

TreeSize:免费的磁盘清理与管理神器,解决C盘爆满的燃眉之急

目录 TreeSize&#xff1a;免费的磁盘清理与管理神器&#xff0c;解决C盘爆满的燃眉之急 一、TreeSize介绍 二、下载安装TreeSize 2.1、下载地址 2.2、下载步骤 ​2.3、安装步骤 三、professional版的TreeSize试用 3.1、分析磁盘空间 3.2、显示拓展名统计信息 3.3、显…

将本地的业务写成成可供RPC远程调用的方法

第一步&#xff1a;首先我们先定义proto文件&#xff0c;这些proto文件将会为远程调用者提供调用的方法&#xff0c;为login方法。 2.重写UserServiceRpc类中的Login方法。 在Login中做的操作主要是&#xff0c;得到requst里面的参数&#xff0c;然后调用本地的Login方法&#…

可解释性终极追问,什么才是第一性解释?20篇CCF-A+ICLR论文给你答案

一、前言 长期以来&#xff0c;我们团队一直在思考可解释性领域的一个终极问题&#xff0c;即什么才是解释性领域的第一性原理&#xff1f;所谓第一性原理&#xff0c;目前没有一个被广泛接受的框架&#xff0c;世上本无路&#xff0c;我们需要逐渐去定义这样一个路。我们需要在…

Linux系统中的高级内核模块调试技术

引言 在Linux系统中进行高级内核模块开发时&#xff0c;调试是不可或缺的重要环节。调试技术能够帮助开发人员发现和解决代码中的错误和问题&#xff0c;提高开发效率和代码质量。本文将深入探讨Linux系统中高级内核模块调试的技术和方法&#xff0c;包括常用的调试工具、调试…

JAVA—面向对象编程高级

学习了一定基础后&#xff0c;开始更加深入的学习面向对象&#xff0c;包含static,final两个关键字&#xff0c;面向对象编程三大特征之继承和多态。以及对于抽象类&#xff0c;内部类&#xff0c;接口&#xff0c;枚举&#xff0c;泛型的学习。 目录 1.static &#xff08;…

cdn 内容分发网络

cdn 内容分发网络 CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。 其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层…

Milvus与Zilliz Cloud:向量数据库高可用性的双重飞跃

向量数据库高可用性的重要性及其在现代数据分析中的关键作用 在数据爆炸式增长的今天,企业对于高效、准确地处理和分析大规模数据集的需求日益迫切。尤其是在人工智能、机器学习、图像识别、自然语言处理等领域,向量数据库因其对高维数据的高效存储与检索能力,成为了不可或…