用 LangChain 搭建基于 Notion 文档的 RAG 应用

2023-12-01 13:52

本文主要是介绍用 LangChain 搭建基于 Notion 文档的 RAG 应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如何通过语言模型查询 Notion 文档?LangChain 和 Milvus 缺一不可。

在整个过程中,我们会将 LangChain 作为框架,Milvus 作为相似性搜索引擎,用二者搭建一个基本的检索增强生成(RAG)应用。在之前的文章中,我们已经介绍过 LangChain 中的“自查询”(Self-querying)。本质上,LangChain 中的自查询功能就是构建一个基本的 RAG 架构,如图所示:

alt

在 LangChain 中处理 Notion 文档共包含三个步骤:获取、存储和查询文档。获取是指获取 Notion 文档并将内容加载到内存中。存储步骤包括启动向量数据库(Milvus)、将文档转化为向量、将文档向量存储至向量数据库中。查询部分包括针对 Notion 文档进行提问。本文将带大家一一拆解这三个步骤,代码请参考 colab notebook。

01.获取 Notion 文档

用 LangChain 的 NotionDirectoryLoader将文档加载到内存中。我们提供文档的路径并调用load 函数来获取 Notion 文档。加载完毕后,可以得到 Notion 文档的 Markdown 文件。本例中我们以一个 Markdown 文件示意。

接下来,用 LangChain 的 markdown 标题文本分割器。我们向其提供一个分割符列表,然后传入之前命名的 md_file 来获取分割内容。在实际定义headers_to_split_on列表时,请使用自己 Notion 文档的标题。

# Load Notion page as a markdownfile filefrom langchain.document_loaders import NotionDirectoryLoader
path='./notion_docs'
loader = NotionDirectoryLoader(path)
docs = loader.load()
md_file=docs[0].page_content
# Let's create groups based on the section headers in our pagefrom langchain.text_splitter import MarkdownHeaderTextSplitter
headers_to_split_on = [
    ("##""Section"),
]
markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(md_file)

分割任务并检查分割结果。用 LangChain 的 RecursiveCharacterTextSplitter,使用一些不同的字符来进行分割。四个默认的检查字符是换行符、双换行符、空格或无空格。也可以选择传入自己的 separators 参数。

将 Notion文档进行分块时,我们还需要定义两个关键超参数——分块大小(chunk size)和分块重叠(chunk overlap)。本例中,分块大小为 64,重叠为 8。随后,我们就可以调用 split_documents 函数将所有文档进行分割。

# Define our text splitter
from langchain.text_splitter import RecursiveCharacterTextSplitter
chunk_size = 64
chunk_overlap = 8
text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap)
all_splits = text_splitter.split_documents(md_header_splits)
all_splits

下图展示了部分分割的 document 对象,其中包含了页面内容和元数据。元数据显示了内容是从哪个章节中提取出来的。

alt

02.存储 Notion 文档

所有文档加载和分割完毕后,就需要存储这些文档块。首先,在 notebook 中直接运行向量数据库 Milvus Lite,随后导入所需的 LangChain 模块——Milvus 和 OpenAI Embeddings。

用 LangChain 的 Milvus 模块为文档块创建 Collection。这个步骤中我们需要传入的参数包括:文档列表、使用的 Embedding 模型、连接参数、以及 Collection 名称(可选)。

from milvus import default_server
default_server.start()
from langchain.vectorstores import Milvus
from langchain.embeddings import OpenAIEmbeddings


vectordb = Milvus.from_documents(documents=all_splits,
    embedding=OpenAIEmbeddings(),
    connection_args={"host""127.0.0.1""port": default_server.listen_port},
    collection_name="EngineeringNotionDoc")

03.查询 Notion 文档

现在可以开始查询文档了。开始前,我们需要从 LangChain 中再导入三个模块:

  • OpenAI:用于访问GPT。

  • SelfQueryRetriever:用于搭建基本的 RAG 应用。

  • Attribute info:用于传入元数据的。

首先,我们定义元数据。随后,需要给自查询检索器提供文档的描述。本例中,描述即为“文档的主要部分”。在我们实例化自查询检索器前,现将 GPT 的温度(Temperature)设置为 0,并赋值给一个名为 llm 的变量。有了 LLM、向量数据库、文档描述和元数据字段后,我们就完成了自查询检索器定义。

from langchain.llms import OpenAI
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo


metadata_fields_info = [
    AttributeInfo(
        name="Section",
        description="Part of the document that the text comes from",
        type="string or list[string]"
    ),
]
document_content_description = "Major sections of the document"


llm = OpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(llm, vectordb, document_content_description, metadata_fields_info, verbose=True)
retriever.get_relevant_documents("What makes a distinguished engineer?")

以下例子中我们提出了一个问题:“一名优秀工程师有哪些品质?”(What makes a distinguished engineer?)

响应如下图所示。我们获得了与提问在语义上最相似的文档片段。但不难发现,其回答也仅仅只是语义上相似,并非完全正确。

alt

本教程介绍了如何加载并解析 Notion 文档,并搭建一个基本的 RAG 应用查询 Notion 文档。我们使用到了 LangChain 作为框架,Milvus 作为向量数据库用于相似性搜索。如果想要进行深入的探索,建议大家调整分块大小和重叠等参数,检查不同的参数值是如何影响查询结果的。

所谓分块(Chunking)是构建检索增强型生成(RAG应用程序中最具挑战性的问题。具体的介绍和操作可参考《在 LangChain 尝试了 N 种可能后,我发现了分块的奥义!》

本文由 mdnice 多平台发布

这篇关于用 LangChain 搭建基于 Notion 文档的 RAG 应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/441414

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、

搭建Kafka+zookeeper集群调度

前言 硬件环境 172.18.0.5        kafkazk1        Kafka+zookeeper                Kafka Broker集群 172.18.0.6        kafkazk2        Kafka+zookeeper                Kafka Broker集群 172.18.0.7        kafkazk3

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联