【大语言模型系列】不到两百行代码教你实现一个完整的RAG系统(案例+源码)

python实战(七)——基于LangChain的RAG实践 本文详细介绍了使用LangChain构建RAG程序的各个流程,并给出了对应的python实现代码。 阅读详情

一、引言

- 检索增强生成(Retrieval-Augmented Generation,RAG)
- RAG借助外挂的知识库来为大语言模型提供准确和最新的知识,以提升大语言模型生成内容的质量,减少错误内容的产生。RAG允许对新增数据部分使用相同的模型处理,而无需调整及微调模型,从而极大地拓展了大模型的可用性。
- RAG提供了一个有效的方式来解决在特定领域的问答,主要将行业知识转化为向量进行存储和检索,通过知识检索的结果与用户问题结合形成Prompt,最后利用大模型生成合适的回答。

- 实现原理

​ - 加载本地文档 -> 文本分割 -> 文本向量化 -> question向量化 -> 在文本向量中匹配出与问句向量最相似的 top k个 -> 匹配出的文本作为上下文和问题一起添加到 prompt中 -> 提交给 LLM生成回答

二、实现过程

2.1 文档加载

创建一个PyMuPDFLoader实例,输入为待加载的pdf文档路径:

loader = PyMuPDFLoader("../../data_base/knowledge_db/pumkin_book/pumpkin_book.pdf")

调用PyMuPDFLoader实例的load方法加载整个文档:

pages = loader.load()
print(f'载入后的变量类型为:{type(pages)},', f"该PDF一共包含{len(pages)}页")

结果:

img

可见pages是一个列表,列表的长度就是pdf文档的页数。我们看一下第一个元素:

page = pages[1]
print(f"每个元素的类型为:{type(page)}",
      f"该文档的描述性数据:{page.metadata}",
      f"查看该文档的内容:\n{page.page_content}",
      sep="\n--------\n")

列表每个元素的类型是一个langchain.schema.document.Document。第一页的描述性数据和文档内容如下:

img

2.2 文档分割

声明一个RecursiveCharacterTextSplitter实例:

# 知识库中单段文本长度
CHUNK_SISE = 500
# 知识库中相似文本重合长度
OVERLAP_SIZE = 50
# 声明一个RecursiveCharacterTextSplitter实例
text_splitter = RecursiveCharacterTextSplitter(chunk_size=CHUNK_SISE, chunk_overlap=OVERLAP_SIZE)

对整个文档pages进行分割:

split_docs = text_splitter.split_documents(pages)
print(split_docs)   # 是一个列表
print(f"分割后的块数:{len(split_docs)}")
print(f"分割后的字符数(可以用来大致评估token数):{sum([len(doc.page_content) for doc in split_docs])}")

split_docs是一个列表,每一个元素式分割后的一小块:

img

这个文档总共被分割为737块,分割后的总字符数为314699。

img

2.3 文档词向量化

对词进行向量化,需要选择一个embeddings模型,这里我们采用HuggingFaceEmbeddings,我们拿两个词来看看如何向量化的,向量化的形式是咋样的:

# 定义Embeddings
embedding = HuggingFaceEmbeddings(model_name="moka-ai/m3e-base")
query1 = '机器学习'
query2 = '强化学习'
emb1 = embedding.embed_query(query1)
emb2 = embedding.embed_query(query2)
print(emb1)
print(emb2)
# 计算两个词向量的相关性
import numpy as np
emb1 = np.array(emb1)
emb2 = np.array(emb2)
print(f"{query1}和{query2}向量之间的点积为:{np.dot(emb1, emb2)}")

query1和query2经过embedding分别变为emb1和emb2,变成了一个向量(数组),通过计算向量之间的点积可以判断query1和query2的相关性:

img

2.4 构建向量数据库

现在我们对分割后的文档(文本块)进行向量化,并写入保存到向量数据库中:

persist_directory = "../../data_base/vector_db/chroma"
# vectordb = Chroma.from_documents(
#       documents=split_docs[:100],
#       embedding=embedding,
#       persist_directory=persist_directory)
#
# vectordb.persist() # 持久化向量数据库

这里,我们只取了前100个文本块进行向量化存储,如果之前已经构建过向量数据库,则可以直接加载:

# 直接加载已经构建好的向量数据库
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embedding)
# 查看向量数据库的存储的数量
print(f"存储向量的数量:{vectordb._collection.count()}")

结果:这里我们只对前100个文本块进行向量化,因此存储的向量的数量是100。

img

2.5 通过向量数据库检索

接下来,我们就可以通过一个prompt,去到向量数据库中检索与之最相关的n条内容:

question = "什么是机器学习?"
sim_docs = vectordb.similarity_search(question, k=3)
print(f"检索到的内容数:{len(sim_docs)}")
for i, sim_doc in enumerate(sim_docs):
      print(f"检索到第{i}个内容:\n{sim_doc.page_content[:200]}", end="\n----------\n")

这里我的问题是“什么是机器学习?”,去检索向量数据库中与之相近的内容:

img

img

img

2.6 定义大模型

需要创建一个大模型对象,如果我们本地部署了大模型,可以直接调用本地的大语言模型,或者采用api的方式进行调用:

# # 使用huggingfacepipeline本地搭建大语言模型
# model_id = "THUDM/chatglm2-6b-int4"
# tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
# model = AutoModel.from_pretrained(model_id, trust_remote_code=True).half().quantize(4).cuda()
# model = model.eval()
# pipe = pipeline('text2text-generation', model, tokenizer, maxlength=100)
# llm = HuggingFacePipeline(pipeline=pipe)


# 使用OpenAI的大语言模型
# 获取环境变量 OPENAI_API_KEY
# _ = load_dotenv(find_dotenv()) # read local .env fileopenai.api_key  = os.environ['OPENAI_API_KEY']
# openai.api_key = os.environ['OPENAI_API_KEY']
# llm = OpenAI(model_name="gpt-4", temperature=0)


# 使用智谱AI的大模型
_ = load_dotenv(find_dotenv()) # read local .env fileopenai.api_key  = os.environ['OPENAI_API_KEY']
zhipuai.api_key = os.environ['ZHIPUAI_API_KEY']
llm = ZhipuAILLM(model="chatglm_std", temperature=0)

2.7 构造检索式问答链

首先声明一个检索问答链:

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=vectordb.as_retriever())

进行问答:

question = '机器学习是什么'
result = qa_chain({"query": question})
print(f'大语言模型的回答为:{result["result"]}')

大语言模型的回答为:机器学习是一门研究如何让计算机通过数据学习、提高性能的科学。它涉及到许多领域,如统计学、计算机科学、人工智能等。机器学习的目标是开发新的算法和模型,使计算机能够在没有明确编程的情况下,根据数据自动识别模式、进行预测和决策。

img

结合prompt声明一个检索式问答链:

# 建立一个prompt模板
template = """使用以下上下文片段来回答最后的问题。如果你不知道答案,只需说不知道,不要试图编造答案,答案最多使用三个句子。尽量简明扼要地回答。在回答的最后一定要说"感谢您的提问"{context}问题:{question}有用的回答:"""
QA_CHAIN_PROMPT = PromptTemplate.from_template(template)
qa_chain = RetrievalQA.from_chain_type(
    llm,
    retriever=vectordb.as_retriever(),
    return_source_documents=True,
    chain_type_kwargs={"prompt": QA_CHAIN_PROMPT}
)

进行问答:

question = '2025年大语言模型最好的是哪个模型?'
result = qa_chain({"query": question})
print(f'大语言模型的回答为:{result["result"]}')

大语言模型的回答为:您提到的章节和内容似乎是关于机器学习的不同主题和方法。然而,关于2025年大语言模型的最佳模型,由于我是一个AI助手,无法预测未来的具体情况。在2025年,可能会有许多新的模型和技术出现,而最佳模型将取决于许多因素,如准确性、性能、适应性和可用性。因此,很难确定哪个模型将是最好的。感谢您的提问。

img

2.8 构造对话检索链

声明一个对话检索链需要先声明一个记忆对象,然后将这个对象传入到这个链中:

# 声明一个记忆对象
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

# 声明一个对话检索链
from langchain.chains import ConversationalRetrievalChain
qa = ConversationalRetrievalChain.from_llm(
    llm=llm,
    retriever=vectordb.as_retriever(),
    memory=memory
)

提出一个无历史对话的问题,并查看回答:

question = "我可以学习到关于强化学习的知识嘛?"
result = qa({"question": question})
print(f'大语言模型的回答为:{result["answer"]}')

大语言模型的回答为:是的,你可以从南瓜书中学习到关于强化学习的知识。南瓜书是对西瓜书《机器学习》的补充,提供了更详细的公式推导和解析。在第16章,它涵盖了强化学习的相关内容,如任务与奖赏等。你可以在学习强化学习时,结合南瓜书进行查阅和理解。

img

基于答案进行下一个问题,并查看回答:

question = "为什么要学习这方面的知识?"
result = qa({'question': question})
print(f'大语言模型的回答为:{result["answer"]}')

img

大语言模型的回答为:强化学习是一种人工智能的算法,它可以帮助计算机代理在特定环境中根据其行为获得奖励或惩罚,从而学习如何做出最优的决策。学习强化学习的知识可以帮助我们更好地理解这种算法的工作原理,以及如何应用它来解决实际问题。强化学习在很多领域都有应用,比如自动驾驶、游戏控制、推荐系统等,因此学习强化学习的知识对于人工智能的发展和应用具有重要意义。

​

如何学习大模型

现在社会上大模型越来越普及了,已经有很多人都想往这里面扎,但是却找不到适合的方法去学习。

作为一名资深码农,初入大模型时也吃了很多亏,踩了无数坑。现在我想把我的经验和知识分享给你们,帮助你们学习AI大模型,能够解决你们学习中的困难。

下面这些都是我当初辛苦整理和花钱购买的资料,现在我已将重要的AI大模型资料包括市面上AI大模型各大白皮书、AGI大模型系统学习路线、AI大模型视频教程、实战学习,等录播视频免费分享出来,需要的小伙伴可以扫取。

一、AGI大模型系统学习路线

很多人学习大模型的时候没有方向,东学一点西学一点,像只无头苍蝇乱撞,我下面分享的这个学习路线希望能够帮助到你们学习AI大模型。

在这里插入图片描述

二、AI大模型视频教程

在这里插入图片描述

三、AI大模型各大学习书籍

在这里插入图片描述

四、AI大模型各大场景实战案例

在这里插入图片描述

五、结束语

学习AI大模型是当前科技发展的趋势,它不仅能够为我们提供更多的机会和挑战,还能够让我们更好地理解和应用人工智能技术。通过学习AI大模型,我们可以深入了解深度学习、神经网络等核心概念,并将其应用于自然语言处理、计算机视觉、语音识别等领域。同时,掌握AI大模型还能够为我们的职业发展增添竞争力,成为未来技术领域的领导者。

再者,学习AI大模型也能为我们自己创造更多的价值,提供更多的岗位以及副业创收,让自己的生活更上一层楼。

因此,学习AI大模型是一项有前景且值得投入的时间和精力的重要选择。

自己手写了一个大模型RAG项目-04.知识库构建 大家好,我是程序锅。github上的代码封装程度高,不利于小白学习入门。常规的大模型RAG框架有langchain等,但是langchain等框架源码理解困难,debug源码上手难度大。因此,我写了一个人人都能看懂、人人都能修改的大模型RAG框架代码。整体项目结构如下图所示:手把手教你大模型RAG框架架构整个小项目分为10个章节,和github高度封装的RAG代码不同,我们将从0到1搭建大模型RAG问答系统,所有代码评论区回复rag免费获取!本篇文章将介绍。 阅读详情

相关推荐

python实现RAG相关思路与过程

python实现大模型向量检索RAG

NLP与推荐算法 1025

【Python大语言模型系列】不到两百行代码教你实现一个完整的RAG系统(案例+源码)

不到两百行代码教你实现一个完整的RAG系统(案例+源码)

数据杂坛 3675

朴素RAG:Python从零实现

检索增强生成(RAG)是一种将信息检索与生成模型相结合的混合方法。它通过引入外部知识来增强语言模型的性能,从而提高准确性和事实正确性。数据摄取:加载并预处理文本数据。分块:将数据分成较小的块以提高检索性能。嵌入创建:使用嵌入模型将文本块转换为数值表示。语义搜索:根据用户查询检索相关块。响应生成:使用语言模型基于检索到的文本生成响应。本文实现了一个简单的RAG方法,评估模型的响应,并探索各种改进。

AI人工智能的学习之路 898

RAG入门实践:手把手Python实现搭建本地知识问答系统

向量数据库是AI时代的“数据配对专家”,用向量化思维解决非结构化数据的存储和检索难题,尤其适合需要。

Arbboter的专栏 7709

(UE5 5.2)HISM Mobile DrawInstance在渲染层的实现浅分析

在 (UE4 4.27) UHierarchicalInstancedStaticMesh(HISM)原理分析 这篇博客大致介绍HISM组件从游戏线程到渲染线程的重建KD-Tree和剔除并提交DrawCall逻辑,但是没有分析渲染层的大致数据结构和实现. 可以看出FHierarchicalStaticMeshSceneProxy 实际存储Instance数组数据来自于FInstancedStaticMeshSceneProxy FHierarchicalStaticMeshSceneProxy只是以FClu

qq_29523119的博客 2725

半导体AMHS天车振动控制:从0.5G到超低振动的技术演进与工程实战

在先进晶圆厂中,自动化物料搬运系统(AMHS)的天车如同空中出租车,承担着晶圆盒(FOUP)在洁净室各工艺区间的转运任务。然而,当天车加减速、过弯或抓取时产生的机械振动通过轨道梁和建筑结构传递至光刻机等敏感设备,便可能直接威胁套刻精度与良率。传统被动减振方案依靠橡胶垫和弹簧,在0.5G指标时代曾行之有效,但在EUV光刻和先进制程面前已力不从心。主动振动控制技术通过传感器、控制器与作动器构成的闭环系统,在轨道吊点和机械手端实时输出反向力抵消振动,配合磁悬浮走行、轻量化结构及调度系统的路径优化,将振动从0.5G

weixin_29188043的博客 345

不到两百行代码教你实现一个完整的RAG系统(案例+源码)

# 使用huggingfacepipeline本地搭建大语言模型# 使用OpenAI的大语言模型# 获取环境变量 OPENAI_API_KEY# 使用智谱AI的大模型。

EnjoyEDU的博客 2141

CVE-2017-7921漏洞深度解析:海康设备明文密码泄露原理与七层防御

网络摄像头安全本质上是嵌入式Web服务安全,其核心在于身份认证机制是否健全。CVE-2017-7921并非传统远程执行漏洞,而是因信任错位导致的未授权API暴露——`/Security/users/1`接口绕过Session校验,直接返回admin明文密码。该问题根植于安防设备早期‘物理隔离+前端可控’的设计假设,在P2P、云平台等新场景下全面失效。技术价值在于揭示了轻量级HTTP服务中路径级访问控制缺失的普遍风险;典型应用场景包括ONVIF协议接管、Telnet后门登录及NVR侧横向移动。本文基于DS-2

weixin_33324197的博客 403

从零开始搭建 RAG 智能问答系统:一个完整的实战案例|附源码

你是否曾经为处理大量文档而烦恼?是否希望有一个智能助手,能够快速回答你关于文档的任何问题?今天,我将分享一个完整的实战案例,教你如何从零开始搭建一个基于 RAG 技术的智能问答系统。引言还记得上次为了找一个文档中的关键信息,花了整整一个下午翻找的经历吗?或者为了回答客户的问题,不得不反复查阅产品手册的困扰?在信息爆炸的时代,如何高效地管理和利用文档资源,已经成为每个企业和个人都面临的挑战。今天,我要分享一个解决方案:使用 RAG(检索增强生成)技术构建智能问答系统。这个系统不仅能理解你的问题,还能从海量文档

zhishi0000的博客 4564

【数据集】CAMS 全球生物质燃烧排放 GFAS(基于火灾辐射功率)

CAMS 全球生物质燃烧排放 GFAS(基于火灾辐射功率)

WW、forever的博客 400

APM32取代STM32的经验分享

我仔细检查了代码中与硬件相关的部分,例如外设寄存器的访问和中断处理程序的设置,并进行了相应的修改。在本文中,我将分享我将APM32引入项目中取代STM32的经验,并提供相应的源代码。我查看了APM32的官方网站、开发者论坛和相关社交媒体,了解了开发者社区的活跃度和可用的资源。总结起来,将APM32替换STM32的过程需要经过几个关键步骤:了解APM32的规格和功能、评估软件生态系统、迁移代码和调试,以及性能和功耗优化。在开始替换之前,我对APM32进行了详细的研究和评估,以确保它能够满足项目的需求。

UplKubernetes的博客 2004

检索增强生成RAG系列1--RAG的实现

大模型出现涌现能力之后,针对大模型的应用也如雨后春笋般。但是,在大模型真正落地之前,其实还需要做好最后一公里,而这个最后一公里,其中不同应用有着不同的方法。其中prompt、微调和RAG都是其中方法之一。本系列就是针对RAG从入门到落地应用的流程。

代码让AI扣 1240

YOLOv8改进系列:RepVGG重参数化结构——训练多分支,推理单路,极致提速

本文将详细介绍如何将RepVGG的重参数化思想融入到YOLOv8的骨干网络中,实现一种训练时多分支、推理时单路的改进版YOLOv8。我们将提供完整的代码实现、详细的原理讲解,并在COCO数据集和自定义数据集上进行充分的实验验证。

YOLO 200

从零到一:Python构建企业级RAG系统完整实战指南(附完整源码)

RAG技术正处于快速发展期,从基础的文档问答到复杂的多模态智能助手,应用场景不断扩展。通过本项目的学习,你已经掌握了RAG系统的核心技术,具备了构建生产级AI应用的基础能力。🎯用户体验优先:技术服务于业务需求⚡性能与精度平衡:在速度和准确性间找到最佳点🔄持续迭代优化:基于用户反馈不断改进🛡️安全与隐私:保护用户数据和系统安全🚀立即实践:在自己的项目中应用RAG技术🤝社区参与:加入AI技术社区,分享经验📈持续学习:关注最新的RAG技术发展💡创新思考:探索RAG在新场景下的应用可能。

小一的专栏 1293

【YOLOs-CPP-图像分类部署】04-项目优化(加速部署)

本文详细介绍了将YOLO图像分类C++部署项目从CMake迁移到Visual Studio控制台应用的全过程。针对低配CPU性能瓶颈问题,作者通过替换多线程HPP代码为官方实现,并采用448x448固定输入尺寸优化推理速度。项目配置包含OpenCV和ONNX Runtime环境设置,实现了图像批量处理、分类结果显示及结果日志输出功能。关键步骤包括依赖库配置、DLL部署和代码调试,最终在Windows平台成功实现高效CPU推理。该方案显著提升了低配硬件的兼容性,为图像分类任务提供了稳定的部署解决方案。

深耕CV 354

【Simulink教程案例9】基于simulink的BPSK,QPSK调制解调通信系统建模与仿真——使用simulink自带模块设计

BPSK (Binary Phase Shift Keying)-------二进制相移键控。是把模拟信号转换成数据值的转换方式之一,利用偏离相位的复数波浪组合来表现信息键控移相方式。BPSK使用了基准的正弦波和相位反转的波浪,使一方为0,另一方为1,从而可以同时传送接受2值(1比特)的信息。BPSK的映射关系如下所示:BPSK调制过程将输入的1010二进制数据中的0都转化为-1,使得非极性码变为极性码。

FPGA/MATLAB学习教程/源码/项目合作开发 3486

LangChain开发(九)基于Rag实现文档问答

大语言模型可以对广泛的主题进行推理,但它们的知识仅限于训练时截止日期前得公开数据。如果你想构建能够对私有数据或模型截止日期后引入的数据进行推理的人工智能应用,你需要用特定信息来增强模型的知识。使用Streamlit实现文件上传,这里只实现了pdf和txt文件上传,可以在type参数里面设置多个文件类型,在后面的检索器方法里面针对每个类型进行处理即可。大语言模型所实现的最强大的应用之一是复杂的问答(Q&A)聊天机器人。:实际的RAG链,在运行时接受用户查询,从索引中检索相关数据,然后将其传递给模型。

Java全栈开发者 1896

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

从零实现一个简单的RAG系统

我们先从一个。

2401_85116933的博客 1065

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

【AI大模型第10集】RAG技术实现原理及实战(附完整代码)

RAG(检索增强生成)是一种结合外部知识检索与生成模型的技术框架,能有效解决传统生成模型的知识局限和信息滞后问题。其核心优势包括突破知识瓶颈、动态更新能力、支持私有领域知识以及成本效率优化。RAG系统可分为黑盒增强架构(不调整大模型参数)和白盒增强架构(微调大模型),前者侧重优化检索器,后者则协同优化检索器与生成模型。典型实现如REPLUG LSR(黑盒)和Atlas(白盒),通过不同方式提升检索与生成的协同效果,使输出更准确可靠。该技术适用于需要实时更新、领域专业性强或数据隐私要求高的应用场景。

学不可以已,活到老,学到老。 762

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

RAG实战篇:构建一个最小可行性的Rag系统

经过上述流程,我们搭建了一个非常简单的Naive RAG系统,这个系统解析了一篇博客文章,然后接收用户提问,并使用博客的内容做增强生成。这是一个非常简单的框架,也很易于理解。但是在实际应用中还有非常多需要优化的地方,包括Indexing(索引)、Query Translation(查询转换)、Routing(路由)、Query Construction(查询构建)、Retrival(检索)和Generation(生成),每个环节都有多种有效的优化方式。

xx_nm98的博客 2597

RAG工程-基于LangChain 实现 Naive RAG

本篇文章以实现简单的第一范式 RAG-Naive RAG为目标,并最终创建并实现一个基于RAG的论文分析器的项目。

wend的博客 1908

手把手带你徒手打造一个RAG系统!

今天,废话不多说,我们直接进入实战!我将带你一步步构建一个属于你自己的、简易而完整的RAG框架,让你亲手揭开AI“最强大脑”背后的秘密。

2401_82469710的博客 1168

从零开始构建RAG系统,检索增强生成技术详解(附代码实现)

RAG技术通过结合外部知识检索与大型语言模型生成能力,解决了LLM知识时效性和领域特定信息不足的问题。构建RAG系统需经过五个关键步骤:数据准备(收集、清洗、标注)、向量数据库选择与构建、检索模块设计、大语言模型集成以及评估与优化。文章详细介绍了每个步骤的实现方法,包括代码示例,帮助开发者构建更准确、更具针对性的问答系统。

m0_74942241的博客 773

NiceGUI系统源码下载-开发一套RAG系统

有朋友可能会问,将检索出的内部文件发送给公开的大模型接口会不会引起数据泄露?这个问题我回答不了,从理论上说,数据只要通过公网交互就会产生泄露的风险,所以我在文中也说了,之后会考虑全部本地化部署一个规模小一点的模型,用廉价设备继续玩儿一玩儿RAG应用,有兴趣的同学随时联系。

weixin_42152901的博客 1127
上一篇: 还不会部署本地AI大模型?LangChat带你快速接入并部署本地大模型
下一篇: 面了阿里大模型算法岗,问的贼细。。。
少喝冰美式
博客等级 码龄3年 6839粉丝 517原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值