欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 1、开始简单使用rag

1、开始简单使用rag

2025/2/25 15:03:20 来源:https://blog.csdn.net/zengraoli/article/details/145400723  浏览:    关键词:1、开始简单使用rag

文章目录

  • 前言
  • 数据存放
  • 申请api
  • 开始代码
    • 安装依赖
    • 从文件夹中读取文档
    • 文档切块
    • 将分割嵌入并存储在向量库中
    • 检索部分代码
    • 构造用户接口
    • 演示提示
  • 整体代码

前言

本章只是简单使用rag的一个示例,为了引出以后的学习,将整个rag的流程串起来

数据存放

一个示例的文件夹OneFlower下,存放了三种不同类型的文档:

在这里插入图片描述

申请api

本文档中使用的在线api为gpt4,所以需要先申请,如果是国内也可以按照文档使用glm:glm使用文档

开始代码

下面会对每一部分的代码进行说明

安装依赖

pip install langchain
pip install openai
pip install qdrant-client

从文件夹中读取文档

通过便利文件夹OneFlower下,找到所以文件,通过文件的后缀,使用不同的解析器,将解析后的文档存放到documents中

import os
os.environ["OPENAI_API_KEY"] = 'sk-openai的key'# 1.Load 导入Document Loaders
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import Docx2txtLoader
from langchain.document_loaders import TextLoader# 加载Documents
documents = []
for file in os.listdir('OneFlower'): if file.endswith('.pdf'):pdf_path = './OneFlower/' + fileloader = PyPDFLoader(pdf_path)documents.extend(loader.load())elif file.endswith('.docx') or file.endswith('.doc'):doc_path = './OneFlower/' + fileloader = Docx2txtLoader(doc_path)documents.extend(loader.load())elif file.endswith('.txt'):text_path = './OneFlower/' + fileloader = TextLoader(text_path)documents.extend(loader.load())

文档切块

一大片的文档对检索是不友好的,我们需要按照小块进行切分,也就是chunk,每块的大小为200个字符(并且在api中对乱码进行了处理),块与块之间有10个长度的重叠,这种形式的切块使用RecursiveCharacterTextSplitter这个api来操作

# 2.Split 将Documents切分成块以便后续进行嵌入和向量存储
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10)
chunked_documents = text_splitter.split_documents(documents)

将分割嵌入并存储在向量库中

向量库我们使用的是Qdrant,当然还可以使用faiss或者chromedb都是可以的

# 3.Store 将分割嵌入并存储在矢量数据库Qdrant中
from langchain.vectorstores import Qdrant
from langchain.embeddings import OpenAIEmbeddings
vectorstore = Qdrant.from_documents(documents=chunked_documents, # 以分块的文档embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入location=":memory:",  # in-memory 存储collection_name="my_documents",) # 指定collection_name

检索部分代码

这个部分,我们主要狗见了一个大模型的检索,他接收的是vectorstore返回的检索,MultiQueryRetriever的意思是我们需要llm帮我们生成多个MultiQuery,比如:

  • “区块链如何运作?”
  • “区块链的核心技术是什么?”
  • “区块链的数据结构是如何设计的?”
    然后MultiQueryRetriever 依次执行这些查询,并合并结果,最终返回更多相关的文档,提高召回率。

logging的引入,方便我们进行提问的输出

# 4. Retrieval 准备模型和Retrieval链
import logging # 导入Logging工具
from langchain.chat_models import ChatOpenAI # ChatOpenAI模型
from langchain.retrievers.multi_query import MultiQueryRetriever # MultiQueryRetriever工具
from langchain.chains import RetrievalQA # RetrievalQA链# 设置Logging
logging.basicConfig()
logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO)# 实例化一个大模型工具 - OpenAI的GPT-3.5
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)# 实例化一个MultiQueryRetriever
retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm)# 实例化一个RetrievalQA链
# qa_chain = RetrievalQA.from_chain_type(llm,retriever=vectorstore.as_retriever()) # 单个的问题
qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm)

构造用户接口

输出一个input,让用户进行提问,只要不是exit就继续,ask_question是执行langchain的调用

# 5. 问答展示
def ask_question(query):# 使用RetrievalQA链来获取答案response = qa_chain(query)# 返回得到的答案return response# 为用户提供交互界面进行问答
while True:# 获取用户的问题user_query = input("请随意提问 (或者输入'exit'退出): ")# 如果用户输入"exit",则退出循环if user_query.lower() == 'exit':break# 使用定义的函数获取答案,并打印answer = ask_question(user_query)print("答案:", answer)print("谢谢使用 QA 系统!")

演示提示

在这里插入图片描述

对应pdf文档中可以看到对应的内容

在这里插入图片描述

在这里插入图片描述

整体代码

整体代码如下,方便在PyCharm中直接运行

import os
os.environ["OPENAI_API_KEY"] = 'sk-openai的key'# 1.Load 导入Document Loaders
from langchain.document_loaders import PyPDFLoader
from langchain.document_loaders import Docx2txtLoader
from langchain.document_loaders import TextLoader# 加载Documents
documents = []
for file in os.listdir('OneFlower'): if file.endswith('.pdf'):pdf_path = './OneFlower/' + fileloader = PyPDFLoader(pdf_path)documents.extend(loader.load())elif file.endswith('.docx') or file.endswith('.doc'):doc_path = './OneFlower/' + fileloader = Docx2txtLoader(doc_path)documents.extend(loader.load())elif file.endswith('.txt'):text_path = './OneFlower/' + fileloader = TextLoader(text_path)documents.extend(loader.load())import os# 设置环境变量
os.environ['http_proxy'] = 'http://127.0.0.1:7890'
os.environ['https_proxy'] = 'http://127.0.0.1:7890'
os.environ['all_proxy'] = 'http://127.0.0.1:7890'# export HTTP_PROXY=http://127.0.0.1:7890; #换成你自己的代理地址
# export HTTPS_PROXY=http://127.0.0.1:7890; #换成你自己的代理地址
# export ALL_PROXY=socks5://127.0.0.1:7890#换成你自己的代理地址# 2.Split 将Documents切分成块以便后续进行嵌入和向量存储
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=10)
chunked_documents = text_splitter.split_documents(documents)# 3.Store 将分割嵌入并存储在矢量数据库Qdrant中
from langchain.vectorstores import Qdrant
from langchain.embeddings import OpenAIEmbeddings
vectorstore = Qdrant.from_documents(documents=chunked_documents, # 以分块的文档embedding=OpenAIEmbeddings(), # 用OpenAI的Embedding Model做嵌入location=":memory:",  # in-memory 存储collection_name="my_documents",) # 指定collection_name# 4. Retrieval 准备模型和Retrieval链
import logging # 导入Logging工具
from langchain.chat_models import ChatOpenAI # ChatOpenAI模型
from langchain.retrievers.multi_query import MultiQueryRetriever # MultiQueryRetriever工具
from langchain.chains import RetrievalQA # RetrievalQA链# 设置Logging
logging.basicConfig()
logging.getLogger('langchain.retrievers.multi_query').setLevel(logging.INFO)# 实例化一个大模型工具 - OpenAI的GPT-3.5
llm = ChatOpenAI(model_name="gpt-4o-mini", temperature=0)# 实例化一个MultiQueryRetriever
retriever_from_llm = MultiQueryRetriever.from_llm(retriever=vectorstore.as_retriever(), llm=llm)# 实例化一个RetrievalQA链
# qa_chain = RetrievalQA.from_chain_type(llm,retriever=vectorstore.as_retriever())
qa_chain = RetrievalQA.from_chain_type(llm,retriever=retriever_from_llm)# 5. 问答展示
def ask_question(query):# 使用RetrievalQA链来获取答案response = qa_chain(query)# 返回得到的答案return response# 为用户提供交互界面进行问答
while True:# 获取用户的问题user_query = input("请随意提问 (或者输入'exit'退出): ")# 如果用户输入"exit",则退出循环if user_query.lower() == 'exit':break# 使用定义的函数获取答案,并打印answer = ask_question(user_query)print("答案:", answer)print("谢谢使用 QA 系统!")

资源csdn链接:等待更新

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词