入门mem0.NET

入门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 可以帮助系统记忆用户的观看历史和喜好,用以提供更加准确的内容推荐。

<think>好的,用户想要了解LVGL的入门开发教程。我需要先回忆一下LVGL的基本信息,确保自己了解最新的版本和资源。首先,LVGL是一个轻量级的嵌入式GUI库,适用于微控制器和嵌入式系统。用户可能是刚开始接触嵌入式GUI开发,或者想要将LVGL应用到他们的项目中。 用户的需求是入门教程,所以需要从基础开始,分步骤讲解。我需要考虑他们可能的开发环境,比如常用的硬件平台(如STM32、ESP32)、操作系统(是否使用FreeRTOS等)、以及LVGL的版本。目前最新的是v8.x或v9.x,需要确认文档是否有变化。 接下来,应该包括安装和配置LVGL的步骤,如何移植到目标硬件,以及编写第一个“Hello World”程序。还要提到模拟器的使用,这对没有硬件的用户来说很重要。另外,文档和社区资源是学习的关键,需要推荐官方文档和示例代码。 用户可能遇到的问题包括移植过程中的驱动配置、内存不足、或者显示异常。在教程中需要提醒常见问题及解决方法。此外,是否需要提到LVGL的图形工具,如SquareLine Studio?这对快速设计UI可能有帮助,但可能涉及第三方工具,需要说明。 需要确保回答结构清晰,分步骤,并且提供实际代码示例。同时,按照系统指令,所有行内数学表达式用$...$,独立公式用$$...$$,但LVGL教程可能较少涉及数学公式,所以这部分可能用不上。但需注意中英文标点,使用中文回答,避免Markdown格式。 最后,检查是否有遗漏的重要步骤,比如依赖的库、如何配置显示和输入设备驱动、内存管理的最佳实践等。确保用户能够按照步骤顺利入门,并引导他们进一步学习的资源。</think>以下为LVGL入门开发的分步教程,采用结构清晰的工程化框架说明: 一、环境准备 1. 硬件选择 - 推荐MCU:Cortex-M4/M7级别及以上(主频≥100MHz) - 内存要求:≥64KB RAM(建议128KB+) - 显示屏:支持RGB、SPI或8080接口(240x320分辨率起步) 2. 开发工具链 - 编译器:GCC/ARMCC/IAR - 开发环境:VSCode+PlatformIO/Keil/STM32CubeIDE - 模拟器:LVGL官方PC模拟器(Windows/Linux/macOS通用) 二、工程搭建(以STM32为例) 1. 获取LVGL源码 ```bash git clone --branch v9.1.0 https://github.com/lvgl/lvgl.git ``` 2. 文件结构配置 ``` /my_project ├── Drivers/ # HAL驱动 ├── Core/ ├── LVGL/ # 官方源码 │ ├── src/ │ ├── examples/ │ └── ... ├── lv_conf.h # 配置文件模板 └── Src/main.c ``` 三、关键配置步骤 1. 修改lv_conf.h: ```c #define LV_MEM_SIZE (48U * 1024U) // 内存池配置 #define LV_HOR_RES_MAX 480 // 水平分辨率 #define LV_VER_RES_MAX 320 // 垂直分辨率 #define LV_USE_LOG 1 // 启用日志系统 ``` 2. 显示驱动实现(SPI接口示例): ```c void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { uint16_t w = area->x2 - area->x1 + 1; uint16_t h = area->y2 - area->y1 + 1; ILI9341_SetWindow(area->x1, area->y1, area->x2, area->y2); ILI9341_WritePixels((uint16_t*)color_p, w * h); lv_disp_flush_ready(disp_drv); } ``` 四、第一个GUI程序 ```c void lv_example_btn_1(void) { lv_obj_t * btn = lv_btn_create(lv_scr_act()); lv_obj_set_size(btn, 120, 50); lv_obj_center(btn); lv_obj_t * label = lv_label_create(btn); lv_label_set_text(label, "Click Me!"); lv_obj_center(label); lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_CLICKED, NULL); } static void btn_event_handler(lv_event_t * e) { lv_obj_t * label = lv_label_create(lv_scr_act()); lv_label_set_text(label, "Hello LVGL!"); lv_obj_center(label); } ``` 五、最佳实践建议 1. 性能优化 - 启用双帧缓冲(需至少2*屏幕分辨率内存) - 使用LVGL的异步刷新机制 - 启用DMA2D加速(Cortex-M7/M33) 2. 内存管理 - 优先使用lv_mem_alloc()代替malloc() - 对象创建后必须设置parent参数 - 及时使用lv_obj_del()销毁不需要的对象 六、调试工具 1. 内置性能监控: ```c lv_mem_monitor_t mon; lv_mem_monitor(&mon); printf("Used: %d, Frag: %d%%\n", mon.used_pct, mon.frag_pct); ``` 2. 使用LittelvGL官方调试插件: - LV_USE_DEBUG 1 - 内存泄漏检测 - 对象树可视化 七、进阶学习路径 1. 官方资源: - 文档:https://docs.lvgl.io/8.1/ - 示例库:lvgl/demos目录 - 在线API参考:https://lvgl.100ask.net/9.1/ 2. 推荐学习顺序: 基础组件 → 动画系统 → 文件系统集成 → 多语言支持 → 自定义样式开发 → 硬件加速优化 常见问题解决方案: 1. 显示异常:检查lv_conf.h中的颜色深度设置(LV_COLOR_DEPTH) 2. 触控不响应:校准输入设备坐标系统 3. 内存不足:启用LV_MEM_CUSTOM配置自定义内存管理 建议从官方模拟器开始实验,逐步移植到真实硬件。通过LVGL的在线示例生成器(https://sim.lvgl.io/)可快速验证UI设计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值