当前位置: 首页 > article >正文

构建简单RAG代码实现

步骤1:文档准备与切割
假设我们有一个关于机器学习的PDF文档需要处理。

示例代码:

Python
深色版本
from llama_index import SimpleDirectoryReader

# 加载文档
documents = SimpleDirectoryReader('./data').load_data()
说明:

使用SimpleDirectoryReader加载位于指定路径下的文档。
文档被加载后,会根据特定规则进行切割成小块(chunks),如按句子或段落分割。
步骤2:文本向量化
使用预训练模型对切割后的文本块进行向量化。

示例代码:

Python
深色版本
from sentence_transformers import SentenceTransformer

# 加载预训练模型
model = SentenceTransformer('all-MiniLM-L6-v2')

# 对每个文档块进行向量化
embeddings = [model.encode(str(doc)) for doc in documents]
说明:

这里使用了SentenceTransformer中的all-MiniLM-L6-v2模型来生成文本块的向量表示。
每个文档块转换为一个固定长度的向量。
步骤3:构建索引并入库
将向量化的文本块及其元数据存入向量数据库中。

示例代码:

Python
深色版本
from faiss import IndexFlatL2

# 初始化索引
index = IndexFlatL2(embeddings[0].shape[0])

# 添加向量到索引中
for embedding in embeddings:
    index.add(embedding.reshape(1, -1))
说明:

使用Faiss创建了一个简单的索引来存储和查询向量。
将所有文档块的向量添加到索引中以便后续查询。
步骤4:问题理解与向量化
当用户提出一个问题时,首先将其转化为向量形式。

示例代码:

Python
深色版本
question = "什么是机器学习?"
question_embedding = model.encode(question)
说明:

问题“什么是机器学习?”被编码为其对应的向量表示。
步骤5:相似度搜索
在向量库中查找与问题向量最接近的文档块向量。

示例代码:

Python
深色版本
D, I = index.search(question_embedding.reshape(1, -1), k=5)  # 查找前5个最相关的文档块
说明:

search函数返回最接近问题向量的前k个文档块的距离(D)和索引(I)。
在这个例子中,k=5意味着我们将找到与问题最相关的前5个文档块。
步骤6:RAG检索增强生成
利用检索到的相关文档块作为上下文信息,结合问题生成最终答案。

示例代码:
假设我们已经有了一个支持RAG的模型和相关API调用方式:

Python
深色版本
context_texts = [documents[i].text for i in I[0]]  # 获取检索到的上下文文本
answer = rag_model.generate(question=question, context=context_texts)
print("回答:", answer)
说明:

根据索引结果获取最相关的文档块文本。
使用支持RAG的模型结合问题和这些上下文信息生成最终的回答。
以上流程展示了如何从文档准备开始,经过向量化、索引建立、问题向量化、相似度搜索到最后通过RAG方法生成答案的一个完整过程。请注意,这只是一个简化的示例,实际应用中可能需要根据具体的需求和技术栈做出相应的调整。

问题1:

之前了解到,大模型检索生成是将预料切割成问题:答案,这样键值对的形式,存储到数据库中。检索生成,输入问题,然后匹配对应问题的key,找到问题答案。这种说法正确吗?怎么看待这种说法,和你刚刚讲解的流程是有差异的

你提到的方法确实存在,并且在某些应用场景中被采用,特别是当数据集可以明确地分割为问题和答案对的形式时。这种方法通常被称为基于检索的问答系统(Retrieval-Based QA System),它与我之前描述的基于文档切割、向量化以及检索增强生成(RAG)的方法有所不同。

基于检索的问答系统(问题-答案键值对)

在这种方法中,原始数据首先会被转换成“问题:答案”这样的键值对格式,然后存储在一个数据库或搜索引擎中。当用户输入一个问题时,系统会在预定义的问题集合中查找最匹配的问题,然后返回对应的答案。这种方法的优点在于其简单直接,特别适用于FAQ(常见问题解答)等场景。

流程示例:

  1. 准备数据:将文档内容转化为问题-答案对。

    • 示例:“机器学习是什么?” -> “机器学习是一门多领域交叉学科...”
  2. 构建索引:使用文本相似度算法或者搜索引擎技术来索引这些问题。

  3. 查询处理:当接收到用户提问时,通过搜索最接近的问题来找到并返回相应的答案。

与基于文档切割、向量化及RAG方法的区别

相比之下,基于文档切割、向量化及RAG的方法更加灵活,尤其适合处理那些没有预先定义好问题答案对的大规模非结构化数据集。

  • 数据灵活性:前者依赖于预先定义好的问题答案对,而后者可以直接从大量未结构化的文档中提取信息。

  • 回答质量:基于RAG的方法能够结合多个相关文档片段的信息来生成更全面的答案,而不是局限于预先设定的答案。

  • 适用范围:基于检索的方法更适合用于FAQ等有限范围内的问答任务;而基于RAG的方法则更适用于开放域问答、知识库问答等需要综合多种信息来源的任务。

总结

两种方法各有优劣,选择哪一种取决于具体的应用需求:

  • 如果你的应用场景是围绕一组固定的常见问题和答案设计的,那么基于检索的问答系统可能是一个高效的选择。
  • 如果你需要处理大量的非结构化文本数据,并希望从中动态生成高质量的回答,那么基于文档切割、向量化及RAG的方法可能是更好的选择。

两者并不是互相排斥的,实际上,在一些复杂的系统中,可能会结合使用这两种方法以达到最佳效果。例如,先用基于检索的方法快速定位到相关的文档或章节,再利用基于RAG的方法深入分析这些文档内容以生成最终的答案。

问题2:

rag中我们通常说的向量检索和关键字检索,向量检索是不是我们上文中从向量库中检索的流程是一致吗?不一致的话给出实现过程和demo。关键字检索是如何实现的?和向量检索有什么区别?给出demo和过程

确实,向量检索和关键字检索是两种不同的信息检索方法,它们各自适用于不同类型的应用场景,并且在实现方式上也存在显著差异。

向量检索
定义:向量检索基于文本的语义表示(即向量),通过计算查询与文档之间的相似度来返回最相关的文档。这种方法特别适合处理模糊匹配、语义相似性搜索等复杂查询。

实现过程:

数据预处理:对原始文本进行清洗、分词等操作。
向量化:使用预训练的语言模型将文本转换为固定长度的向量。
索引构建:使用如Faiss或Milvus这样的工具为这些向量建立索引。
查询处理:将用户的查询也转换为向量,并在索引中查找最近邻向量。
示例代码(简化版):

Python
深色版本
from sentence_transformers import SentenceTransformer
import faiss

# 加载模型并生成文档向量
model = SentenceTransformer('all-MiniLM-L6-v2')
documents = ["机器学习是一门多领域交叉学科...", "深度学习是机器学习的一个子集..."]
doc_embeddings = [model.encode(doc) for doc in documents]

# 创建Faiss索引
index = faiss.IndexFlatL2(doc_embeddings[0].shape[0])
for emb in doc_embeddings:
    index.add(emb.reshape(1, -1))

# 查询处理
query = "什么是机器学习?"
query_embedding = model.encode(query)
D, I = index.search(query_embedding.reshape(1, -1), k=2)  # 返回最接近的两个文档

# 输出结果
for idx in I[0]:
    print(f"相关文档: {documents[idx]}")
关键字检索
定义:关键字检索依赖于精确匹配用户查询中的关键词到文档中的词语。它更适合于那些需要高精度匹配的场景,比如特定术语的查找。

实现过程:

数据预处理:包括去除停用词、词干提取等步骤。
倒排索引构建:创建一个映射,其中每个关键词指向包含该词的所有文档ID列表。
查询处理:解析用户输入的查询,直接从倒排索引中查找对应的文档ID。
示例代码(简化版,使用Python标准库):

Python
深色版本
from collections import defaultdict

# 构建倒排索引
inverted_index = defaultdict(list)
documents = {
    0: "机器学习是一门多领域交叉学科",
    1: "深度学习是机器学习的一个子集"
}
for doc_id, text in documents.items():
    words = text.split()
    for word in words:
        inverted_index[word].append(doc_id)

# 查询处理
def search(query):
    terms = query.split()
    result_docs = set(range(len(documents)))  # 初始包含所有文档
    for term in terms:
        if term in inverted_index:
            result_docs &= set(inverted_index[term])  # 取交集
        else:
            return []  # 如果任意一个词不存在,则无结果
    return [documents[doc_id] for doc_id in result_docs]

# 测试查询
query = "机器 学习"
print("查询结果:", search(query))
主要区别
灵活性:向量检索能够捕捉文本间的语义关系,而关键字检索则侧重于词汇级别的精确匹配。
性能:对于大规模数据集,向量检索可能需要更多的计算资源来维持索引结构;关键字检索通常更快,尤其是在使用优化的数据结构如Trie树或B树时。
适用场景:向量检索适合于探索式搜索和推荐系统,关键字检索则更适合于快速定位特定信息。
这两种方法可以根据具体需求单独使用或结合使用,以达到最佳的信息检索效果。

问题3:

实际生产过程中,向量检索内容和关键字检索内容都是在数据库中存储的。这两种数据业界分别采用什么样的数据库存储?原因是什么?

在实际生产环境中,向量检索和关键字检索的内容通常存储于不同的数据库或数据管理系统中,以优化各自的性能和满足特定需求。以下是业界常用的解决方案及其背后的原因:

向量检索

常用数据库/工具

  • Faiss:由Facebook AI Research开发的高效相似度搜索库,专门用于大规模向量搜索。它支持多种索引类型,如IVF(Inverted File)、HNSW(Hierarchical Navigable Small World Graphs)等,能够显著加速最近邻搜索。
  • Milvus:一个开源的向量数据库,旨在管理、存储和搜索大规模向量数据集。Milvus提供了丰富的API接口,易于与现有系统集成,并且支持多种索引技术来提高查询效率。
  • Pinecone:一种云端向量数据库服务,专为实时应用程序设计,特别适合需要快速响应的应用场景。

原因

  • 高效性:这些工具专门为处理高维向量数据设计,采用了先进的算法和技术来加快相似度计算的速度。
  • 可扩展性:它们可以轻松地水平扩展,适应不断增长的数据规模。
  • 灵活性:支持多种距离度量方法(如欧几里得距离、余弦相似度),适用于不同类型的向量数据。

关键字检索

常用数据库/工具

  • Elasticsearch:一个基于Lucene的搜索引擎,广泛应用于全文搜索场景。它支持复杂的查询语法、分词、过滤等功能,非常适合处理关键字检索任务。
  • Solr:另一个流行的开源搜索引擎平台,提供了强大的文本分析能力,以及分布式搜索功能,适合构建大型搜索应用。
  • 传统关系型数据库(如MySQL, PostgreSQL):虽然不是专门为全文搜索设计,但通过添加全文索引插件或使用内置的全文搜索功能,也能有效地支持关键字检索。

原因

  • 精确匹配:这些工具擅长执行精确的关键字匹配,能够快速返回包含特定词汇的所有文档。
  • 丰富查询功能:提供强大的查询语言和过滤选项,允许用户进行复杂查询操作。
  • 易用性和成熟度:这类系统已经非常成熟,拥有良好的社区支持和大量的使用案例,易于部署和维护。

总结

选择合适的数据库主要取决于应用的具体需求。对于向量检索来说,重点在于如何高效地执行相似度搜索,因此倾向于选择那些专门为处理高维向量设计的数据库或工具。而对于关键字检索,则更关注于精确匹配和快速定位,这使得像Elasticsearch这样的全文搜索引擎成为理想的选择。同时,考虑到系统的可扩展性和灵活性,企业可能会根据实际情况组合使用这两种技术,以达到最佳效果。例如,在一些高级的信息检索系统中,可能会先利用向量检索缩小候选范围,再通过关键字检索进一步筛选结果。

深度搜索

相关文章:

构建简单RAG代码实现

步骤1:文档准备与切割 假设我们有一个关于机器学习的PDF文档需要处理。 示例代码: Python 深色版本 from llama_index import SimpleDirectoryReader # 加载文档 documents SimpleDirectoryReader(./data).load_data() 说明: 使用Simple…...

kubeadm拉起的k8s集群证书过期的做法集群已奔溃也可以解决

kubeadm拉起的k8s集群证书过期的做法 这个是很久之前遇到的了,今天有空(心血来潮)就都回忆回忆写在这里为爱发光,部分内容来自arch先生(死党)的帮助。有时候有很多部门提了建k8s的需求,有些是临…...

Ubuntu:20.04更新cmake到更高版本

从输出信息可以看出,您当前的系统中已经安装了 cmake,但版本是 3.16.3,而您的项目需要 CMake 3.18 或更高版本。默认情况下,Ubuntu 20.04 的官方软件仓库中提供的 CMake 版本较低(如 3.16.3),因…...

php 系统命令执行及绕过

文章目录 php的基础概念php的基础语法1. PHP 基本语法结构2. PHP 变量3.输出数据4.数组5.超全局变量6.文件操作 php的命令执行可以执行命令的函数命令执行绕过利用代码中命令(如ls)执行命令替换过滤过滤特定字符串神技:利用base64编码解码的绕…...

【Java】泛型与集合篇 —— Set 接口

目录 Set 接口及实现类HashSet 类特点内部实现构造方法LinkedHashSet 类基本概念特点构造方法常用方法适用场景用 Set 对象实现集合运算TreeSet 类特性构造方法常用方法注意事项对象顺序自然排序定制排序注意事项Set 接口及实现类 HashSet 类 HashSet 是 Java 集合框架中 Set…...

基于YOLOv8的人脸识别系统

文章目录 一.前言 二.原理阐述 三.源代码 四.代码改进 五.流程概述 一.前言 原开源项目是对于某时段校园门口学生出入的视频,使用YOLOv8目标检测算法以及yolov8l-face模型将目标换算成只检测人脸, 通过该模型中的track技术实现检测出的人脸进行自动跟踪, 通过跟踪到的…...

HBuilderX中,VUE生成随机数字,vue调用随机数函数

Vue 中可以使用JavaScript的Math.random() 函数生成随机数,它会返回 0 到 1 之间的浮点数, 如果需要0到1000之前的随机数,可以对生成的随机数乘以1000,再用js的向下取整函数Math.floor() 。 let randNum Math.random(); // 生成…...

论文笔记-WSDM2024-LLMRec

论文笔记-WSDM2024-LLMRec: Large Language Models with Graph Augmentation for Recommendation LLMRec: 基于图增强的大模型推荐摘要1.引言2.前言2.1使用图嵌入推荐2.2使用辅助信息推荐2.3使用数据增强推荐 3.方法3.1LLM作为隐式反馈增强器3.2基于LLM的辅助信息增强3.2.1用户…...

计算四个锚点TOA定位中GDOP的详细步骤和MATLAB例程

该MATLAB代码演示了在三维空间中,使用四个锚点的TOA(到达时间)定位技术计算几何精度衰减因子(GDOP)的过程。如需帮助,或有导航、定位滤波相关的代码定制需求,请联系作者 文章目录 DOP计算原理MATLAB例程运行结果示例关键点说明扩展方向另有文章: 多锚点Wi-Fi定位和基站…...

Lookup Join显著增强,Paimon1.0版本如何做的?

Hi,大家好,我们又满血复活了。 2025年开年更新频率不快,一方面是大模型如火如荼,也一直在补相关知识;另外一方面,新的一年里身体健康被我摆到了第一位,不会像前几年那么卷了。 后续我们的更新会…...

【Golang学习之旅】如何在Go语言中使用Redis实现分布式锁,并解决锁过期导致的并发问题?

文章目录 前言1. 分布式锁的基本原理1.1 锁过期导致并发问题的解决: 2. Go实现分布式锁3. 代码实现分布式锁3.1 安装Go-Redis包3.2 创建分布式锁工具函数3.3 代码解析 4. 如何避免锁过期导致的并发问题4.1 延长锁的有效期4.2 利用Redis的WATCH命令(乐观锁…...

Vue前端开发-Vant组件之Button组件

Vant 有丰富的UI组件,而基础组件是全部组件的核心,基础组件中将常用的元素做了二次的开发,封装成Vant格式组件,如按钮、图片和布局等,这些封装后的Vant组件,提供了更多面向实际应用的属性和事件&#xff0c…...

DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方DeepSeek接入)

前言 在当今数字化时代,AI编程助手已成为提升开发效率的利器。DeepSeek作为一款强大的AI模型,凭借其出色的性能和开源免费的优势,成为许多开发者的首选。今天,就让我们一起探索如何将DeepSeek接入PyCharm,实现高效、智…...

【Linux网络编程】应用层协议HTTP(请求方法,状态码,重定向,cookie,session)

🎁个人主页:我们的五年 🔍系列专栏:Linux网络编程 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 ​ Linux网络编程笔记: https://blog.cs…...

健康养生:从生活细节开启活力之旅

在忙碌的现代生活里,健康养生不再是一个抽象概念,而是关乎生活质量的关键。其实,只要掌握日常养生要点,就能轻松开启活力满满的健康生活。 饮食是健康的基石。每日饮食需遵循 “彩虹原则”,摄入多种颜色食物。早餐时&…...

DeepSeek + Mermaid编辑器——常规绘图

下面这张图出自:由清华大学出品的 《DeepSeek:从入门到精通》。 作为纯文本生成模型,DeepSeek虽不具备多媒体内容生成接口,但其开放式架构允许通过API接口与图像合成引擎、数据可视化工具等第三方系统进行协同工作,最终…...

DevOps自动化部署详解:从理念到实践

在软件开发日益快速迭代的今天,如何以高效、稳定且可重复的方式将代码变更从开发环境自动部署到生产环境成为企业竞争的重要因素。DevOps 正是在这一背景下应运而生,它打破开发、测试、运维之间的壁垒,通过自动化工具和流程,实现持…...

【拥抱AI】GPT Researcher的诞生

一、GPT Researcher 研究过程总结 GPT Researcher 是一个开源的自主智能体,旨在通过利用人工智能技术实现高效、全面且客观的在线研究。它通过一系列创新的设计和优化,解决了传统研究工具(如 AutoGPT)中存在的问题,如…...

Redis7——基础篇(三)

前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。 基础篇: Redis(一)Redis(二) 接上期内容:上期完成了Redis的基本…...

ES12 weakRefs的用法和使用场景

ES12 (ECMAScript 2021) 特性总结:WeakRef 1. WeakRef 概述 描述 WeakRef 是 ES12 引入的一个新特性,用于创建对对象的弱引用。弱引用不会阻止垃圾回收器回收对象,即使该对象仍然被弱引用持有。WeakRef 通常与 FinalizationRegistry 结合使…...

【Elasticsearch】搜索时分片路由

Elasticsearch 的Search Shard Routing(搜索分片路由)是一个核心机制,用于在分布式环境中高效地分发和执行搜索请求,确保查询能够快速、准确地返回结果,同时充分利用集群资源并保持系统的高可用性。以下是结合上述内容…...

MySQL登录问题总结

不管何种数据库,使用的第一步都是先登录。 MySQL命令行登录语句:mysql -u username -P port -p -D database_name 登录MySQL的报错一般从报错信息都能得到反馈,常见报错原因分析如下,实例中的以test用户为例,登录环境为…...

一些耳朵起茧子的名词解释

1 web应用 1.1 web应用的概念 Web应用(Web Application) 是一种通过浏览器访问的软件程序,它运行在服务器上,用户通过网络(如互联网或内网)与它进行交互。与传统网站(主要提供静态内容&#x…...

Redis 持久化:从零到掌握

Redis 作为一款广泛使用的内存数据库,虽然核心功能是基于内存提供高性能的数据存取,但在实际应用中,数据的持久化是不可忽视的。毕竟,内存中的数据一旦出现故障或重启,就会面临数据丢失的风险。因此,Redis …...

Mybatis MyBatis框架的缓存 一级缓存

1. 缓存的概念 缓存的概念 在内存中临时存储数据,速度快,可以减少数据库的访问次数。经常需要查询,不经常修改的数据,不是特别重要的数据都适合于存储到缓存中。 2.Mybatis缓存 mybatis包含了一个非常强大的查询缓存特性&#…...

第1章大型互联网公司的基础架构——1.6 RPC服务

你可能在1.1节的引言中注意到业务服务层包括HTTP服务和RPC服务,两者的定位不一样。一般来说,一个业务场景的核心逻辑都是在RPC服务中实现的,强调的是服务于后台系统内部,所谓的“微服务”主要指的就是RPC服务;而HTTP服…...

多个用户如何共用一根网线传输数据

前置知识 一、电信号 网线(如以太网线)中传输的信号主要是 电信号,它携带着数字信息。这些信号用于在计算机和其他网络设备之间传输数据。下面是一些关于网线传输信号的详细信息: 1. 电信号传输 在以太网中,数据是…...

idea-gradle打包运行配置

最近接触了一个项目,使用gradle做为构建工具,这里记录一波,毕竟平时使用的都是maven idea 配置 这里有个坑,Gradle Wrapper,配置的地址gradle下载超时 这个配置修改成阿里的 第一张 第二张 第二张配置的jvm貌似没啥用…...

(新版本onenet)stm32+esp8266/01s mqtt连接onenet上报温湿度和远程控制(含小程序)

物联网实践教程:微信小程序结合OneNET平台MQTT实现STM32单片机远程智能控制 远程上报和接收数据——汇总 前言 之前在学校获得了一个新玩意:ESP-01sWIFI模块,去搜了一下这个小东西很有玩点,远程控制LED啥的,然后我就想…...

一键部署开源DeepSeek并集成到钉钉

一键部署开源DeepSeek并集成到钉钉 简介: DeepSeek发布了两款先进AI模型V3和R1,分别适用于对话AI、内容生成及推理任务。由于官方API流量限制,阿里云推出了私有化部署方案,无需编写代码即可完成部署,并通过计算巢AppF…...