python实战(四)——RAG预热实践

一、任务目标

        为了清晰直观地展示RAG(检索增强生成)方法的有效性,我们手搓一套RAG的流程进行演示,作为后续LangChain等技术的预热。本文编程实践的目的是展示RAG的工作原理及流程(科普为主),不过多关注技术实现的效果和效率,因此如果是奔着代码拿来即用的目的阅读本文的话,那可能不会有什么大的收获。

二、常规的大模型问答

        这里直接给出本文的示例Query:

“请告诉我,花花是一个怎么样的人”

        下面,调用gpt-3.5-turbo大模型回答这个问题。我们使用openai的大模型接口,在这个过程中需要用到你个人的api_key等信息:

import openai

# 可以去openai官网或者国内某些镜像网站注册一个
openai.api_key = "你的api key"
openai.api_base = "你的api base"
query = '请告诉我,花花是一个怎么样的人'
chat_completion = openai.ChatCompletion.create(
                model="gpt-3.5-turbo",
                messages=[{"role": "user", "content": query}]
            )
response = chat_completion.choices[0].message.content
print(response)

        下面是大模型的回答,很明显,大模型也没办法在没有任何背景知识的情况下回答这个问题:

三、基于RAG的大模型问答

1、知识库构建

        首先,我们需要有一个存储着各类信息的知识库,里面需要有花花相关的内容。有了基本的知识储备,才能够正确回答问题。这里给出一个简单的知识库示例,其中包含了磊磊、花花、明明三个人各自性格、特长等信息:

dataBase = [
"磊磊是一个充满活力的北京小伙子,性格外向,总是人群中的焦点。他对生活充满了热情,喜欢与人交流,总是能够轻松地与陌生人打成一片。磊磊的运动爱好广泛,尤其擅长篮球和游泳,他经常参加各种体育活动,不仅锻炼了身体,也结交了许多志同道合的朋友。",
"磊磊的特长之一是公共演讲,无论是在学校的辩论赛还是公司的年会上,磊磊总能用他那富有感染力的言辞吸引听众的注意。此外,磊磊还对摄影有着浓厚的兴趣,喜欢捕捉生活中的美好瞬间,他的社交媒体上充满了他拍摄的风景和人物照片。",
"在人际交往方面,磊磊有着广泛的社交圈,他善于倾听,乐于助人,这使得他在朋友中非常受欢迎。磊磊总是能够用他的幽默感和积极态度为周围的人带来正能量。尽管磊磊的朋友众多,但磊磊也非常重视与家人的关系,经常抽时间陪伴家人,享受家庭的温暖。",
"花花是一个温柔而细腻的女孩,她的性格内向,喜欢安静和独处。花花来自江南的一个小镇,那里的宁静和美丽深深地影响了她的性格和审美。花花的爱好是绘画和写作,她喜欢用画笔捕捉自然的美丽,用文字记录内心的感受。",
"花花在社交场合可能显得有些害羞和保守,但她的真诚和善良总能赢得他人的尊重和喜爱。她更倾向于深度交流而非表面的寒暄,这使得她的友谊往往更加长久和稳固。在业余时间,花花喜欢阅读和研究心理学,这不仅帮助她更好地理解自己,也让她在与人交往时更加敏感和体贴。尽管她不常成为聚会的中心,但花花的存在总能为周围的人带来一份宁静和安慰。",
"明明,一个性格外向的年轻人,总是带着阳光般的笑容,他的热情和活力很容易感染周围的人。他出生在繁华的上海,这个城市的快节奏和多元文化塑造了他开朗和包容的性格。",
"明明的爱好多种多样,他特别喜欢户外运动,如徒步旅行和自行车骑行,这些活动不仅让他保持了健康的体魄,也让他有机会结识来自不同背景的朋友。明明还是各种社交活动的常客,无论是公司的团队建设还是朋友间的聚会,他总能成为调动气氛的关键人物。",
"在工作之余,明明也热衷于公益事业,他经常参与志愿者活动,帮助那些需要帮助的人。明明的这种乐于助人的精神,让他在社区中也赢得了良好的声誉。"
]

2、知识检索

        我们的示例知识库规模很小,但是实际业务过程中,数据的规模可能非常大,我们不可能把整个知识库同时作为prompt输入给大模型。那一个基本的方案就是去检索跟Query相关的知识来辅助大模型理解,例如我们可以通过计算余弦相似度的方式来选择跟Query最相似的Top N条知识,然后合并这些知识到Prompt中。

        由于我们这是一个简易版RAG,秉着简易的原则,我们在这里使用Word2Vec进行文本的向量化。这里,Word2Vec模型的训练语料就是dataBase,完成训练之后直接对dataBase中的每一句话进行向量化(Word2Vec句向量由所有词向量按位取平均所得)。

from gensim.models import Word2Vec
import numpy as np
import jieba


texts_cut = [list(jieba.cut(text)) for text in dataBase]
model = Word2Vec(sentences=texts_cut, vector_size=100, window=10, min_count=1, sg=1, epochs=100)
sentence_vectors = []
for sentence in texts_cut:
    vector = np.mean([model.wv[word] for word in sentence if word in model.wv], axis=0)
    sentence_vectors.append(vector)

        现在,我们已经实现了知识库的向量化,接下来就是检索Query与知识库中的每一条知识的相似度了。这里我们直接使用Word2Vec对Query进行向量化,并比对Query向量和知识向量表示的相似度,由于数据量不大,这里直接使用for循环。

from scipy.spatial import distance


query_emb = np.mean([model.wv[word] for word in list(jieba.cut('请告诉我,花花是一个怎么样的人')) if word in model.wv], axis=0)
most_relative = -1
max_sims = -1
for idx, vec in enumerate(sentence_vectors):
    cosine_similarity = 1 - distance.cosine(query_emb, vec)
    print("向量ID:{}, 余弦相似度:{}".format(idx, cosine_similarity))
    if cosine_similarity>max_sims:
        max_sims = cosine_similarity
        most_relative = idx

      结果如下:

        由于知识库数据量太小,这里我们只选择Top 1最相关的知识。可以看到,最相似的为ID为3的知识表示,对应文本为:

        “花花是一个温柔而细腻的女孩,她的性格内向,喜欢安静和独处。花花来自江南的一个小镇,那里的宁静和美丽深深地影响了她的性格和审美。花花的爱好是绘画和写作,她喜欢用画笔捕捉自然的美丽,用文字记录内心的感受。”

3、大模型问答

        我们把上述文本加入到prompt中并让大模型回答我们的问题:

query = '请告诉我,花花是一个怎么样的人。'
prompt = f"以下是一些相关的可用信息:{dataBase[most_relative]}"
chat_completion = openai.ChatCompletion.create(
                model="gpt-3.5-turbo",
                messages=[{"role": "user", "content": query+prompt}]
            )
response = chat_completion.choices[0].message.content
print(response)

        结果如下,是否优雅了许多?

四、完整代码

import openai
from gensim.models import Word2Vec
import numpy as np
import jieba
from scipy.spatial import distance

# api配置
openai.api_key = "你的api key"
openai.api_base = "你的api base"

dataBase = [
"磊磊是一个充满活力的北京小伙子,性格外向,总是人群中的焦点。他对生活充满了热情,喜欢与人交流,总是能够轻松地与陌生人打成一片。磊磊的运动爱好广泛,尤其擅长篮球和游泳,他经常参加各种体育活动,不仅锻炼了身体,也结交了许多志同道合的朋友。",
"磊磊的特长之一是公共演讲,无论是在学校的辩论赛还是公司的年会上,磊磊总能用他那富有感染力的言辞吸引听众的注意。此外,磊磊还对摄影有着浓厚的兴趣,喜欢捕捉生活中的美好瞬间,他的社交媒体上充满了他拍摄的风景和人物照片。",
"在人际交往方面,磊磊有着广泛的社交圈,他善于倾听,乐于助人,这使得他在朋友中非常受欢迎。磊磊总是能够用他的幽默感和积极态度为周围的人带来正能量。尽管磊磊的朋友众多,但磊磊也非常重视与家人的关系,经常抽时间陪伴家人,享受家庭的温暖。",
"花花是一个温柔而细腻的女孩,她的性格内向,喜欢安静和独处。花花来自江南的一个小镇,那里的宁静和美丽深深地影响了她的性格和审美。花花的爱好是绘画和写作,她喜欢用画笔捕捉自然的美丽,用文字记录内心的感受。",
"花花在社交场合可能显得有些害羞和保守,但她的真诚和善良总能赢得他人的尊重和喜爱。她更倾向于深度交流而非表面的寒暄,这使得她的友谊往往更加长久和稳固。在业余时间,花花喜欢阅读和研究心理学,这不仅帮助她更好地理解自己,也让她在与人交往时更加敏感和体贴。尽管她不常成为聚会的中心,但花花的存在总能为周围的人带来一份宁静和安慰。",
"明明,一个性格外向的年轻人,总是带着阳光般的笑容,他的热情和活力很容易感染周围的人。他出生在繁华的上海,这个城市的快节奏和多元文化塑造了他开朗和包容的性格。",
"明明的爱好多种多样,他特别喜欢户外运动,如徒步旅行和自行车骑行,这些活动不仅让他保持了健康的体魄,也让他有机会结识来自不同背景的朋友。明明还是各种社交活动的常客,无论是公司的团队建设还是朋友间的聚会,他总能成为调动气氛的关键人物。",
"在工作之余,明明也热衷于公益事业,他经常参与志愿者活动,帮助那些需要帮助的人。明明的这种乐于助人的精神,让他在社区中也赢得了良好的声誉。"
]

# 知识库文本向量化
texts_cut = [list(jieba.cut(text)) for text in dataBase]
model = Word2Vec(sentences=texts_cut, vector_size=100, window=10, min_count=1, sg=1, epochs=100)
sentence_vectors = []
for sentence in texts_cut:
    vector = np.mean([model.wv[word] for word in sentence if word in model.wv], axis=0)
    sentence_vectors.append(vector)
print(sentence_vectors)

# query
query = '请告诉我,花花是一个怎么样的人。'

# 余弦相似度匹配/知识检索
query_emb = np.mean([model.wv[word] for word in list(jieba.cut(query)) if word in model.wv], axis=0)
most_relative = -1
max_sims = -1
for idx, vec in enumerate(sentence_vectors):
    cosine_similarity = 1 - distance.cosine(query_emb, vec)
    print("向量ID:{}, 余弦相似度:{}".format(idx, cosine_similarity))
    if cosine_similarity>max_sims:
        max_sims = cosine_similarity
        most_relative = idx

# 结合知识库知识的大模型问答
prompt = f"以下是一些相关的可用信息:{dataBase[most_relative]}"
chat_completion = openai.ChatCompletion.create(
                model="gpt-3.5-turbo",
                messages=[{"role": "user", "content": query+prompt}]
            )
response = chat_completion.choices[0].message.content
print(response)

五、总结

        本文使用极其简单的流程实现了一个简易版RAG。可见,结合RAG技术,大模型能够轻松回答原先无法回答的一些需要知识背景的问题。RAG的概念非常简单,但是它对于提升大模型的表现却非常有效。本文只是进行了一个科普性质的讲解,后续将会详细介绍RAG技术的实现。毕竟,实际业务知识库的规模可能达到了大数据的量级,因此必然无法直接逐条知识和Query比较相似度,这使得我们需要进行一些必要的检索优化;另外,将知识文本添加到Prompt中的方式也较为原始,实际上有更加高效的知识应用策略;最后,RAG的链路也早就有诸如LangChain等开源解决方案帮助我们进行开发了,无需人工重复造轮子。

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

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

相关文章

pycharm与anaconda下的pyside6的安装记录

一、打开anaconda虚拟环境的命令行窗口,pip install,加入清华源: pip install PySide6 -i https://pypi.tuna.tsinghua.edu.cn/simple 二、打开pycharm,在文件--设置--工具--外部工具中配置一下三项: 1、 QtDesigner…

MATLAB实现人类学习优化算法HLO

1.算法简介 人类学习优化算法(Human Learning-based Optimization,HLO)是一种基于人类学习过程开发的启发式算法。HLO算法的设计灵感来源于人类的智慧和经验,特别是人类在学习和调整过程中展现出的适应性、学习能力和创新思维。该…

ubuntu openmpi安装(超简单)

openmpi安装 apt update apt install openmpi-bin openmpi-common libopenmpi-dev安装到此完毕 测试一下,success !

车位识别系统项目设计

车位识别系统需求分析 1.概述 1.1问题描述 随着车辆保有量的不断增长,对车位中是否停有车辆进行检测的车位检测装置的需求不断增加。为了改善停车体验,建设停车引导系统非 常必要。而停车引导系统的核心,是需要检测哪些车位被占用,哪些空闲。 室内停车场因为施工…

2 columns passed, passed data had 4 columns

文章目录 一、问题复现二、原因分析 在使用Pandas等数据处理库时,我们经常需要将数据赋值给DataFrame。然而,有时候我们可能会遇到ValueError: 2 columns passed, passed data had 4 columns这个错误。这个错误表明你在构建一个 Pandas DataFrame 时&…

深度学习中one-hot 编码的正确理解

one-hot编码 是一种表示类别标签的方法。对于一个分类问题(例如图像分割中的类别标签),one-hot编码会将一个类别标记转换为一个向量,这个向量中只有一个位置为1,其余位置为0。划重点:一个one hot 编码可以理…

vscode和pycharm在当前工作目录的不同|python获取当前文件目录和当前工作目录

问题背景 相信大家都遇到过一个问题:一个项目在vscode(或pycharm)明明可以正常运行,但当在pycharm(或vscode)中时,却经常会出现路径错误。起初,对于这个问题,我也是一知…

《操作系统真象还原》第3章 完善MBR【3.1 — 3.2】

目录 引用与说明 3.1、地址、section、vstart 浅尝辄止 1、什么是地址 2、什么是 section【汇编】 3、什么是 vstart【汇编】 3.2、CPU 的实模式 1、CPU 工作原理【重要】 2、实模式下的寄存器 4、实模式下 CPU 内存寻址方式 5、栈到底是什么玩意儿 6 ~ 8 无条件转移…

tiktok双旋转验证码识别,利用图像处理技术准确率达97

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为 如有侵犯,请联系作者下架 该文章模型已经上线ocr识别网站,欢迎测试!!,地址:https://yxlocr.windy-rain.cn/ocr/othe…

TVM前端研究--Relay

文章目录 深度学习IR梳理1. IR属性2. DL前端发展3. DL编译器4. DL编程语言Relay的主要内容一、Expression in Relay1. Dataflow and Control Fragments2. 变量3. 函数3.1 闭包3.2 多态和类型关系3.3. Call4. 算子5. ADT Constructors6. Moudle和Global Function7. 常量和元组8.…

angular使用http实现get和post请求

说明: angular使用http实现get和post请求 提示:在运行本项目前,请先导入路由router,可以参考我上一篇文章。 效果图: step1:E:\projectgood\ajsix\untitled4\package.json “angular/cdk”: “^18.2.10”, “angula…

虚拟现实辅助工程技术助力航空航天高端制造业破局

在当今竞争激烈的航天产业环境中,高昂的研发成本、复杂的制造流程、繁重的维护任务以及对关键太空资产需求的不断升级,是航空航天高端制造业亟待破解的困境。在此背景下,虚拟现实辅助工程技术正以前所未有的速度渗透至各行各业,成…

LySocket 远程ShellCode注入工具

一款基于C/C开发的远程ShellCode注入工具,通常配合Metasploit一起使用,可实现远程注入反弹代码到指定进程,它由服务端和客户端两部分组成,并使用最少的代码实现了多Socket套接字管理机制,目前主要功能包括,…

【JVM第2课】类加载子系统(类加载器、双亲委派)

类加载系统加载类时分为三个步骤,加载、链接、初始化,下面展开介绍。 文章目录 1 类加载器1.1 引导类加载器(BootStrapClassLoader)1.2 拓展类加载器(ExtClassLoader)1.3 应用类加载器(AppClas…

进一步认识ICMP协议

在日常工作中,我们经常需要判断网络是否连通,相信大家使用较多的命令就是 ping啦。ping命令是基于 ICMP 协议来实现的,那么什么是 ICMP 协议呢?ping命令又是如何基于 ICMP 实现的呢? 今天这篇文章,我们就来…

计算机网络-MSTP的基础概念

前面我们大致了解了MSTP的由来,是为了解决STP/RSTP只有一根生成树导致的VLAN流量负载分担与次优路径问题,了解MSTP采用实例映射VLAN的方式实现多实例生成树,MSTP有很多的理论概念需要知道,其实与其它的知识一样理论复杂配置还好的…

宠物空气净化器哪个牌子好?有没有噪音低的宠物空气净化器推荐?

如今随着社会竞争越来越激烈,不少人开始焦虑内耗,但为了能更好的生活,养宠物便成为不少人的排忧解乏的方法。 我也不例外,作为一名996社畜,天刚亮就出门,天黑很久才回家,所以选择养猫来陪我度过…

Linux shell编程学习笔记87:blkid命令——获取块设备信息

0 引言 在进行系统安全检测时,我们需要收集块设备的信息,这些可以通过blkid命令来获取。 1 blkid命令的安装 blkid命令是基于libblkid库的命令行工具,可以在大多数Linux发行版中使用。 如果你的Linux系统中没有安装blkid命令,…

华为手机卸载系统应用的方法

摘要: 1.手机环境:手机需要开启开发者模式并使用usb连接电脑,并选择文件传输模式 2.电脑环境:使用鸿蒙工具箱进行傻瓜操作或安装adb工具进行命令卸载 3.鸿蒙工具箱和adb工具本质都是使用adb shell pm uninstall -k --user 0 xx…

聊聊我在新加坡的近况

我是 2022 年 4 月初过来新加坡的,然后两个月后就把老婆孩子们也接了过来。时至今日,已经两年半有余了。 22 年 8 月初的时候,写过一篇文章「聊聊我在新加坡的生活和工作体验」,没想到成了一篇热门文章,在知乎上不知不…