预热

RAG系统比较官方的定义如下:

‌RAG‌(Retrieval-Augmented Generation,检索增强生成)是一种结合‌信息检索‌与‌大语言模型生成能力‌的技术框架,旨在提升大模型在回答问题、生成内容时的‌准确性、可解释性和实时性‌。

这听起来不像人话,说人话定义RAG系统是在一般语言大模型的基础上增加了信息检索能力,这样大模型在回答你问题之前会去先检索相关信息,基于相关信息再回答问题,这种方式能在一定程度上消除幻觉。

废话少说开始手搓代码

因为涉及到大预言模型,所以语言咱们还是选择python语言,而且python语言有很多可以调用的库,都是非常强大的工具,同时这些年随着python语言的迭代,这种语言多了越来越多方便的花式写法。由于是刚开始的代码,所以今天简单点,先做一个最基础的东西,能调用大模型先回答一个简单的问题就好,这一步很重要,因为后面所有的工作,都是基于大模型问答的,所以今天的目标是用代码让大模型回答问题就好。

语言模型还是选择Openai 这里其实也可以用一些国产模型或者其他模型,但是有意思的是现在基本上所有模型都能兼容openai,什么意思,意思是如果你用了openai的基座,现在市面上所有的模型你都能直接拿来用,只需要改一下api_key和base_url就行。

from openai import OpenAI

client = OpenAI(
    api_key="",
    base_url="https://api.deepseek.com" #这里也可以使用其他的语言模型
)

有了大模型,就需要准备咱们的问题和文本内容了。

context = "Transformer 是一种用于处理序列数据的模型结构,广泛应用于自然语言处理任务。"

question = "Transformer是干嘛的?"

有了问题和文本内容后就可以开始调用大模型了,具体调用方式参考官方文档即可,可能随着版本更新调用方式发生变化,但是原理大差不大:

response = client.chat.completions.create(
    model="deepseek-chat",
    messages=[
        {"role": "system", "content": "你是一个擅长解释论文的助手"},
        {"role": "user", "content": context + "\n\n问题:" + question}
    ]
)

print(response.choices[0].message.content)

RAG原理解读

RAG系统听起来很复杂,但是底层原理一旦解读将会非常简单,下面我们来说说RAG的底层原理和逻辑。

RAG检索基于的核心是相关领域知识检索,简单来说:当用户问到一个问题后,RAG系统会到知识数据库中去检索与该问题相关的知识,然后基于找到的知识回答用户的问题。整个原理如上所说,实现过程中将会利用到一个绕不开的过程,那就是Embedding嵌入,说到了Embedding嵌入就要稍微展开一下了,因为这涉及到机器理解我们世界的文本。

Ai中数据的本质

我们的有语言文字、图片、视频以及声音,但是这些东西是我们能感觉到的,但是机器不一样, 计算机的世界只有0/1代码以及其能表示的一堆数据,那么问题来了,如何让计算机也能感受到和我们一样世界呢,准确说如何让计算机也理解我们的世界呢?这就涉及到计算机中的数据表示了。

其实很好理解,相信很多人也都知道在计算机中图片数据本质上就是三个矩阵,一张彩色的图片在计算机的世界中是三个矩阵,也就是表示红、绿、蓝三色光的矩阵,当三色光矩阵的数据在现实器同时输出,你也就看到一张彩色的图片。

同样的,在计算机中英文数据由美国上个世纪提出的ASCII码表示,但是我们学过计算机的人都知道ASCII码只能表示英文,后面为了表示中文编码集又扩展Unicode、UTF-8等编码,今天中文在计算机中的表示或者更准确说在机器学习中的表示又One-hot独热编码和基于深度学习的表示,其中基于深度学习的表示涉及到文本嵌入,后面会详细展开,但是要知道One-hot表示相对来说会占据更多的内存,但是基于深度学习的特征表示即嵌入embedding方法,占用的空间会下降一些。

为什么要用Embedding

嵌入的好处很多,首先一点是可以将一个高纬数据映射到低纬空间,另外一点是可以增加一些数据的可解释性和推理能力,例如:
king−man+woman=queen king - man + woman = queen kingman+woman=queen
此外,我个人理解嵌入还有一些好处,将平时我们所见的数据嵌入到一个高纬的数据空间,那么数据将会具备一些低纬空间不具备的特点和特性,这样利用这些特点和特性可以很好的解决一些低位空间很难判断的问题。最典型的就是啤酒和尿不湿的案例,两类看似不相干的东西,但是在数据特点上存在某种正相关的关系,人们利用这点将啤酒和尿不湿的货架放在一起可以提高销量。

地基代码

刚刚说到RAG的技术原理是基于知识检索的,这些知识是将网络上大量的长文本切碎成小碎片存储的,那么今天先实现一个简单的将知识切碎存储,并手动选择一个知识回答问题的系统,后面将会进行优化,在优化中将会实现自动筛选有效知识。

from openai import OpenAI 

client = OpenAI(
    api_key="",
    base_url="https://api.deepseek.com"
)


def split_text(text,chunk_size=100):   #用于切分知识的函数
	chunks=[]
	for i in range(0,len(text),chunk_size):
		chunks.append(text[i:i+chunk_size])
	return chunks

#假设text是知识
text = "隐写分析(steganalysis)是指针对隐写术的检测与破解技术,旨在通过分析数字载体的统计特性,判断其中是否存在隐蔽信息,并在可能的情况下进一步提取或破解隐秘内容。作为信息安全监管的重要手段,隐写分析的核心在于破坏隐秘通信的隐蔽性,实现对潜在威胁的感知与阻断。从技术路径上,隐写分析可分为被动分析与主动分析两类:前者仅判断载体中是否包含秘密信息,后者则进一步尝试恢复嵌入内容或推断隐写算法参数。检测对象覆盖图像、音频、视频等多模态载体,分析方法经历了从早期基于统计特征(如均值、直方图、高阶统计量)的检测,到利用离散余弦变换(DCT)、离散小波变换(DWT)等频域变换检测块效应与嵌入痕迹,再到当前以卷积神经网络(CNN)为代表的深度学习模型自动提取高维语义特征的发展历程。评估检测性能的关键指标包括真阳性率与假阳性率等。隐写分析的概念于1998年由Neil F. Johnson等学者在国际信息隐藏会议上正式提出,早期研究以统计检测方法为主,近年来研究重心逐步转向特征表达优化与分类器设计,并开始探索面向生成式隐写等新兴技术的通用分析框架,以适应隐蔽通信技术不断演进的对抗需求。"

chunks = split_text(text) #chunks是切碎的知识

selected_chunk = chunks[0] #先手动选一个相关知识,假设已经切碎的知识第一条是相关知识,后面会做自动化处理

question = "这段的核心思想是什么?" #这是你问大模型的问题,然后他会去找相关知识回答。

response =client.chat.completions.create(
			model='deepseek-chat',
			messages=[
				{"role":"system","content":"你是一个擅长解释论文的助手"},
				{"role":"user","content":selected_chunk+"\n\n问题:"+question}
			]
)
print(response.choices[0].message.content)
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐