从0开始学RAG第一篇——RAG快速入门
- 原文地址:https://zhuanlan.zhihu.com/p/685411934
一、什么是检索增强生成(RAG)?
检索增强生成(RAG)作为一种将LLM与外部数据源打通的方法,可以有效弥补LLM的实时性和幻觉等短板。
二、检索增强生成(RAG)流程包含哪些环节?
常规的RAG流程包括indexing、retrieval和generation三部分,但当面对真实使用场景时,还需要采用更先进的技术和方案来解决现实中的挑战。
下图汇总了RAG全链路上各个环节可应用的技术,可以看到林林总总的还不少,接下来我们会用一个系列对图中的每项技术进行讲解和代码实践。有条件的同学可以follow 视频教程。
RAG全链路 视频 https://www.youtube.com/watch?v=wd7TZ4w1mSw&feature=youtu.be

2.1 Indexing
构建RAG应用首先要通过相应的loader加载数据,不论是pdf、word、markdown,亦或是网页。加载完成后再选择TextSplitter将文档切割为chunk用于embedding和向量存储。

2.2 Retrieval
最简单的retrieval是将向量存储作为检索器,检索获取相似文档。此外,还有各种类型的retriever,后面我们会一一介绍。
2.3 Retrieval
将retriever检索到的候选文档和query与prompt一并扔给LLM,让它根据prompt中的指令生成答案,生成的答案再用parser解析成人类方便阅读的格式。

三、检索增强生成(RAG)代码解读?
本节首先讲解如何利用ChatGPT快速构建RAG应用,大家可以根据自己的使用需求将代码中embedding模型和LLM替换成开源大模型。
以下是RAG应用的快速实现示例,初学者可以运行体验一下。
导包
import bs4 from langchain import hub from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.document_loaders import WebBaseLoader from langchain_community.vectorstores import Chroma from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough from langchain_openai import ChatOpenAI, OpenAIEmbeddings
3.1 INDEXING
# Load Documents loader = WebBaseLoader( web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",), bs_kwargs=dict( parse_only=bs4.SoupStrainer( class_=("post-content", "post-title", "post-header") ) ), ) docs = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) splits = text_splitter.split_documents(docs)
# Embed vectorstore = Chroma.from_documents( documents=splits, embedding=OpenAIEmbeddings() ) retriever = vectorstore.as_retriever()
3.2 RETRIEVAL and GENERATION
# Prompt prompt = hub.pull("rlm/rag-prompt")
# LLM llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# LLM llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
# Post-processingdef format_docs(docs): return "\n\n".join(doc.page_content for doc in docs)
# Chainrag_chain = ( {"context": retriever | format_docs, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser())
# Questionrag_chain.invoke("What is Task Decomposition?")
通过上面的示例代码,可以快速构建一个简单的RAG demo,体验LLM的乐趣。若想打造能够工程落地的RAG应用,需要针对具体数据和bad case确定总的解决方案,在indexing、retriever和generation等环节上进行联合优化。