langchain-RAG检索 | 豆包MarsCode AI刷题

127 阅读4分钟

前言

上两篇文章分别介绍了LangChain的快速入门和Agent智能体开发。在LLM的实际应用场景中,经常会需要用到特定领域用户的数据,但这些数据不属于模型训练集的一部分,要实现这一需求,最好的方法是通过检索增强生成(RAG)。在用户提问时,先检索特定的外部数据,把检索结果作为上下文传递给LLM,以便大模型返回更精准的结果。今天我们就带大家了解下在LangChain里RAG的使用,结合智谱AI GLM4大模型开发一个基于特定知识库的智能问答应用。

RAG介绍

LangChain中提供了RAG应用程序的所有构建模块。结构图如下:

image.png

1、文档加载器

文档加载器用来加载各种不同类型的文档。LangChain提供了100 多种不同的文档加载器,可以加载各种类型文档,包括:CSV、HTML、JSON、Markdown、PDF、DOC、XLS、图片、视频、音频等等。

2、文本分割器

加载文档后,对于长文档,需要分割成更小的块,以适合LLM的上下文窗口。LangChain 有许多内置的文档转换器,可以轻松地拆分、组合、过滤和以其他方式操作文档。 LangChain 提供了多种不同类型的文本分割器。下表列出了所有这些以及一些特征:

  • 类型:文本分割器的类型
  • 分割依据:此文本拆分器如何拆分文本
  • 添加元数据:此文本拆分器是否添加有关每个块来自何处的元数据。
  • 描述:分离器的描述,包括有关何时使用它的建议。

3、嵌入模型

嵌入(Embedding)是一种将单词、短语或整个文档转换为密集向量的技术。每个单词或短语被转换成一组数字,这组数字捕捉了该文本的某些语义特征。 嵌入模型通过将文本转换为计算机可以处理的数值形式(即向量),使得计算机能够理解和处理自然语言。通过嵌入捕获文本的语义,可以快速有效地找到文本的其他相似部分。 LangChain提供了超过25种不同嵌入提供商和方法的集成,抱脸上有个中文、英文嵌入模型排行榜,可以作为参考,具体还要选适合自己的,比如开源的,对中文支持比较好的等等:

4、向量数据库

有了嵌入模型对数据的向量化,就需要数据库来支持这些嵌入数据的高效存储和搜索。LangChain提供了50多种不同向量数据库的集成,目前Milvus评分最高。

RAG开发案例 接下来我们实战开发一个基于特定知识库的智能问答应用。还是在Jupyter Notebook环境中执行。

1、创建智谱GLM4大模型对象

首先定义LangChain里智谱大模型的包装类,参考第一篇文章里有,或者从github上下载: 创建大模型对象

# 填写您自己的APIKey
ZHIPUAI_API_KEY = "..."
llm = ChatZhipuAI(
    temperature=0.1,
    api_key=ZHIPUAI_API_KEY,
    model_name="glm-4",
)

加载文档

这里特定领域用户的数据来源于一个示例的ordersample.csv文件,这个文件可以从我的github上获取: 文件具体内容如下: 把orersample.csv下载到jupyter notebook当前ipynb文件目录,使用CSV文档加载器,加载文档内容:

from langchain_community.document_loaders.csv_loader import CSVLoader

loader = CSVLoader(file_path='ordersample.csv')
data = loader.load()

文本分割

通常可以使用递归字符文本分割器对文档对象进行分割,可以设置分割块字符的大小,和重合字符大小。因为我的文档对象比较小,所以每个文档基本上没有达到要切分的大小阈值,可以尝试把文档内容变多,试下效果。

from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000, chunk_overlap=200, add_start_index=True
)
all_splits = text_splitter.split_documents(data)

向量化存储

接下来我们首先使用嵌入模型对分割后的文档进行向量化,然后存储到向量数据库中。 嵌入模型使用的是bge-large-zh-v1.5,这是BAAI北京智源人工智能研究院开源的,支持中、英文的嵌入模型,在开源嵌入模型中算是效果比较好的一个。 向量数据库使用的是FAISS,是FAIR(Meta人工智能实验室)开源的向量数据库。可以在本地使用,相对轻量些,没有Milvus那么强, 但在本地环境使用也够用了。

from langchain_community.embeddings import HuggingFaceBgeEmbeddings

model_name = "BAAI/bge-large-zh-v1.5"
model_kwargs = {"device": "cpu"}
encode_kwargs = {"normalize_embeddings": True}
bgeEmbeddings = HuggingFaceBgeEmbeddings(
    model_name=model_name, model_kwargs=model_kwargs, encode_kwargs=encode_kwargs
)
from langchain_community.vectorstores import FAISS
vector = FAISS.from_documents(all_splits, bgeEmbeddings)

向量库检索

接下来尝试下使用向量库进行检索。

retriever = vector.as_retriever(search_type="similarity", search_kwargs={"k": 3})
retriever.invoke("收货人姓名是张三丰的,有几个订单?金额分别是多少,总共是多少?")

生成问答结果

使用检索链,串联向量库检索和大模型,根据用户的提问,生成问答结果。

from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_template("""仅根据所提供的上下文回答以下问题:

<context>
{context}
</context>

问题: {question}""")

from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
retriever_chain = (
    {"context": retriever , "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)