使用langchain 和本地HuggingFace 库,实现简单RAG应用
向量模型
向量模型是RAG系统中实现有效信息检索和生成的关键技术之一,它们使得系统能够处理复杂的语言理解任务,并生成更加准确和相关的输出。
向量模型将文本转换为向量形式,便于在高维空间中进行快速的相似性检索,这是RAG系统中检索相关信息的基石。通过向量化,模型能够评估不同文本之间的语义相似度,即使在词汇不完全匹配的情况下也能找到语义相关的文档。向量模型帮助系统捕捉输入查询的上下文信息,这对于理解用户意图并检索最相关的信息至关重要。
本篇文章将为大家介绍在langchain中使用自己向量模型的方法,帮助大家扫清障碍快速搭建
RAG
原因
我们可以在langchain官网看到RAG的实例代码RAG应用
不想点进去官网的话,下面我将贴出对于的关键代码
pip install -qU langchain-mistralai
pip install langchain langchain_community langchain_chroma
import getpass
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
import getpass
import os
os.environ["MISTRAL_API_KEY"] = getpass.getpass()
from langchain_mistralai import ChatMistralAI
llm = ChatMistralAI(model="mistral-large-latest")
import bs4
from langchain import hub
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
# Load, chunk and index the contents of the blog.
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)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
# Retrieve and generate using the relevant snippets of the blog.
retriever = vectorstore.as_retriever()
prompt = hub.pull("rlm/rag-prompt")
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
rag_chain.invoke("What is Task Decomposition?")
我跑过这段代码,如果你有对应的openai的API_KEY那你完全可以参考这段代码,添加你的需求就可以了,但是大多数情况下如果你没有这个要命的API_KEY,那恭喜你,你会在这里卡住
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
# 尤其是着一块embedding=OpenAIEmbeddings()
所以我们的替代方法就是需要选择使用本地的向量模型,来进行向量化
这里我们介绍一种我试用过的,并且简单可行的一种HuggingFaceEmbeddings的bge-small-zh-v1.5模型
因为我们使用的是本地模型这样可以一次下载之后不用每次使用都需要在中途下载,所以我们必须先将其下载到本地,(之前就是没有下载到本地,直接在代码中使用,所以每次执行都会很慢(等大概需要1分钟),因为需要加载模型)
下载步骤
- 这里我们给出下载地址**魔塔社区
- 出现这个页面表示加载成功
- 点击下载模型
这里我们选择git下载,如果没有装git环境的可以装一下,这个很常用的。
- 将模型拉取到本地之后,放到你项目的目录下
这样我们就可以本地的向量模型了
最后
这里我们给出一段 实例代码,使用本地的向量模型完成简单RAG应用
def simple_rag():
"""
1.实现简单的rag,将txt文件内容向量化
2.实现检索功能
:return: 检索结果
"""
# 读取并处理 TXT 文件
txt_file_path = "efaultRecordForm.txt"
text_loader = TextLoader(txt_file_path, encoding="utf-8")
raw_documents = text_loader.load()
# 分块
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
# 切分
splits = text_splitter.split_documents(raw_documents)
# 加载默认的本地HuggingFaceEmbeddings模型(这里一定要写你项目下的路径)
# 我习惯将模型放到models文件夹下
model_name = 'models/bge-small-zh-v1.5'
# 创建chrom向量数据库
db = Chroma(
collection_name="example_collection",
embedding_function=HuggingFaceEmbeddings(model_name=model_name),
persist_directory="chromDB/chroma_langchain_db", # 保存数据的本地目录
)
# 将分割的文本数据添加到数据库
db.add_documents(splits)
# 检索器对象 retriever search_type指定检索的类型为基于相似度的搜索。
retriever = db.as_retriever(search_type="similarity", search_kwargs={"k": 2})
retrieved_docs = retriever.invoke("给出故障的解决方案")
# print(retrieved_docs[0].page_content)输出检索内容
return retrieved_docs[0].page_content