基于大模型和向量数据库的 RAG 示例

news2024/9/20 8:06:24

1        RAG 介绍

RAG是一种先进的自然语言处理方法,它结合了信息检索和文本生成技术,用于提高问答系统、聊天机器人等应用的性能。

2        RAG 的工作流程

  1. 文档加载(Document Loading)

    • 从各种来源加载大量文档数据。
    • 这些文档将作为知识库,用于后续的信息检索。
  2. 文档分割(Document Splitting)

    • 将加载的文档分割成更小的段落或部分。
    • 这有助于提高检索的准确性和效率。
  3. 嵌入向量生成(Embedding Generation)

    • 对每个文档或文档的部分生成嵌入向量。
    • 这些嵌入向量捕捉文档的语义信息,方便后续的相似度比较。
  4. 写入向量数据库(Writing to Vector Database)

    • 将生成的嵌入向量存储在一个向量数据库中。
    • 数据库支持高效的相似度搜索操作。
  5. 查询生成(Query Generation)

    • 用户提出一个问题或输入一个提示。
    • RAG模型根据输入生成一个或多个相关的查询。
  6. 文档检索(Document Retrieval)

    • 使用生成的查询在向量数据库中检索相关文档。
    • 选择与查询最相关的文档作为信息源。
  7. 上下文融合(Context Integration)

    • 将检索到的文档内容与原始问题或提示融合,构成扩展的上下文。
  8. 答案生成(Answer Generation)

    • 基于融合后的上下文,RAG生成模型产生最终的回答或文本。
    • 这一步骤旨在综合原始输入和检索到的信息。

3        准备环境

3.1        向量数据库环境

已经通过百度向量数据库测试申请的才能访问创建,地址:VectorDB 向量数据库官网页-百度智能云

1        创建百度向量数据库实例,注意需要地域,可用区需要和 BCC 保持在同一个 VPC 内。 地址:百度智能云-向量数据库

image1.png

2        创建成功后,通过实例详情页查看访问的地址信息和账号信息,用于访问操作向量数据库。如例子截图,访问信息如下:

# 访问地址格式:http://${IP}:${PORT}
访问地址:http://192.168.20.4:5287
账号:root
密钥:xxxx

image2.png

image3.png

3.2         开通千帆 Embedding 模型

千帆模型开通付费之后才能使用,开通不会产生费用,且有代金券赠送

1        开通千帆 Embedding 模型的收费,地址: 百度智能云千帆大模型平台

image4.png

2        右上角个人中心的安全认证里面提取用于鉴权调用 Embedding 模型的 Access Key 和 Secret Key

image5.png

3.3        客户端环境

3.3.1        数据准备和写入

本例子使用的是 bcc 计算型 c5 2c4g 实例基于 Centos 系统作为例子,但不仅限于 bcc,只要是同 vpc 内的服务器产品都可以。已经有 BCC 客户端的用户忽略步骤 1。

1        创建 BCC 客户端。 地址:百度智能云

image6.png

2        登录创建的实例进行环境准备,部署安装 python 环境和搭建知识库所必须的依赖包,

# 安装 python 3.9
yum install -y python39
# langchain 依赖包,用于把文本数据转化为向量数据。
pip3.9 install langchain
# pymochow 依赖包,用于访问和操作百度向量数据库。
pip3.9 install pymochow
# qianfan 依赖包,用于访问千帆大模型。
pip3.9 install qianfan
# pdfplumber 依赖包,加载除了 pdf 文档。
pip3.9 install pdfplumber
# 创建项目目录
mkdir -p knowledge/example_data && cd knowledge

3        上传一个 PDF 文件到 knowledge/example_data 目录下

4        创建访问的配置文件

# config.py
import os
from pymochow.auth.bce_credentials import BceCredentials

# 定义配置信息
account = 'root'
api_key = '修改为你的密钥'
endpoint = '修改为之前记录的访问地址,如 http://192.168.20.4:5287'

# 初始化BceCredentials对象
credentials = BceCredentials(account, api_key)

# 设置千帆AI平台的安全认证信息(AK/SK),通过环境变量
# 注意替换以下参数为您的Access Key和Secret Key
os.environ["QIANFAN_ACCESS_KEY"] = "your_iam_ak"
os.environ["QIANFAN_SECRET_KEY"] = "your_iam_sk"

5        创建 document 数据库

import pymochow
from pymochow.configuration import Configuration
import config  # 导入配置文件

config_obj = Configuration(credentials=config.credentials, endpoint=config.endpoint)
client = pymochow.MochowClient(config_obj)

try:
    db = client.create_database("document")
except Exception as e:  # 捕获所有类型的异常
    print(f"Error: {e}")  # 打印异常信息
db_list = client.list_databases()
for db_name in db_list:
    print(db_name.database_name)
client.close()

6        创建 chunks 数据表

import time
import pymochow  # 导入pymochow库,用于操作数据库
from pymochow.configuration import Configuration  # 用于配置客户端
import config  # 导入配置文件,包含身份验证和终端信息

# 导入pymochow模型相关的类和枚举类型
from pymochow.model.schema import Schema, Field, VectorIndex, SecondaryIndex, HNSWParams
from pymochow.model.enum import FieldType, IndexType, MetricType, TableState
from pymochow.model.table import Partition

# 使用配置文件中的信息初始化客户端
config_obj = Configuration(credentials=config.credentials, endpoint=config.endpoint)
client = pymochow.MochowClient(config_obj)

# 选择或创建数据库
db = client.database("document")

# 定义数据表的字段
fields = [
    Field("id", FieldType.UINT64, primary_key=True, partition_key=True, auto_increment=False, not_null=True),
    Field("source", FieldType.STRING),
    Field("author", FieldType.STRING, not_null=True),
    Field("vector", FieldType.FLOAT_VECTOR, dimension=384)
]

# 定义数据表的索引
indexes = [
    VectorIndex(index_name="vector_idx", field="vector", index_type=IndexType.HNSW, metric_type=MetricType.L2, params=HNSWParams(m=32, efconstruction=200)),
    SecondaryIndex(index_name="author_idx", field="author")
]

# 尝试创建数据表,捕获并打印可能出现的异常
try:
    table = db.create_table(table_name="chunks", replication=3, partition=Partition(partition_num=1), schema=Schema(fields=fields, indexes=indexes))
except Exception as e:  # 捕获所有类型的异常
    print(f"Error: {e}")  # 打印异常信息

# 轮询数据表状态,直到表状态为NORMAL,表示表已准备好
while True:
    time.sleep(2)  # 每次检查前暂停2秒,减少对服务器的压力
    table = db.describe_table("chunks")
    if table.state == TableState.NORMAL:  # 表状态为NORMAL,跳出循环
        break
    time.sleep(10)  # 如果状态不是NORMAL,等待更长时间再次检查

# 打印数据表的详细信息
print("table: {}".format(table.to_dict()))

client.close()  # 关闭客户端连接

7        从PDF文档中加载数据、将文档内容分割为更小的文本块以及利用千帆AI平台的接口来对文本进行向量化表示,并且写到 chunks 表,本例子会用小的文档作为例子,用户可以根据实际情况加载。

# 导入必要的库
from langchain_community.document_loaders import PDFPlumberLoader  # 用于加载PDF文档
from langchain.text_splitter import RecursiveCharacterTextSplitter  # 用于文本分割
import os  # 用于操作系统功能,如设置环境变量
import qianfan  # 千帆AI平台SDK
import time  # 用于暂停执行,避免请求频率过高
import pymochow
import config  # 导入配置文件
from pymochow.model.table import Row # 用于写入向量数据
from pymochow.configuration import Configuration


# 加载PDF文档
loader = PDFPlumberLoader("./example_data/ai-paper.pdf")  # 指定PDF文件路径
documents = loader.load()  # 加载文档
print(documents[0])  # 打印加载的第一个文档内容

# 设置文本分割器,指定分割的参数
# chunk_size定义了每个分割块的字符数,chunk_overlap定义了块之间的重叠字符数
# separators列表定义了用于分割的分隔符
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=384, 
    chunk_overlap=0, 
    separators=["\n\n", "\n", " ", "", "。", ","]
)
all_splits = text_splitter.split_documents(documents)  # 对文档进行分割
print(all_splits[0])  # 打印分割后的第一个块内容

emb = qianfan.Embedding()  # 初始化嵌入模型对象

embeddings = []  # 用于存储每个文本块的嵌入向量
for chunk in all_splits:  # 遍历所有分割的文本块
    # 获取文本块的嵌入向量,使用默认模型Embedding-V1
    resp = emb.do(texts=[chunk.page_content])
    embeddings.append(resp['data'][0]['embedding'])  # 将嵌入向量添加到列表中
    time.sleep(1)  # 暂停1秒,避免请求过于频繁
print(embeddings[0])  # 打印第一个文本块的嵌入向量

# 逐行写入向量化数据
rows = []
for index, chunk in enumerate(all_splits):
    row = Row(
        id=index,
        source=chunk.metadata["source"],
        author=chunk.metadata["Author"],
        vector=embeddings[index]
    )
    rows.append(row)
# 打印第一个Row对象转换成的字典格式,以验证数据结构
print(rows[0].to_dict())

# 读取数据库配置文件,并且初始化连接
config_obj = Configuration(credentials=config.credentials, endpoint=config.endpoint)
client = pymochow.MochowClient(config_obj)

# 选择或创建数据库
db = client.database("document")

try:
    table = db.describe_table("chunks")
    table.upsert(rows=rows) # 批量写入向量数据,一次最多支持写入1000条
    table.rebuild_index("vector_idx") # 创建向量索引,必要步骤
except Exception as e:  # 捕获所有类型的异常
    print(f"Error: {e}")  # 打印异常信息
client.close()

当打印到如下的数据证明你写入成功了。

image7.png

3.3.2        文档检索

1        基于标量的检索

import pymochow
from pymochow.configuration import Configuration
import config  # 导入配置文件

config_obj = Configuration(credentials=config.credentials, endpoint=config.endpoint)
client = pymochow.MochowClient(config_obj)

# 选择或创建数据库
db = client.database("document")

try:
    table = db.describe_table("chunks")
    primary_key = {'id': 0}
    projections = ["id", "source", "author"]
    res = table.query(
        primary_key=primary_key, 
        projections=projections, 
        retrieve_vector=True
    )
except Exception as e:  # 捕获所有类型的异常
    print(f"Error: {e}")  # 打印异常信息

print(res)
client.close()

结果显示如下:

image8.png

2        基于向量的检索

import os
import config
import pymochow
import qianfan
from pymochow.configuration import Configuration
from pymochow.model.table import AnnSearch, HNSWSearchParams

# 初始化千帆AI平台的嵌入模型对象
emb = qianfan.Embedding()

# 定义待查询的问题文本
question = "讲解下大模型的发展趋势"

# 获取问题文本的嵌入向量
resp = emb.do(texts=[question])
question_embedding = resp['data'][0]['embedding']

# 使用配置信息初始化向量数据库客户端
config_obj = Configuration(credentials=config.credentials, endpoint=config.endpoint)
client = pymochow.MochowClient(config_obj)

# 选择数据库
db = client.database("document")

try:
    # 获取指定表的描述信息
    table = db.describe_table("chunks")
    # 构建近似最近邻搜索对象
    anns = AnnSearch(
        vector_field="vector",  # 指定用于搜索的向量字段名
        vector_floats=question_embedding,  # 提供查询向量
        params=HNSWSearchParams(ef=200, limit=1)  # 设置HNSW算法参数和返回结果的限制数量
    )
    # 执行搜索操作
    res = table.search(anns=anns)
    # 打印搜索结果
    print(res)
except Exception as e:  # 捕获并打印所有异常信息
    print(f"Error: {e}")

# 关闭客户端连接
client.close()

3        基于标量和向量的混合检索

import os
import config
import pymochow
import qianfan
from pymochow.configuration import Configuration
from pymochow.model.table import AnnSearch, HNSWSearchParams

# 初始化千帆AI平台的嵌入模型对象
emb = qianfan.Embedding()

# 定义待查询的问题文本
question = "讲解下大模型的发展趋势"

# 获取问题文本的嵌入向量
resp = emb.do(texts=[question])
question_embedding = resp['data'][0]['embedding']

# 使用配置信息初始化向量数据库客户端
config_obj = Configuration(credentials=config.credentials, endpoint=config.endpoint)
client = pymochow.MochowClient(config_obj)

# 选择数据库
db = client.database("document")

try:
    # 获取指定表的描述信息
    table = db.describe_table("chunks")
    # 构建近似最近邻搜索对象
    anns = AnnSearch(
        vector_field="vector",  # 指定用于搜索的向量字段名
        vector_floats=question_embedding,  # 提供查询向量
        params=HNSWSearchParams(ef=200, limit=1),  # 设置HNSW算法参数和返回结果的限制数量
        filter="author='CNKI'" # 提供标量的过来条件
    )
    # 执行搜索操作
    res = table.search(anns=anns)
    # 打印搜索结果
    print(res)
except Exception as e:  # 捕获并打印所有异常信息
    print(f"Error: {e}")

# 关闭客户端连接
client.close()

当然后续还需要上下文融合和答案生成,可以基于百度文心大模型的能力实现,本文篇幅有限就不详细展开了。

原文链接:千帆+Langchain+VectorDB 建立简单的 RAG 示例 - 向量数据库 - 设计架构

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

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

相关文章

基于微信小程序的校园跑腿小程序,附源码

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

SpringBoot(接受参数相关注解)

文章目录 1.基本介绍2.PathVariable 路径参数获取信息1.代码实例1.index.html2.ParameterController.java3.测试 2.细节说明 3.RequestHeader 请求头获取信息1.代码实例1.index.html2.ParameterController.java3.测试 2.细节说明 4.RequestParameter 请求获取参数信息1.代码实例…

08-java基础-锁之AQSReentrantLockBlockingQueueCountDownLatchSemapho

文章目录 0:AQS简介-常见面试题AQS具备特性state表示资源的可用状态AQS定义两种资源共享方式AQS定义两种队列自定义同步器实现时主要实现以下几种方法:同步等待队列条件等待队列 1:AQS应用之ReentrantLockReentrantLock如何实现synchronized不…

如何选购自助咖啡机?这三点是关键!

在竞争激烈的咖啡市场中,既有知名咖啡连锁品牌,也有众多咖啡馆和小型连锁店,无人智能饮品机要想在激烈的竞争中脱颖而出,发挥自身优势:快速便捷是关键,同时好的口感才能留客,因此饮品机的选购成…

MES管理系统中电子看板都有哪些类型?

随着工业信息化和智能制造的不断发展,MES管理系统已经成为现代制造业不可或缺的重要工具。MES管理系统通过集成和优化生产过程中的各个环节,实现对生产过程的实时监控、调度和管理,提高生产效率和质量。 在生产制造过程中,看板管…

第七届国际通信与网络工程会议(ICCNE 2024)即将召开!

2024年第七届国际通信与网络工程会议(ICCNE 2024)将于7月26-28日在越南岘港召开。本次会议由维新大学主办,岘港大学、胡志明市科技大学协办。ICCNE 2024旨在为来自行业和学术界的研究人员、从业者和专业人士提供论坛,分享其最新研…

vid2vid(Video-to-Video Synthesis)论文详读和理解

论文:https://arxiv.org/abs/1808.06601 代码:https://github.com/NVIDIA/vid2vid

Linux系统部署Swagger Editor结合内网穿透实现公网管理本地接口文档

文章目录 Swagger Editor本地接口文档公网远程访问1. 部署Swagger Editor2. Linux安装Cpolar3. 配置Swagger Editor公网地址4. 远程访问Swagger Editor5. 固定Swagger Editor公网地址 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站&#xf…

Win7安装 .NET Framework 4.6.2 产生阻滞的问题

如图: 解决方案:安装补丁 windows6.1-KB976932-X64 补丁下载地址: 链接:https://pan.baidu.com/s/1_pIflWRKriAheAweJVkXFQ 提取码:6a1q

如何在Linux部署Docker Registry本地镜像仓库并实现无公网IP远程连接

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…

HTML静态网页成品作业(HTML+CSS)——电影加勒比海盗介绍设计制作(1个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…

供应IMX290LQR-C芯片现货

长期供应各品牌芯片现货,SONY索尼SONY索尼CMOS/CCD芯片全系列全新现货优势出: IMX225LQR-C IMX415-AAQR-C IMX290LQR-C imx273llr-C IMX397CLN-C IMX637-AAMJ-C IMX647-AAMJ-C IMX991-A***-C IMX991-AABJ-C IMX287LLR-C IMX287LQR-C IMX297L…

【李沐论文精读】CLIP改进工作串讲精读

参考:CLIP改进工作串讲(上)、CLIP改进工作串讲(下)、李沐精读系列、CLIP 改进工作串讲(上)笔记 由于是论文串讲,所以每个链接放在每一个小节里。 CLIP的应用如下: 回顾&a…

mineadmin 快速安装部署(docker环境)

前提条件:已安装docker 一、下载dnmp环境包 github地址:https://github.com/tomorrow-sky/dnmp gitee地址: https://gitee.com/chenjianchuan/dnmp 二、看一下dnmp包目录结构 三、打开docker-compose.yml 文件,将不需要…

使用Python批量实现在Excel里新加一列

目录 一、引言 二、所需库介绍 三、代码实现 四、批量处理多个Excel文件 五、注意事项与扩展 六、案例演示 七、总结与展望 一、引言 Excel作为广泛使用的电子表格软件,在数据处理和分析中扮演着重要角色。然而,当面对大量Excel文件需要批量处理…

傅立叶之美:深入研究傅里叶分析背后的原理和数学

一、说明 T傅里叶级数及其伴随的推导是数学在现实世界中最迷人的应用之一。我一直主张通过理解数学来理解我们周围的世界。从使用线性代数设计神经网络,从混沌理论理解太阳系,到弦理论理解宇宙的基本组成部分,数学无处不在。 当然&#xff0c…

seaborn去除图例的小标题

import seaborn as sns g sns.lineplot(x"myXs", y"myYs", hue"myHue", datamydf) g.legend_.set_title(None)效果: 图例的小方框里就没有小标题了。

豆瓣书影音存入Notion

使用Python将图书和影视数据存放入Notion中。 🖼️介绍 环境 Python 3.10 (建议 3.11 及以上)Pycharm / Vs Code / Vs Code Studio 项目结构 │ .env │ main.py - 主函数、执行程序 │ new_book.txt - 上一次更新书籍 │ new_video.…

4G安卓核心板T310_紫光展锐平台方案

紫光展锐T310应用 DynamlQ架构 12nm 制程工艺,采用 1*Cortex-A753*Cortex-A55处理器,搭载Android11.0操作系统,主频最高达2.0GHz.此外,DynamlQ融入了AI神经网络技术,新增机器学习指令,让其在运算方面的机器…

华为OD机试C卷“跳步-数组”Java解答

描述 示例 算法思路1 不断移动数组将元素删去(并未彻底删除,而是将数字元素前移实现“伪删除”)这样删除元素的位置就呈现一定规律,详细见下图(潦草的画) 答案1 import java.util.*;public class Main {…