基于ollama,langchain,springboot从零搭建知识库三【解析文档并存储到向量数据库】

安装环境

安装pgvector,先设置docker镜像源:

vim /etc/docker/daemon.json

{
  "registry-mirrors": [
    "https://05f073ad3c0010ea0f4bc00b7105ec20.mirror.swr.myhuaweicloud.com",
    "https://mirror.ccs.tencentyun.com",
    "https://0dj0t5fb.mirror.aliyuncs.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://6kx4zyno.mirror.aliyuncs.com",
    "https://registry.docker-cn.com",
    "https://akchsmlh.mirror.aliyuncs.com",
    "https://registry.docker-cn.com",
    "https://docker.mirrors.ustc.edu.cn", 
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}

编写docker-compose.yml:

services:
  pgvector:
    image: ankane/pgvector:latest
    container_name: pgvector
    ports:
      - "5432:5432"
    restart: always
    environment:
      - POSTGRES_DB=langchat
      - POSTGRES_USER=root
      - POSTGRES_PASSWORD=root
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    networks:
      - app_network

  pgadmin:
    image: dpage/pgadmin4:latest
    container_name: pgadmin
    ports:
      - "5050:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: "admin@example.com"
      PGADMIN_DEFAULT_PASSWORD: "admin"
    volumes:
      - pgadmin-data:/var/lib/pgadmin
    networks:
      - app_network

networks:
  app_network:
    driver: bridge

volumes:
  pgadmin-data:
  pgdata:

执行docker compose up -d(老版本的docker是docker-compose up -d)。如下则安装成功:

访问http://128.0.0.1:5050/ 登录pgadmin,账号密码在docker-compose中

登陆完新增一个server

ollama中安装embedding,在ollama官网中搜索nomic-embed-text ,这里的embedding.length表示向量长度,需要记住

存储向量数据

首先在pom中添加对应依赖

<dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-core</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-pgvector</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.5.8</version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-embedding-store-filter-parser-sql</artifactId>
            <version>${langchain4j.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>com.github.jsqlparser</groupId>
                    <artifactId>jsqlparser</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-document-parser-apache-tika</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>
        <dependency>
            <groupId>dev.langchain4j</groupId>
            <artifactId>langchain4j-pgvector</artifactId>
            <version>${langchain4j.version}</version>
        </dependency>

编写代码:新增EmbeddingController,首先构建一个EmbbedingStore

 private EmbeddingStore buildEmbeddingStore() {
        PgVectorEmbeddingStore store = PgVectorEmbeddingStore.builder()
                .host("127.0.0.1")
                .port(5432)
                .database("langchat")
                .dimension(768)  //需要跟llm embedding模型的向量长度统一
                .user("root")
                .password("root")
                .table("testEmb")  //可以自定义新增,无需提前创建
                .indexListSize(1)
                .useIndex(true)
                .createTable(true)
                .dropTableFirst(false)
                .build();
        return store;
    }

随后构建一个EmbeddingModel,用于将文档解析成向量数据

public EmbeddingModel buildEmbedding() {
            return OllamaEmbeddingModel
                    .builder()
                    .baseUrl("http://127.0.0.1:11434")
                    .modelName("nomic-embed-text")
                    .logRequests(true)
                    .logResponses(true)
                    .build();
    }

随后准备一份简单的文本内容存放于E盘中(自己喜欢):

Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。
Redis服务默认端口号为 6379 ,通过快捷键Ctrl + C 即可停止Redis服务
重启Redis后,再次连接Redis时,需加上密码,否则连接失败。
Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型:
在MySQL中,可以使用create database语句来创建数据库。以下是创建一个名为my_database的数据库的示例:

新增embed方法,用于解析文档并存储到pgvector中

@GetMapping(value="/embed")
    public String embed() {
        Document document;
        document = FileSystemDocumentLoader.loadDocument("E:\\新建文本文档.txt", new ApacheTikaDocumentParser());
        document.metadata().put("fileName", "c.md");
        DocumentSplitter splitter = new DocumentByLineSplitter(100,0);
        List<TextSegment> segments = splitter.split(document);


        EmbeddingModel embeddingModel = buildEmbedding();
        EmbeddingStore<TextSegment> embeddingStore = buildEmbeddingStore();
        List<Embedding> embeddings = embeddingModel.embedAll(segments).content();
        List<String> ids = embeddingStore.addAll(embeddings, segments);
        // 正则表达式匹配换行符
        return JSONUtil.toJsonStr(ids);
    }

        其中FileSystemDocumentLoader表示系统文件读取器,可以读取本地文件并转化为document。同时还有UrlDocumentLoader用于读取网络上的文档内容

        DocumentSplitter作为文档切割器,可以将文档切割成小份的TextSegment。DocumentSplitter有多种实现,可根据自己需求选择:

                                   

          其中常用的有DocumentByLineSplitter,用于根据行切割(需要注意的点是他需要定义maxSegmentSizeInChars,当他设置为1000,文档每行大小为300时,会将每三行合并成一个segment,会根据分隔符最大程度的填充)

        DocumentByParagraphSplitter表示根据段落切割

        DocumentByRegexSplitter表示根据正则表达式切割

        具体可以点到方法中查看

        

        metadata则表示元数据,可以存储如用户名,文档名之类的检索信息,在后续检索中可以作为条件进行查询

        至此文档已成功解析并存储到向量数据库中

查询向量数据

        

 @GetMapping(value="/search")
    public String search() {

        EmbeddingModel embeddingModel = buildEmbedding();
        EmbeddingStore<TextSegment> embeddingStore = buildEmbeddingStore();
        Embedding queryEmbedding = embeddingModel.embed("MySQL创建语句").content();
        Filter filter = metadataKey("fileName").isEqualTo("c.md");
        EmbeddingSearchResult<TextSegment> list = embeddingStore.search(EmbeddingSearchRequest
                .builder()
                .queryEmbedding(queryEmbedding)
                .maxResults(5)
                .filter(filter)
                .build());

        List<Map<String, Object>> result = new ArrayList<>();
        list.matches().forEach(i -> {
            TextSegment embedded = i.embedded();
            Map<String, Object> map = embedded.metadata().toMap();
            map.put("text", embedded.text());
            result.add(map);
        });

        String promot = """
                查询MySQL创建语句,
                以下是文本内容,请根据内容提取问题的结果:
                """ + JSONUtil.toJsonStr(result);
        ChatLanguageModel model = buildModel();

        return  model.generate(promot);
    }


  private ChatLanguageModel buildModel(){
        return OllamaChatModel.builder()
                .baseUrl("http://127.0.0.1:11434")
                .modelName("qwen2:7b")
                .temperature(0.1)
                .build();
    }

        其中Embedding填充的是需要通过向量数据查询的内容

        Filter表示需要过滤的元数据内容。它是一个链式结构,可以通过or,and等关联条件进行搜索

        search方法中maxResult表示返回最高匹配的文档数(可能查询的内容不存在于向量中,但是根据向量查询算法查询他有一定相似度也会查询出来)

        promot表示将pgvector中搜索出来的内容,根据描述将问题跟结果拼接丢给大模型去整合并返回最终的结果(这里的提示词很粗糙,可以根据自己的需求不断完善提示词)

        最终输出结果如下:

至此,一个简单的rag增强搜索就完成了。其中有很多需要微调的地方,还有很多需要整合的地方需要后续再一步步优化迭代

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# OpenCV机器视觉:红外体温检测

在一个骄阳似火的夏日&#xff0c;全球却被一场突如其来的疫情阴霾笼罩。阿强所在的小镇&#xff0c;平日里熙熙攘攘的街道变得冷冷清清&#xff0c;人们戴着口罩&#xff0c;行色匆匆&#xff0c;眼神中满是对病毒的恐惧。阿强作为镇上小有名气的科技达人&#xff0c;看着这一…

计算机视觉算法实战——无人机检测

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​ 1. 引言✨✨ 随着无人机技术的快速发展&#xff0c;无人机在农业、物流、监控等领域的应用越来越广泛。然而&#xff0c;无人机的滥用也带…

日志收集Day004

1.filebeat安装 基于二进制安装filebeat (1)下载filebeat软件包 (2)解压软件包 tar xf filebeat-7.17.5-linux-x86_64.tar.gz -C /app/softwares/ (3)验证filebeat安装是否成功 cd /app/softwares/filebeat-7.17.5-linux-x86_64/ ln -svf pwd/filebeat /usr/local/sbin/ f…

Vue入门(Vue基本语法、axios、组件、事件分发)

Vue入门 Vue概述 Vue (读音/vju/&#xff0c;类似于view)是一套用于构建用户界面的渐进式框架&#xff0c;发布于2014年2月。与其它大型框架不同的是&#xff0c;Vue被设计为可以自底向上逐层应用。Vue的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三…

缓存商品、购物车(day07)

缓存菜品 问题说明 问题说明&#xff1a;用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大。 结果&#xff1a; 系统响应慢、用户体验差 实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询…

数据结构测试题2

一、单选题&#xff08;每题 2 分&#xff0c;共20分&#xff09; 1. 栈和队列的共同特点是( A )。 A.只允许在端点处插入和删除元素 B.都是先进后出 C.都是先进先出 D.没有共同点 2. 用链接方式存储的队列&#xff0c;在进行插入运算时( C ) A. 仅修改头指针 B. 头…

qml Settings详解

1、概述 QML中的Settings类提供了一种便捷的方式来保存和恢复应用程序的配置信息&#xff0c;如用户名、密码、窗口位置和大小等。它简化了配置数据的存储过程&#xff0c;无需使用像SQLite这样的数据库系统。通过使用Settings&#xff0c;开发者可以轻松实现应用程序设置的持…

认识Django项目模版文件——Django学习日志(二)

1.默认文件介绍 └── djangoproject1/├── djangoproject1/│ ├── urls.py [URL和函数的对应关系]【常用文件】│ ├── settings.py [项目配置文件]【常用文件】│ ├── _init_.py│ ├── wsgi.py [接受网络请求] 【不要动】│ └──…

Qt实践:一个简单的丝滑侧滑栏实现

Qt实践&#xff1a;一个简单的丝滑侧滑栏实现 笔者前段时间突然看到了侧滑栏&#xff0c;觉得这个抽屉式的侧滑栏非常的有趣&#xff0c;打算这里首先尝试实现一个简单的丝滑侧滑栏。 首先是上效果图 &#xff08;C&#xff0c;GIF帧率砍到毛都不剩了&#xff09; QProperty…

【Linux网络编程】传输层协议

目录 一&#xff0c;传输层的介绍 二&#xff0c;UDP协议 2-1&#xff0c;UDP的特点 2-2&#xff0c;UDP协议端格式 三&#xff0c;TCP协议 3-1&#xff0c;TCP报文格式 3-2&#xff0c;TCP三次握手 3-3&#xff0c;TCP四次挥手 3-4&#xff0c;滑动窗口 3-5&#xf…

[C]基础8.详解操作符

博客主页&#xff1a;算法歌者本篇专栏&#xff1a;[C]您的支持&#xff0c;是我的创作动力。 文章目录 0、总结1、操作符的分类2、二进制和进制转换2.1、2进制转10进制2.2、10进制转2进制2.3、2进制转8进制和16进制 3、原码、反码、补码4、移位操作符4.1 左移操作符4.2 右移操…

基于Springboot用axiospost请求接收字符串参数为null的解决方案

问题 ​ 今天在用前端 post 请求后端时发现&#xff0c;由于是以 Json对象的形式传输的&#xff0c;后端用两个字符串形参无法获取到对应的参数值 前端代码如下&#xff1a; axios.post(http://localhost:8083/test/postParams,{a: 1, b:2} ,{Content-Type: application/jso…

数据结构——堆(介绍,堆的基本操作、堆排序)

我是一个计算机专业研0的学生卡蒙Camel&#x1f42b;&#x1f42b;&#x1f42b;&#xff08;刚保研&#xff09; 记录每天学习过程&#xff08;主要学习Java、python、人工智能&#xff09;&#xff0c;总结知识点&#xff08;内容来自&#xff1a;自我总结网上借鉴&#xff0…

【Qt】05-菜单栏

做菜单 前言一、创建文件二、菜单栏 QMenuBar2.1 示例代码2.2 运行结果 三、工具栏 QToolBar3.1 运行代码3.2 结果分析 四、状态栏 QStatusBar4.1 运行代码4.2 运行结果 五、文本编辑框 QTextEdit5.1 运行代码5.2 运行结果 六、浮动窗口 addDockWidget6.1 运行代码6.2 运行结果…

【喜讯】海云安荣获“数字安全产业贡献奖”

近日&#xff0c;国内领先的数字化领域独立第三方调研咨询机构数世咨询主办的“2025数字安全市场年度大会”在北京成功举办。在此次大会上&#xff0c;海云安的高敏捷信创白盒产品凭借其在AI大模型技术方面的卓越贡献和突出的技术创新能力&#xff0c;荣获了“数字安全产业贡献…

MySQL训练营-慢查询诊断问题

slow_query_log long_query_time slow_query_log&#xff1a;日志开关&#xff0c;是否记慢查询日志 long_query_time&#xff1a;超过多长时间判定为慢查询 查看参数设置&#xff1a; SHOW VARIABLES LIKE ‘slow_query_log’;SHOW VARIABLES LIKE ‘long_query_time’; …

2025年最新汽车零部件企业销售项目管理解决方案

在汽车零部件企业&#xff0c;销售项目管理的不规范和销售预测的不准确性常导致生产计划无法及时调整&#xff0c;因此客户关系常常中断&#xff0c;导致企业业务机会的丧失。为解决该问题&#xff0c;企业需要投入更多资源以优化销售流程与销售预测。 1、360多维立体客户视图…

K8S中ingress详解

Ingress介绍 Kubernetes 集群中&#xff0c;服务&#xff08;Service&#xff09;是一种抽象&#xff0c;它定义了一种访问 Pod 的方式&#xff0c;无论这些 Pod 如何变化&#xff0c;服务都保持不变。服务可以被映射到一个静态的 IP 地址&#xff08;ClusterIP&#xff09;、一…

大模型:LangChain技术讲解

一、什么是LangChain 1、介绍 LangChain是一个用于开发由大型语言模型提供支持的Python框架。它提供了一系列工具和组件&#xff0c;帮助我们将语言模型集成到自己的应用程序中。 有了它之后&#xff0c;我们可以更轻松地实现对话系统、文本生成、文本分类、问答系统等功能。…

【优选算法篇】2----复写零

---------------------------------------begin--------------------------------------- 这道算法题相对于移动零&#xff0c;就上了一点点强度咯&#xff0c;不过还是很容易理解的啦~ 题目解析&#xff1a; 这道题如果没理解好题目&#xff0c;是很难的&#xff0c;但理解题…