RAG概述
一个典型的RAG应用程序,它有两个主要组件:
- 索引:从源中获取数据并对其进行索引的管道。这通常在脱机情况下发生。
- 检索和生成:在运行时接受用户查询,并从索引中检索相关数据,然后将其传递给模型。
从原始数据到答案的完整序列如下所示:
索引
- 加载:首先我们需要加载我们的数据。我们将为此使用DocumentLoaders。
- 拆分:文本拆分器将大型文档拆分成更小的块。这对于索引数据和将数据传递给模型都很有用,因为大块更难搜索,也不适合模型的有限上下文窗口。
- 信息存储:我们需要一个地方来存储和索引我们的拆分,以便以后可以搜索它们。这通常使用VectorStore和Embeddings模型来完成。
检索和生成
- 检索:给定用户输入,使用Retriever从存储中检索相关拆分。
- 生成:ChatModel/LLM使用包含问题和检索到的数据的提示生成答案。
代码实例
依赖加载
from langchain_community.llms import Ollama
import bs4
from langchain import hub
from langchain_community.document_loaders import WebBaseLoader
from langchain_chroma import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_community.embeddings import OllamaEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
#实例化大模型
llm = Ollama(model="llama2")
#添加向量化
embeddings = OllamaEmbeddings()
# 加载数据
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()
#我们这里查看具体的下载内容
print(docs)
查看具体的下载内容
加载数据的拆分和灌库
#添加数据的拆分 每1000个为一组并重叠200个字符
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
#拆分下载的数据
splits = text_splitter.split_documents(docs)
#灌入向量数据库
vectorstore