【橘子大模型】初探rag知识库的构建

一、简介

我们在实现了一系列功能之后,终于来到了rag的部分,下面我们将基于langchain来实现一个rag检索。
关于rag方面的知识,可以查看这两篇文章:
大模型应用之RAG详解
什么是 RAG(检索增强生成)
或者是去油管上IBM Technology专栏,他们在这方面的简介令人印象深刻。
好了,我们还是简单来描述一下rag文本处理的一个流程。

  • 数据加载
  • 文本分块
  • 文本嵌入
  • 创建索引

其实简单理解就是你要把一个外部的文档(各种格式)进行拆分,然后做嵌入(向量化),存储进向量库,作为检索的语料。
这就是我们今天主要要做的,我们要基于langchain来实现一下,然后后面不断完善他。

二、代码实现

1、启动es

我们需要使用es进行向量结果的存储,所以我们简单启动一个es,我们选择8.17.2
配置文件我们简单配置一下,不启动太多的安全检测。如果你想启动生产级别的单点配置,可以参考使用docker搭建ELK环境

cluster.name: my-application
node.name: node-1
http.port: 9200
xpack.security.http.ssl.enabled: false
xpack.security.enabled: false
xpack.security.transport.ssl.enabled: false
xpack.ml.enabled: false

kibana我们就不配置了,启动之后我们来编写python代码。

2、代码实现

我们准备两个pdf,我准备的是山东省公布的对台湾同胞的政策和潍坊的美食介绍。分别是lutai.pdf,weifangfood.pdf。
我们来看一下langchain对于文档加载的支持。这部分内容位于langchain的文档加载
你能看到他支持多种文件格式的加载。
Webpages:网络页面
PDFs:pdf文件

我们这里使用的就是pdf加载器。我们就用这个,PyPDF文档
你按照他的那个步骤安装这个包就好了:

pip install -qU pypdf

我们在pycharm中的虚拟环境中加载这个就可以了,前面我们弄过了,可以直接去看前面的文章就行。

from langchain_community.document_loaders import PyPDFLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_ollama import OllamaEmbeddings
from langchain_elasticsearch import ElasticsearchStore
from uuid import uuid4from langchain_core.documents import Document# 构建一个文件数组,后期用来解析
pdf1 = './weifangfood.pdf'
pdf2 = './lutai.pdf'
pdfs = [pdf1,pdf2]
docs = []# 解析pdf拆分文档
for pdf in pdfs:# 构建pdf loaderloader = PyPDFLoader(pdf)# 添加到文档数组中,后面就处理这个docs.extend(loader.load())# 对文档结果做切分,每一块切1000个字符,重叠大约200个,并且设置索引(做编号,标记这个切分结果来自于文档切分的哪一块)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=200,add_start_index=True)
split_text_list = text_splitter.split_documents(docs)# 构建向量化组件
embed = OllamaEmbeddings(model="llama3.2:latest")# 构建es向量存储器
elastic_vector_search = ElasticsearchStore(es_url="http://localhost:9200",index_name="langchain_index",embedding=embed,
)documents = []
for text in split_text_list:# 向量化,输出的就是向量结果# vector = embed.embed_query(text.page_content)# 对拆分的文本构建一个文档结构document = Document(page_content = text.page_content,metadata = text.metadata,)documents.append(document)uuids = [str(uuid4()) for _ in range(len(documents))]
# 添加到es向量存储中
elastic_vector_search.add_documents(documents=documents, ids=uuids)

以上代码均可参考以下文档来实现。
文本向量化
向量数据库选择
es向量化存储

运行之后他会自动在es中创建一个索引langchain_index,然后把你的文档向量化的结果存储进es中。

3、向量化结果

我们运行之后,查看一下这个索引。

{"langchain_index": {"aliases": {},"mappings": {"properties": {"metadata": {"properties": {"author": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"comments": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"company": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"creationdate": {"type": "date"},"creator": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"keywords": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"moddate": {"type": "date"},"page": {"type": "long"},"page_label": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"producer": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"source": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"sourcemodified": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"start_index": {"type": "long"},"subject": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"title": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"total_pages": {"type": "long"},"trapped": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}}}},"text": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"vector": {"type": "dense_vector","dims": 3072,"index": true,"similarity": "cosine","index_options": {"type": "int8_hnsw","m": 16,"ef_construction": 100}}}},"settings": {"index": {"routing": {"allocation": {"include": {"_tier_preference": "data_content"}}},"number_of_shards": "1","provided_name": "langchain_index","creation_date": "1744981253591","number_of_replicas": "1","uuid": "JdwR_WlTQzWtzFRlVCv-rw","version": {"created": "8521000"}}}}
}

我们来主要分析一下他的这些字段,或者你可以在代码中输出结果来看下。我们在es中直接查看即可。

  • text:你在把文本拆分之后然后对每一段进行向量化存储,每一段就是一条es doc。text存储了这一段的原文。
  • metadata:元数据,这里是一个层级结构,下层还存储着当前段来自哪个文档,属于第几段。这个文档一共拆分了几段,当前这一段属于第几段,等等元信息。
  • vector:double类型的数组,其实就是当前段向量化之后的结果。

我们来看其中一个段的结果:

{"_index": "langchain_index","_id": "e5bb54ff-8269-4e0b-8cb3-3952dc4d57b9","_score": 1,"_ignored": ["text.keyword"],"_source": {"text": """中国台湾网 815 日济南讯 731 日,山东省正式发布实施《关
于促进鲁台经济文化交流合作的若干措施》,该措施共 56 条,其中
促进鲁台经济合作 23 条措施、促进鲁台文教交流 14 条措施,支持
台湾同胞在鲁学习创业就业生活 19 条。措施涵盖产业合作、就业、
人才引进、知识产权保护、文教合作及职业资格考试、证件办理等
方面,综合运用了财税、金融、用地等政策手段,并明确规定今后
山东省各级政府在制定发展规划、设立扶持资金和出台支持政策时,
都将保障符合条件的台资企业和台湾同胞享有同等待遇。
山东是大陆国有经济大省、基础设施建设不断发展,该措施支
持台湾民间资本与山东国有资本共同设立股权投资基金、产业投资
基金,支持台资参与山东高速公路、轨道交通等多方面基础设施建
设,让台商台企率先享受山东发展红利,实现两岸资本合作共赢。
山东也是儒家文化发源地和教育人力资源大省,措施扶持台湾同胞、
台湾高校研究机构和民间社团参与承接山东文化产业工程项目,联
合开展教学改革和共建研究生培养基地,大力拓展两岸文化融合的
深度广度,特别是将大力吸引台湾儒学研究高端人才到山东开展儒
学研究和传播工作,符合条件的给予优厚待遇。同时,该措施也针
对台商反映的“退城进园”、农业土地流转合同到期优先续租、子
女就学、台胞行医等做出了统筹管理和制度化安排。
据悉,山东省人大正加紧制定保护促进台胞在山东投资权益的
地方立法条例,条例将吸收本次出台的 56 条措施,在法律层面上对
台胞应享有权益予以明确和保障。""","metadata": {"producer": "","creator": "WPS 文字","creationdate": "2024-07-30T17:08:05+09:08","author": "","comments": "","company": "","keywords": "","moddate": "2024-07-30T17:08:05+09:08","sourcemodified": "D:20240730170805+09'08'","subject": "","title": "","trapped": "/False","source": "./lutai.pdf","total_pages": 14,"page": 0,"page_label": "1","start_index": 0},"vector": [0.017683318,0.010620082,0.02021882,-0.0032659627,......0.006196561]}}

4、相似性检索

我们把文本向量化之后,我们就可以执行一些向量检索,这个是es中一个比较重要的概念,文档位于ai检索
我们使用langchain中的一些封装就可以。文档同样位于langchain相似性检索

from langchain_ollama import OllamaEmbeddings
from langchain_elasticsearch import ElasticsearchStore# 向量化
embed = OllamaEmbeddings(model="llama3.2:latest")# 存储es
elastic_vector_search = ElasticsearchStore(es_url="http://localhost:9200",index_name="langchain_index",embedding=embed,
)
# 使用相似性检索
results = elastic_vector_search.similarity_search_with_score(query="进鲁台经济合作方面",k=1,
)# 输出检索结果
for doc, score in results:print(f"* [SIM={score:3f}] {doc.page_content} [{doc.metadata}]")

这个检索结果有很大提升空间,我们后面整合到llm中再说。

5、Retrievers 检索器

我们的langchain中有很多向量检索的api,es的 pgsql的很多。这种都有各自的使用方式,于是langchain封装了一个上层实现Retrievers 检索器
众多实现都实现了这个接口,我们可以直接使用这个上层接口来屏蔽底层的实现。我们来简单实现一个。

from langchain_ollama import OllamaEmbeddings
from langchain_elasticsearch import ElasticsearchStore# 向量化
embed = OllamaEmbeddings(model="llama3.2:latest")# 存储es
elastic_vector_search = ElasticsearchStore(es_url="http://localhost:9200",index_name="langchain_index",embedding=embed,
)
# 构建一个Retrievers 检索器,使用similarity相似性检索。k:1表示每一个问题都只返回一个回答
retriever = elastic_vector_search.as_retriever(search_type="similarity",search_kwargs={"k":1}
)# 批量执行两个问题
resp = retriever.batch(["台湾同胞在山东就业期间有什么政策","潍坊有啥好吃的"]
)
# 返回输出
for result in resp:print(result)

这就是检索器的简单使用,我们后面再来探究其深入使用。

三、总结

我们到此完成了文本的rag存储,后面我们将会使用rag增强检索来增强大模型的问答效果。

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

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

相关文章

CentOS7执行yum命令报错 Could not retrieve mirrorlist http://mirrorlist.centos.org

CentOS7执行yum命令报错 引更新yum源备份原有源创建新的源文件清理并重建缓存 引 CentOS 7 系统无法连接到 CentOS 的官方镜像站点。这通常是由于网络问题或 CentOS 7 已停止维护导致的(2024年6月30日后 CentOS 7 已进入 EOL) 报错明细: 已…

VSCode安装与环境配置(Mac环境)

20250419 - 概述 大概是非常久之前了,装了VSCode,估计都得21的时候了,电脑上也没更新过。当时安装也直接装上就完事了。这次把版本更新一下,同时记录一下这个安装过程。 安装 mac下安装非常简单,直接从官网下载&am…

QML动画--ParallelAnimation和SequentialAnimation

一、ParallelAnimation ParallelAnimation 是 QML 中用于并行执行多个动画的容器动画类型,可以同时运行多个子动画。 基本用法 qml import QtQuick 2.15Rectangle {id: rectwidth: 100; height: 100color: "red"x: 0; y: 0; opacity: 1.0ParallelAnim…

NLP高频面试题(四十三)——什么是人类偏好对齐中的「对齐税」(Alignment Tax)?如何缓解?

一、什么是「对齐税」(Alignment Tax)? 所谓「对齐税」(Alignment Tax),指的是在使人工智能系统符合人类偏好的过程中,所不可避免付出的性能损失或代价。换句话说,当我们迫使AI遵循人类价值观和规范时,AI系统往往无法达到其最大理论性能。这种性能上的妥协和折衷,就…

速查手册:TA-Lib 超过150种量化技术指标计算全解 - 1. Overlap Studies(重叠指标)

速查手册:TA-Lib 超过150种量化技术指标计算全解 - 1. Overlap Studies(重叠指标) TA-Lib(Technical Analysis Library)是广泛使用的金融技术分析库,实现了超过150种技术指标计算函数,适用于股票…

重构未来智能:Anthropic 解码Agent设计哲学三重奏

第一章 智能体进化论:从工具到自主体的认知跃迁 1.1 LLM应用范式演进图谱 阶段技术形态应用特征代表场景初级阶段单功能模型硬编码规则执行文本摘要/分类进阶阶段工作流编排多模型协同调度跨语言翻译流水线高级阶段自主智能体动态决策交互编程调试/客服对话 1.1.…

Git 中修改某个特定的commit提交内容

在 Git 中修改某个特定的提交(commit)通常需要使用 交互式变基(Interactive Rebase) 或 修改提交(Commit Amend)。以下是不同场景下的具体操作步骤: 一、修改最近的提交(最新提交&am…

ZLMediaKit流媒体服务器

ZLMediaKit 简介 ZLMediaKit 是一个基于 C11 开发的高性能流媒体服务器框架,支持 RTSP、RTMP、HLS、HTTP-FLV、WebSocket-FLV、HTTP-TS、WebSocket-TS、HTTP-fMP4、WebSocket-fMP4 等多种流媒体协议。 主要特性 多协议支持: 支持 RTSP/RTMP/HLS/HTTP-F…

数字电子技术基础(五十)——硬件描述语言简介

目录 1 硬件描述语言简介 1.1 硬件描述语言简介 1.2 硬件编程语言的发展历史 1.3 两种硬件描述的比较 1.4 硬件描述语言的应用场景 1.5 基本程序结构 1.5.1 基本程序结构 1.5.2 基本语句和描述方法 1.5.3 仿真 1 硬件描述语言简介 1.1 硬件描述语言简介 硬件描述语…

SQL系列:常用函数

1、【MySQL】合并字段函数(列转行) 它可以将两个字段中的数据合并到一个字段中。 1)CONCAT函数 CONCAT函数可以将多个字段中的数据合并到一个字段中。它的语法格式如下: SELECT CONCAT(字段1,字段2,...字段N) FROM 表名;SELEC…

多线程和线程同步

多线程在项目开发中使用频率高,使用多线程能够提高程序的并发性 提高程序的并发性:1.多线程,对系统资源的消耗更小一些 2.多进程 系统的cpu资源有线,cpu时间片被分好后,由系统进行调度,每个线程在执行的时候都需要抢这个cpu的时间片。如果抢到了,就执行,如果没抢到,…

时序数据预测:TDengine 与机器学习框架的结合(一)

一、引言 在当今数字化时代,时序数据如潮水般涌来,广泛存在于物联网、工业监控、金融交易、气象监测等众多领域。这些按时间顺序记录的数据蕴含着丰富的信息,对其进行准确预测,能够为企业和组织的决策提供有力支持,带…

elementUI中MessageBox.confirm()默认不聚焦问题处理

在项目中使用elementUI的MessageBox.confirm()出现了默认不聚焦的问题,默认确认按钮是浅色的,需要点击一下才会变成正常。面对这种问题,创建新组件,实现聚焦。替换默认的MessageBox.confirm() 解决 创建components/MessageBoxCo…

yarn的定义

YARN 即 Yet Another Resource Negotiator,它是 Apache Hadoop 2.x 及后续版本中的集群资源管理系统,也是 Hadoop 生态系统的核心组件之一。 YARN 的诞生是为了解决 Hadoop 1.x 中 MapReduce 框架将资源管理和作业调度任务耦合在一起所带来的可扩展性差等…

http、https、TLS、证书原理理解,对称加密到非对称加密问题,以及对应的大致流程

http 超文本传输协议 存在问题: 安全性、隐私性、数据完整性 易被中间人(黑客之类的)对数据进行劫持、篡改、隐私泄露 引出了 https (source) http 在网络模型中的应用层 Application > transport > inter…

深度补全网络:如CSPN++填补稀疏点云的深度信息

深度补全网络:CSPN填补稀疏点云的深度信息 深度补全(Depth Completion)是计算机视觉中的一个重要任务,旨在从稀疏的深度测量中恢复密集的深度图。CSPN(Convolutional Spatial Propagation Network)是这一领域的前沿方法之一。 CSPN概述 CSPN是对原始CSPN…

QT网络拓扑图绘制实验

前言 在网络通讯中,我qt常用的是TCP或者UDP协议,就比方说TCP吧,一台服务器有时可能会和多台客户端相连接,我之前都是处理单链接情况,最近研究图结构的时候,突然就想到了这个问题。那么如何解决这个问题呢&…

DNS主从同步实验

dns域名解析原理 实验步骤1、主dns要完成dns解析:192.168.21.128 [rootlocalhost ~]# yum install bind -y [rootlocalhost ~]# systemctl start named [rootlocalhost ~]# vim /etc/named.conf options { listen-on port 53 { any; }; direct…

知识了解03——怎么解决使用npm包下载慢的问题?

1、为什么使用npm下载包会下载的慢 因为使用npm下载包时,默认使用国外服务器进行下载,此时的网络传输需要经过漫长的海底电缆,因此下载速度会变慢 2、怎么解决?(切换镜像源) (1)方…

在Ubuntu系统中安装和升级RabbitVCS

在Ubuntu系统中安装和升级RabbitVCS 目前在ubuntu中使用svn的GUI工具,已经安装了。想升级一下。 当前遇到的问题是,我想用它看看我当前的代码对应的版本号,然后再决定是否update。但是,好像我看不出来。根本不如在windows使用To…