LlamaIndex 实现 RAG(二)- 文档解析

RAG 中最关键的就是知识库构建,知识库主要的作用就是为大模型提供内企业内部知识或者新的知识。在 RAG 中,知识存储通常是把文档进行拆分为块 (Chunk),并通过 Embedding 模型将文档块转为向量型数据,并将向量数据进行保存,为后续的搜索提供数据。文档通常分为多种类型,比较常见的文档类型包括 Work、PDF、Markdown,对于 Excel 这种表格型文档,也可以转为 Markdown 类型的文档,本文将使用 LlamaIndex 对不同文档进行切分、向量化和并进行搜索。

文档切分

先来看上一篇文章中所切分的 PDF 文档,文档总共13 页,分析一下 LlamaIndex 的切分结果。

    # 读取 "./data" 目录中的数据并加载为文档对象
    documents = SimpleDirectoryReader("./data").load_data()

文件被解析成了 13 个文档,每页转成了一个文档

在这里插入图片描述
PDF 转换代码如下
在这里插入图片描述
LamaIndex 中 Document 都是 Node,对于文字类型的节点,节点类型为 TextNode,对于图片,对应的节点类型为 ImageNode,ImageNode 用于多模态,语意搜索时会检查每个节点的向量,如下图所示。
在这里插入图片描述
接下来,需要将长文档进行切分,要对上文所讲的 13 页进行进一步的切分,并转为向量。下面这一行代码,包含了将文档进行切分,并通过 Embedding Model 转为向量的逻辑。

vector_index = VectorStoreIndex.from_documents(documents, embed_model=ollama_embedding)

Node 切分在 LlamaIndex 中,默认通过 SentenceSplitter 进行切分,切分参数如下1024 Token 进行切分,20 个重叠,重叠可以认为就是个移动的窗口。以下配置为切分的默认配置项:

DEFAULT_CHUNK_SIZE = 1024 # tokens
DEFAULT_CHUNK_OVERLAP = 20 # tokens
DEFAULT_SIMILARITY_TOP_K = 2
DEFAULT_IMAGE_SIMILARITY_TOP_K = 2

从配置项可知,文档是按照 1000 Token进行切分的,1000 个Token 肯定是超过一页了,文档有 13 页,如果按1000 Token 来拆分,最后 Node 也是 13 个。下图中是 LlamaIndex 进行句子切分的类:
在这里插入图片描述
切分完成之后,会通过 Embedding 将 Node 转为向量。
在这里插入图片描述
如果我们想采用更细力度的策略进行拆分呢?在 LlamaIndex 中,可以自定义文档切分方式,例如我们想按 100 Token 进行切分,可以自定义文档切分的策略,chunk_size=100,代码如下:

    vector_index = VectorStoreIndex.from_documents(documents, embed_model=ollama_embedding, 
                                                   transformations=[SentenceSplitter(chunk_size=100, chunk_overlap=20)],)

在这里插入图片描述
ChunkSize 不易偏小,太小有可能获取的上下文数据不完整最终模型无法给出更好的回答。

Word 文档

解析 Word 文档,Word 从处理方式来说和 PDF 相似,只是底层的解析器用到的不一样,从下面代码中可以看到 LlamaIndex 对于不同类型的文档使用的解析器。

        from llama_index.readers.file import (
            DocxReader,
            EpubReader,
            HWPReader,
            ImageReader,
            IPYNBReader,
            MarkdownReader,
            MboxReader,
            PandasCSVReader,
            PandasExcelReader,
            PDFReader,
            PptxReader,
            VideoAudioReader,
        )  # pants: no-infer-dep
        
    default_file_reader_cls: Dict[str, Type[BaseReader]] = {
        ".hwp": HWPReader,
        ".pdf": PDFReader,
        ".docx": DocxReader,
        ".pptx": PptxReader,
        ".ppt": PptxReader,
        ".pptm": PptxReader,
        ".gif": ImageReader,
        ".jpg": ImageReader,
        ".png": ImageReader,
        ".jpeg": ImageReader,
        ".webp": ImageReader,
        ".mp3": VideoAudioReader,
        ".mp4": VideoAudioReader,
        ".csv": PandasCSVReader,
        ".epub": EpubReader,
        ".md": MarkdownReader,
        ".mbox": MboxReader,
        ".ipynb": IPYNBReader,
        ".xls": PandasExcelReader,
        ".xlsx": PandasExcelReader,
    }

Word 解析代码如下:



def get_doc_index():
    '''
    解析 words
    '''
    # 创建 OllamaEmbedding 实例,用于指定嵌入模型和服务的基本 URL
    ollama_embedding = OllamaEmbedding(
        model_name="nomic-embed-text",
        base_url="http://10.91.3.116:11434"
    )

    # 读取 "./data" 目录中的数据并加载为文档对象
    documents = SimpleDirectoryReader(input_files=['./docs/a1.docx']).load_data()


    # 从文档中创建 VectorStoreIndex,并使用 OllamaEmbedding 作为嵌入模型
    vector_index = VectorStoreIndex.from_documents(documents, embed_model=ollama_embedding, 
                                                   transformations=[SentenceSplitter(chunk_size=1000, chunk_overlap=20)],)
    vector_index.set_index_id("vector_index")  # 设置索引 ID
    vector_index.storage_context.persist("./storage")  # 将索引持久化到 "./storage"
    return vector_index

Html 页面

解析 Html 页面,通过 Html 解析器,将 Html 转成 Document,从 Document 转为 Node 代码同 PDF。LlamaIndex 中集成多种解析器,本事使用的是 FireCrawlWebReader,很多网页都是 SPA 实现的,需要 JS 运行才能获取到 HTML 代码,所以需要第三方的 API,也可以自行HeadLess Chrome 去实现。 Html 解析完成之后,需要把文档存下来,从而不需要每次都做一次解析。

代码如下:

# 解析网页保存
def get_webpage_index():

    docstore = SimpleDocumentStore()

    
    firecrawl_reader = FireCrawlWebReader(
        api_key=os.environ.get("FC_API_KEY"),  # Replace with your actual API key from https://www.firecrawl.dev/
        mode="scrape"
    )
    documents = firecrawl_reader.load_data(url="https://www.joinquant.com/help/api/help#name:Stock")

    docstore.add_documents(documents)
    docstore.persist(persist_path="./docstorage/docstore") 
    print(documents)

# 创建网页索引
def load_doc():
    store  = SimpleDocumentStore.from_persist_path("./docstorage/docstore.json")
    doc = [store.get_document("be3bd9b5-7099-4143-807e-ca6e39ba3cb0")]
    return doc

总结

本文对 LlamaIndex 中文档的索引进行了介绍,包括不同文档使用不同解析方式,文档的处理在 RAG 中起到了关键作用,对文档的分块策略也会直接影响到 RAG 的搜索效果,在落地开发中要根据自己的业务场景进行设计。

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
4S店客户管理小程序-毕业设计,基于微信小程序+SSM+MySql开发,源码+数据库+论文答辩+毕业论文+视频演示 社会的发展和科学技术的进步,互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。手机具有便利性,速度快,效率高,成本低等优点。 因此,构建符合自己要求的操作系统是非常有意义的。 本文从管理员、用户的功能要求出发,4S店客户管理系统中的功能模块主要是实现管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理,用户客户端:首页、车展、新闻头条、我的。门店客户端:首页、车展、新闻头条、我的经过认真细致的研究,精心准备和规划,最后测试成功,系统可以正常使用。分析功能调整与4S店客户管理系统实现的实际需求相结合,讨论了微信开发者技术与后台结合java语言和MySQL数据库开发4S店客户管理系统的使用。 关键字:4S店客户管理系统小程序 微信开发者 Java技术 MySQL数据库 软件的功能: 1、开发实现4S店客户管理系统的整个系统程序; 2、管理员服务端;首页、个人中心、用户管理、门店管理、车展管理、汽车品牌管理、新闻头条管理、预约试驾管理、我的收藏管理、系统管理等。 3、用户客户端:首页、车展、新闻头条、我的 4、门店客户端:首页、车展、新闻头条、我的等相应操作; 5、基础数据管理:实现系统基本信息的添加、修改及删除等操作,并且根据需求进行交流信息的查看及回复相应操作。
现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本微信小程序医院挂号预约系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此微信小程序医院挂号预约系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。微信小程序医院挂号预约系统有管理员,用户两个角色。管理员功能有个人中心,用户管理,医生信息管理,医院信息管理,科室信息管理,预约信息管理,预约取消管理,留言板,系统管理。微信小程序用户可以注册登录,查看医院信息,查看医生信息,查看公告资讯,在科室信息里面进行预约,也可以取消预约。微信小程序医院挂号预约系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值