RAG就是一句话:对数据设置索引,用问题去检索,用llm生成回答
注意: py 3.10以上
配置环境变量,安装库
load外部数据,存储到本地的一个index里(这是最简单的形式)
对数据做切分 split
然后,做store存储,用Embedding的方式,将切好的数据存到某种数据库,比如向量数据库里
(eg...把问题抽象一下,再具体的去数据库检索;把问题用llm重新生成几个语义不变的问题,都去数据库检索;把长问题分解成多个短问题等)主要就是为了能提高与数据库中数据的检索成功率和检索效率。
(eg...文档、摘要、分好的文档、聚类后的摘要、带上下文信息的token级的词向量)的 相似度 ,比如用的k临近算法,SVN
再说人话一点:
没问题,你看我这样说怎么样:
一句话概括 RAG: 咱们先给一大堆资料建个“索引”(就像图书馆的书架一样),然后你问问题,我就去这个“索引”里快速找到最相关的几段话,最后让厉害的“聊天机器人”(LLM)根据你问的问题和找到的资料,给你一个靠谱的回答。
咱们一步步来,打造你的“本地知识小助手”:
准备好你的“小书库”: 你得先把你的各种资料弄进来,比如你的笔记、PDF 文档、网页文章等等。Langchain 就像一个“搬运工”,能帮你把这些东西都“搬”到电脑里。
给你的“小书”分段: 有些“书”(文件)太长了,一下塞给“聊天机器人”它会懵。所以我们要把它们切成一小段一小段的,就像给长文章分段落一样,方便后面查找。
给每段“小书”贴标签(Embedding): 光分段还不行,我们得让电脑知道每段话是关于什么的。这就用到一种叫 “Embedding” 的技术,简单来说就是把每段话变成一串数字(就像给书贴上内容标签),意思相近的段落,它们的数字也会比较接近。
把“标签”放进“超级书架”(向量数据库): 我们把这些“数字标签”放到一个特别的“书架”里,这个“书架”(向量数据库)的特点就是找东西特别快!你给出一个新的问题(也变成“数字标签”),它能迅速找到和这个问题最相关的那些“书”的“标签”。
开始提问,让“小助手”去找答案: 现在你可以问你的“小助手”任何问题了。
“小助手”分析你的问题: 它不会直接拿着你的问题就去找,可能会稍微“琢磨”一下你的问题,比如换个说法问,或者把一个复杂的问题拆成几个小问题,这样能更准确地找到相关的资料。
“小助手”去“超级书架”里翻书: 它会把你的问题也变成“数字标签”,然后去“超级书架”(向量数据库)里找那些最相似的“书”的“标签”。这就好比在图书馆里,管理员根据你描述的主题,快速找到相关的书籍。
找到相关的“书”了! “小助手”会找到和你的问题最相关的几段话。
“聊天机器人”读“书”回答问题: 最后,Langchain 会把你的问题和找到的相关段落一起交给厉害的“聊天机器人”(LLM),让它读懂这些信息,然后给你一个清晰、有条理的回答。
更厉害的“小助手”还能做这些:
检索增强生成(Retrieval-Augmented Generation,RAG)是一种强大的自然语言处理(NLP)范式,它通过从外部知识库检索相关文档片段,并将其融入到语言模型的生成过程中,来提高生成文本的质量、相关性和可信度。Langchain 是一个旨在简化 LLM(大型语言模型)应用程序开发的框架,它提供了构建 RAG 系统的各种工具和模块。本文档将深入探讨如何在 Langchain 中使用这些工具来构建高效的 RAG 系统。
一个典型的 RAG 系统包含以下核心步骤:
Langchain 提供了丰富的模块来构建 RAG 系统的各个环节:
Langchain 提供了各种文档加载器,用于从不同的数据源加载文档。例如:
TextLoader
: 加载纯文本文件。PyPDFLoader
: 加载 PDF 文件。WebBaseLoader
: 从 URL 加载网页内容。DirectoryLoader
: 加载指定目录下的多个文件。示例代码:
Python
from langchain.document_loaders import TextLoader
# 从文本文件加载文档
loader = TextLoader("./my_document.txt")
documents = loader.load()
print(f"加载了 {len(documents)} 个文档。")
print(f"第一个文档的内容:\n{documents[0].page_content[:100]}...")
文本分割器将大型文档分割成更小的块。Langchain 提供了多种分割策略:
CharacterTextSplitter
: 基于字符进行分割。RecursiveCharacterTextSplitter
: 尝试按特定字符(例如,段落、句子、单词)递归地分割,直到块大小合适。TokenTextSplitter
: 基于 token 进行分割。示例代码:
Python
from langchain.text_splitter import RecursiveCharacterTextSplitter
text = """这是一个很长的文档,包含了多个段落。
第一段是关于 Langchain 的介绍。
第二段讨论了 RAG 系统的原理。
第三段将介绍如何在 Langchain 中使用 RAG。"""
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=100,
chunk_overlap=20,
separators=["\n\n", "\n", " ", ""],
)
chunks = text_splitter.split_text(text)
print(f"文档被分割成 {len(chunks)} 个文本块。")
print(f"第一个文本块:\n{chunks[0]}")
嵌入模型将文本转换为向量表示。Langchain 集成了多种流行的嵌入模型:
OpenAIEmbeddings
: 使用 OpenAI 的嵌入模型(需要 API 密钥)。HuggingFaceEmbeddings
: 使用 Hugging Face Transformers 库中的模型。SentenceTransformerEmbeddings
: 使用 sentence-transformers 库中的模型。示例代码:
Python
from langchain.embeddings import OpenAIEmbeddings
# 需要设置 OpenAI API 密钥
# export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
embeddings = OpenAIEmbeddings()
text = "这是一个用于测试嵌入的句子。"
vector = embeddings.embed_query(text)
print(f"文本的向量表示(前 5 个维度):\n{vector[:5]}...")
向量存储用于存储和索引文本块的向量嵌入,以便进行高效的相似性搜索。Langchain 支持多种向量数据库:
FAISS
: 一个高效的相似性搜索库。Chroma
: 一个轻量级的嵌入数据库。Pinecone
: 一个托管的向量数据库服务。Weaviate
: 一个开源的向量数据库。示例代码(使用 FAISS):
Python
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
text = """这是一个示例文档,用于演示如何将文本存储到 FAISS 向量存储中。
它可以包含多个段落和句子。"""
text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=0)
chunks = text_splitter.split_text(text)
embeddings = OpenAIEmbeddings()
db = FAISS.from_texts(chunks, embeddings)
# 保存向量存储
db.save_local("faiss_index")
# 加载向量存储
loaded_db = FAISS.load_local("faiss_index", embeddings)
# 执行相似性搜索
query = "如何在向量存储中存储文本?"
docs = loaded_db.similarity_search(query)
print(f"与查询相关的文档片段:\n{docs[0].page_content}")
检索器负责根据用户查询从向量存储中检索相关的文档。Langchain 提供了多种检索器:
VectorStoreRetriever
: 基于向量存储的相似性搜索。BM25Retriever
: 基于 BM25 算法的稀疏检索。MultiQueryRetriever
: 生成多个相关查询并检索结果,以提高检索的覆盖率。示例代码(使用 VectorStoreRetriever):
Python
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
# 假设已经加载了向量存储 loaded_db
retriever = loaded_db.as_retriever()
query = "什么是向量嵌入?"
relevant_docs = retriever.get_relevant_documents(query)
print(f"检索到的相关文档数量:{len(relevant_docs)}")
print(f"第一个相关文档的内容:\n{relevant_docs[0].page_content}")
Langchain 集成了各种大型语言模型:
OpenAI
: 使用 OpenAI 的语言模型(例如,GPT-3.5, GPT-4)。HuggingFaceHub
: 使用 Hugging Face Hub 上的模型。Cohere
: 使用 Cohere 的语言模型。示例代码(使用 OpenAI 的 Chat Model):
Python
from langchain.chat_models import ChatOpenAI
from langchain.schema import HumanMessage
# 需要设置 OpenAI API 密钥
# export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"
llm = ChatOpenAI(model_name="gpt-3.5-turbo")
messages = [HumanMessage(content="请简要介绍一下 Langchain。")]
response = llm(messages)
print(f"LLM 的回复:\n{response.content}")
提示词模板用于构建发送给语言模型的输入。在 RAG 系统中,提示词通常包含用户查询和检索到的相关上下文。
示例代码:
Python
from langchain.prompts import ChatPromptTemplate
template = """请根据以下上下文回答用户的问题:
上下文:{context}
问题:{question}
答案:"""
prompt = ChatPromptTemplate.from_template(template)
formatted_prompt = prompt.format_messages(
context="Langchain 是一个用于构建 LLM 应用程序的框架。",
question="Langchain 的主要用途是什么?",
)
print(f"格式化后的提示词:\n{formatted_prompt[0].content}")
输出解析器用于结构化语言模型的输出。
示例代码(简单的文本输出解析器):
Python
from langchain.schema import StrOutputParser
output_parser = StrOutputParser()
# 在 Chain 中使用
Chains 是 Langchain 的核心概念,它将不同的组件(例如,加载器、分割器、嵌入模型、向量存储、检索器、语言模型、提示词模板、输出解析器)连接在一起,形成一个完整的处理流程。对于 RAG 系统,RetrievalQA
或 RetrievalQA.from_chain_type
是一个常用的 Chain 类型。
示例代码(使用 RetrievalQA):
Python
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import TextLoader
# 加载文档
loader = TextLoader("./my_document.txt")
documents = loader.load()
# 分割文本
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=20)
chunks = text_splitter.split_documents(documents)
# 创建嵌入模型
embeddings = OpenAIEmbeddings()
# 创建向量存储
db = FAISS.from_documents(chunks, embeddings)
# 创建检索器
retriever = db.as_retriever()
# 创建语言模型
llm = ChatOpenAI(model_name="gpt-3.5-turbo")
# 创建 RetrievalQA Chain
qa_chain = RetrievalQA.from_llm(llm, retriever=retriever)
# 提问
query = "文档中提到了哪些关键技术?"
result = qa_chain({"query": query})
print(f"问题:{query}")
print(f"答案:{result['result']}")
除了基本的 RetrievalQA
,Langchain 还支持构建更复杂的 RAG 系统,例如:
RetrievalQAWithSourcesChain
。GraphCypherQAChain
等。ContextCompressor
。BaseRetriever
类来实现自定义的检索逻辑。Langchain 提供了一套强大且灵活的工具,可以帮助开发者快速构建和部署高效的 RAG 系统。通过理解 RAG 的基本流程以及 Langchain 中各个组件的用法,开发者可以根据自己的需求定制出各种复杂的问答、信息检索和文本生成应用。希望本文档能够帮助您入门 Langchain 中的 RAG 系统开发。
文本加载器——做数据增强 RAG
TextLoader ,CSVLoader等
文档转换器—— 进行拆分
对文本拆分,对代码拆分,对json拆分
当检索到相关的文档10+的时候,设置检索器...