自己手写了一个大模型RAG项目-05.基于知识库的大模型问答

大家好,我是程序锅。

github上的代码封装程度高,不利于小白学习入门。

常规的大模型RAG框架有langchain等,但是langchain等框架源码理解困难,debug源码上手难度大。

因此,我写了一个人人都能看懂、人人都能修改的大模型RAG框架代码。

整体项目结构如下图所示:手把手教你大模型RAG框架架构

手把手教你大模型RAG框架架构

整个小项目分为10个章节,和github高度封装的RAG代码不同,我们将从0到1搭建大模型RAG问答系统。

前序章节:
自己手写了一个大模型RAG项目-04.知识库构建

图1.RAG技术路线

本篇文章将介绍5.基于知识库的大模型问答,知识库构建好之后还需要通过知识检索和智能问答。

一、知识检索

首先第一个问题,为什么要做知识检索

在整个大模型RAG智能问答应用构建过程中,需要将用户的问题向量化,将向量化后的问题与知识库内的向量做匹配。

前面几篇文章已经讲述了如何构建知识库,目前需要从向量库中匹配与问题最相似的k个向量(k是一个超参数,需要根据大模型输入上下文长度来界定)

怎么匹配以及匹配的标准是什么呢?

匹配的目的就是一堆向量中找到最相似的几个向量,最简单直白的方式就是去遍历所有向量,计算问题向量与知识库所有向量之间的相似度,然后按照相似度多少,从高到低排序,取最大的几个。

匹配的标准也很简单,我采用了余弦相似度。此外可以用L2范数、内积、曼哈顿距离、p范数等等。

@classmethod
def cosine_similarity(cls, vector1: List[float], vector2: List[float]) -> float:
    """
        calculate cosine similarity between two vectors
        """
    dot_product = np.dot(vector1, vector2)
    magnitude = np.linalg.norm(vector1) * np.linalg.norm(vector2)
    if not magnitude:
        return 0
    return dot_product / magnitude
def query(self, query: str, EmbeddingModel: BaseEmbeddings, k: int = 1) -> List[str]:
      query_vector = EmbeddingModel.get_embedding(query)
      end_time = time.time()
      result = np.array([self.get_similarity(query_vector, vector)
                        for vector in self.vectors])
      print(' 检索 cost %f second' % (time.time() - end_time))
      return np.array(self.document)[result.argsort()[-k:][::-1]].tolist()    

上面代码用到了最简单的for循环对比。不过for循环对比效率太低,因此有了许多优化方法。主要可以分为索引构建、检索加速、向量数据库等。

1.索引构建

索引一般存储在磁盘的文件中,它是占用物理空间的。一般我们都将存储所有原始向量

由于原始向量维度比较高,为了减少索引占用的空间,可以采用主成分分析(PCA)对向量降维;也可以通过某些编码方式降低向量维度,比如PQ16使用16个字节编码向量、PQ8+16通过8字节来进行PQ,16个字节对第一级别量化的误差再做PQ等等。

2.检索加速

检索这一块最简单的是基于余弦相似度的暴力全量搜索。如果你只是少量检索,或者要求检索结果非常准确的话这种索引是你的首选。

在数据量大了之后,暴力搜索会很慢,因此也有一些新的搜索算法。

  • 倒排暴力检索

    具体做法是预先设定好需要把所有向量聚成多少类,每个簇下会选出一个中心向量,在每次search的时候可以找到最近的几个中心向量,然后只在这几个中心向量涉及的簇中进行搜索,这样就大大减小了搜索范围,有利于搜索效率的提升。

  • 乘积量化

    利用乘积量化的方法,改进了普通检索,将一个向量的维度切成x段,每段分别进行检索,每段向量的检索结果取交集后得出最后的TopK。

  • 图检索

    图搜索算法是一类用于遍历或搜索图的数据结构和算法,图的节点可能带有关系,这些关系可以是有向的或无向的,加权的或无权的。图检索构建索引极慢,占用内存极大,检索速度极快,10亿级别秒出检索结果,

还有很多检索加速的方法,想快速用起来,推荐使用Faiss向量检索库,一行代码即可实现上述检索功能。比如用Faiss构建倒排暴力检索,代码如下:

import faiss  
# 向量维度是128,faiss.METRIC_L2代表相似度采用欧式距离
dim, measure = 128, faiss.METRIC_L2 
#代表k-means聚类中心为4096,   
description =  'IVF4096,Flat'
index = faiss.index_factory(dim, description, measure)

3.向量数据库

向量数据库是一种专门用于存储和处理向量数据的数据库系统。它以向量为基本数据类型,将向量作为数据的主要组织形式。相比传统的关系型数据库,向量数据库具有高效的相似性搜索和高度可扩展性。

你可以理解向量数据库主要包括数据存储、索引构建和相似性搜索三个过程。并且都根据数据是高维向量这一特性,在存储、索引、检索方面都做了大量的优化。

目前国产向量数据库中,比较厉害的就是Milvus。代码中也会涉及Milvus部署使用以及在没有资源的情况下如何白嫖Zilliz(Milvus的云化版本)

二、智能问答

这一块涉及如何组织语言,将用户的问题与知识库被检索出的文本块结合起来,便于大模型更好理解用户意图,生成用户想要的结果。

业界给了它一个高大上的名字:提示工程。提示工程探讨如何设计出最佳提示词,用于指导语言模型帮助我们高效完成某项任务。

下面给个项目中提示工程的例子:

PROMPT_TEMPLATE = dict(
    RAG_PROMPT_TEMPALTE="""使用以上下文来回答用户的问题。如果你不知道答案,就说你不知道。总是使用中文回答。
        问题: {question}
        可参考的上下文:
        ···
        {context}
        ···
        如果给定的上下文无法让你做出回答,请回答数据库中没有这个内容,你不知道。
        有用的回答:""",
    InternLM_PROMPT_TEMPALTE="""先对上下文进行内容总结,再使用上下文来回答用户的问题。如果你不知道答案,就说你不知道。总是使用中文回答。
        问题: {question}
        可参考的上下文:
        ···
        {context}
        ···
        如果给定的上下文无法让你做出回答,请回答数据库中没有这个内容,你不知道。
        有用的回答:"""
)

其中question是我们问的问题,context是知识库检索到的知识。

三、运行

代码目录结构:

├─images
├─RAG #存放RAG核心代码
└─tutorial
    ├─01.如何调用大模型API
    ├─02.RAG介绍
    ├─03.部署环境准备
    ├─04.知识库构建
    ├─05.基于知识库的大模型问答
    ├─06.改进-用自己的embedding模型
    ├─07.封装镜像对外提供服务
    ├─08.改进-基于Faiss的大模型知识索引构建
    ├─09.改进-使用向量数据库
    │  └─cloud-vectordb-examples
    └─10.前端构建

其中tutorial文件夹中,进入05.基于知识库的大模型问答

执行:python test.py,即可针对知识库开展大模型问答(前提条件:完成04.知识构建

好了,我们已经做出了一个最简单的基于RAG的大模型问答。下一章将介绍不调用接口,使用自己部署的embedding模型。

最后,我撰写的人工智能应用相关的博客及配套代码均整理放置在Github:ai-app,有需要的朋友自取。

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

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

相关文章

力扣HOT100 - 79. 单词搜索

解题思路&#xff1a; 深度优先搜索&#xff08;DFS&#xff09; 剪枝。 class Solution {public boolean exist(char[][] board, String word) {char[] words word.toCharArray();for(int i 0; i < board.length; i) {for(int j 0; j < board[0].length; j) {if (df…

Springboot+MybatisPlus入门案例(postman测试)

一、项目框架 pom.xml依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apac…

微软如何打造数字零售力航母系列科普04 - 微软联合Adobe在微软365应用程序中工作时推出新的生成式AI功能

微软和Adobe正在合作&#xff0c;将情境营销见解和工作流程引入微软Copilot&#xff0c;以提供生成的人工智能功能&#xff0c;使营销人员和营销团队能够在自然的工作流程中实现更多目标。 这些新的集成功能将在生产力和协作工具&#xff08;如Outlook、Teams和Word&#xff0…

【保姆级教程】用IDEA2023版本给RuoYi-Vue添加子模块

文章目录 前言添加子模块新建子模块新建子模块界面&#xff1f;新建子模块界面&#xff01; 修改pom依赖配置RuoYiApplication添加测试接口配置接口权限测试 前言 若依前后端分离框架能够极大方便当前开发任务&#xff0c;并且使用的技术栈也相当丰富&#xff0c;但是目前只提…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(六)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 12 - 13节&#xff09; P12《11.ArkUI组件-循环控制》 forEach() 方法的使用方式&#xff1a; 在预览界面点击红框的按钮&#xf…

煤矿综合自动化智能监控系统

系统概述 建设煤矿井上下工业环网、工业数据集成平台、排水、供电、运输、通风、压风、瓦斯抽放、采掘、智能洗煤厂等智能自动化控制系统&#xff0c;利用多种软硬件接口(OPC协议、驱动通讯、数据库、文本文件、DDE/NETDDE、子网等)&#xff0c;构建全矿井统一、稳定、高效的数…

vue2 实现echarts图表进入可视区域后再加载动画,以及 使用了resize之后,动画失效问题解决

Intersection Observer API 是一个现代的浏览器 API&#xff0c;用于监测一个或多个目标元素与其祖先元素或视窗&#xff08;viewport&#xff09;之间的交叉状态&#xff08;intersection&#xff09;的变化。它可以有效地监听元素是否进入或离开可视区域&#xff0c;从而实现…

使用OkHttp 缓存 API 调用提高Android应用性能

使用OkHttp 缓存 API 调用提高Android应用性能 坦率地说&#xff0c;我们都遇到过这样的情况——焦急地刷新应用&#xff0c;看着加载图标不停地旋转&#xff0c;等待那个至关重要的 API 响应。这样的等待我们已经是炉火纯青了&#xff0c;是吧&#xff1f;手指有节奏地轻敲屏…

记录些RAG-Fusion、Agent、NL2SQL的问题

RAG-Fusion RAG-Fusion 的实现原理 Query Duplication with a Twist&#xff1a;用 LLM 根据用户的 Query 生成几个相关的但不同的 Queries。Vector Search Unleashed&#xff1a;对原 Query 和生成的 Queries 都进行向量&#xff08;或者其他方式的&#xff09;搜索。Intell…

基于Springboot的滑雪场管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的滑雪场管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&a…

摩根大通推出创新工具 FlowMind,引领金融自动化新变革

近日&#xff0c;摩根大通人工智能研究部推出了一款极具创新性的工具——FlowMind&#xff0c;为金融行业带来了全新的工作模式和效率提升。 FlowMind 能够自动化金融工作流程&#xff0c;在信贷审批、风险评估、合规监测等重要任务中发挥着关键作用。它利用 GPT 自动生成工作…

泽攸科技无掩膜光刻机在MEMS压力传感器制造中的应用

在当今的科技快速发展时代&#xff0c;微电子机械系统&#xff08;MEMS&#xff09;技术已成为推动现代传感器技术革新的关键力量。MEMS压力传感器&#xff0c;作为其中的重要分支&#xff0c;广泛应用于生物医学、航空航天、汽车工业等多个领域。随着对传感器性能要求的不断提…

探索Jellyfin:支持Android的自由开源的媒体服务器平台

探索Jellyfin&#xff1a;支持Android的自由开源的媒体服务器平台 I. 简介 A. 什么是Jellyfin&#xff1f; Jellyfin是一个自由开源的媒体服务器平台&#xff0c;旨在让用户能够自主管理和流式传输他们的媒体内容。与许多闭源的商业媒体服务器解决方案不同&#xff0c;Jelly…

基于ESP32—CAM物联网WIFI小车

一.功能概述 摄像头的画面可以实时的传输到&#xff0c;点灯科技APP的手机端&#xff0c;这样可以实时查看周围环境的状况&#xff0c;灯光不足&#xff0c;画面不清晰时可以打开灯光照明。手机端有左转、右转、前进、后退、停止的按钮。可以根据自己需要&#xff0c;来控制小车…

美国站群服务器上常见的操作系统选择指南

美国站群服务器上常见的操作系统选择指南 美国站群服务器的选择操作系统对于服务器的性能和功能至关重要。本文将为您介绍在美国站群服务器上常见的操作系统选择指南&#xff0c;以帮助您做出明智的决策。 在选择美国站群服务器时&#xff0c;选择合适的操作系统是至关重要的…

SMTP服务器搭建的注意事项?如何配置SMTP?

SMTP服务器搭建的步骤有哪些&#xff1f;SMTP服务器的搭建方法&#xff1f; SMTP服务器作为电子邮件传输的核心组件&#xff0c;其搭建过程中的每一个细节都至关重要。AokSend将详细探讨SMTP服务器搭建的注意事项&#xff0c;帮助您轻松搭建一个高效、安全的SMTP服务器。 SMT…

Flutter创建自定义的软键盘

参考代码&#xff1a; Flutter - Create Custom Keyboard Examples 本文贴出的代码实现了一个输入十六进制数据的键盘&#xff1a; &#xff08;1&#xff09;支持长按退格键连续删除字符&#xff1b; &#xff08;2&#xff09;可通过退格键删除选中的文字&#xff1b; &…

02 - 步骤 Kafka consumer

简介 Kafka consumer 步骤&#xff0c;用于连接和消费 Apache Kafka 中的数据,它可以作为数据管道的一部分&#xff0c;将 Kafka 中的数据提取到 Kettle 中进行进一步处理、转换和加载&#xff0c;或者将其直接传输到目标系统中。 使用 场景 我需要订阅一个Kafka的数据&…

网络安全之密码学技术

文章目录 网络信息安全的概念数据加密|解密概念密码学概论密码学分类古典密码学现代密码学 现代密码学的相关概念对称加密算法对称加密算法—DES对称加密算法—3DES对称加密算法—AES对称加密算法—IDEA 非对称加密算法非对称加密算法—RSA非对称加密算法—ElGamal非对称加密算…

Reactor Netty-响应式编程-010

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace 为什么不…