LangChain和qwen实现RAG增强检索
本教程技术的选型为langchain+通义千问(qwen),使用的通义千问提供的API,为啥不选择本地部署开源LLM模型的?目前只是处在探索RAG项目应用阶段,再加上本地电脑配置有限,只能跑小型的模型,效果不是很好,目前调用有免费额度,所以最终选择了它。 在开始之前,我们先花几分钟了解一下什么是RAG? RAG 是一种用附加数据来增强大语言模型的技术。RAG技术利用检索模块从大型语料库中检索相关信息,可以更准确地获取到与问题相关的内容,从而提高了问答系统的准确性。与传统的基于生成的系统相比,RAG技术能够更好地理解用户的问题,并给出更准确、全面的答案。 RAG工作流程分为以下步骤 1.数据获取 加载各种类型的数据,如文本文件、PDF、网站数据、数据库或者是接口API。 2.数据预处理和清理 获取到数据后,针对不同格式的数据进行清理,剔除不必要的数据。 3.分块 将数据分成更小的块,对应检索数据比较有用,大块的数据更难搜索并且不适合上下文检索有限的大语言模型。 4.词嵌入 分块后,需要将文本转换成LLM可以理解的数字表示形式(向量嵌入)。 5.矢量数据库 存储转换后的向量数据,方便我们对更多的文档进行检索 6.检索相关内容 根据用户的提问,先从矢量数据库中找到相似的内容。 7.LLM生成 通过检索到相似的内容,把它和用户的问题一起传递给LLM,以便LLM生成更准确的内容。 
准备内容:通义千问API-KEY(必须):申请很简单的,注册账号后进行认证,就可以开通了,几分钟搞定。 langchain的安装
# pip安装 pip install langchain # 如果你用的是Conda,也可以通过以下命令 # conda install langchain -c conda-forge
# pdf文档的读取和ocr识别 pip install pypdf rapidocr-onnxruntime
pip install --upgrade --quiet dashscope 引入相关包from langchain_community.document_loaders import PyPDFLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_community.vectorstores import FAISS from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.llms import Tongyi from langchain_core.prompts import PromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough import os 数据的准备这步主要是把数据读取出来,然后将文档拆分成小块。 chunk_size:指定了每个拆分的片段的长度为1000个字符。
chunk_overlap:指定了每个拆分的片段之间的重叠部分为200个字符。
add_start_index:指定了是否在每个拆分的片段中添加起始索引。如果设置为 True,则在每个拆分的片段的开头添加一个起始索引。
pdf_loader = PyPDFLoader('test.pdf', extract_images=True) text_splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200, add_start_index=True ) pages = pdf_loader.load_and_split()词嵌入并保存到向量数据库使用阿里的灵积模型服务的文本嵌入模型,把拆分成小块的数据进行向量化。然后对数据进行查询,返回两个最相似的数据块,最后保存到向量数据库,下次我们就可以加载该文件使用了。 embeddings = DashScopeEmbeddings( model="text-embedding-v1", dashscope_api_key="你申请的千问API-KEY" )
faiss_index = FAISS.from_documents(all_splits, embeddings) # 搜索我们的文档数据,返回两个最相似的
docs = faiss_index.similarity_search("本季度排名第一的电视剧是啥?", k=2)
# 打印输入 for doc in docs: print(str(doc.metadata["page"]) + ":", doc.page_content[:300])
# 保存到向量数据库中 faiss_index.save_local('testpdf.faiss') 调用大语言模型生成结果先加载向量库文件,然后将向量数据转换成 Retriever 类,最后构建通义千问的大语言模型服务对象。 faiss_index = FAISS.load_local('testpdf.faiss', embeddings, allow_dangerous_deserialization=True)
retriever = faiss_index.as_retriever(search_kwargs={"k": 6})
os.environ["DASHSCOPE_API_KEY"] = "你申请的千问API-KEY"
llm = Tongyi()
开始构建模板通过上下文+提问的方式,生成模板。 template = """利用以下上下文回答最后的问题。如果不知道答案,就说不知道,不要试图编造答案。
{context}
Question: {question}
Helpful Answer:""" custom_rag_prompt = PromptTemplate.from_template(template)
rag_chain = ( {"context": retriever, "question": RunnablePassthrough()} | custom_rag_prompt | llm | StrOutputParser() ) 进行提问rag_chain.invoke("本季度排名第一的电视剧是啥?")


|