
Python与Ollama的开发案例
RAG (检索增强生成)是企业 AI 大模型应用落地的主要应用形态之一,特别是在智能问答、报告生成、内容审核、Text2SQL、流程自动化和 AI 编程等领域大规模应用和落地 RAG 架构。
从技术本质来分析,RAG 架构设计是由两部分构成:数据工程和信息抽取。其中数据工程是最重要的部分,数据工程的最重要的工作之一是对文档进行分块(Chunking)。
因为要处理的文档可能会相当大,所以第一步还包括“分块”,就是把一个大文件分成更小的、更容易处理的部分。
这个步骤非常重要,因为它确保文本能够适应嵌入模型的输入大小。
而且,它还能提高信息抽取步骤的效率和准确性,这直接影响到生成回答的质量。
下文我们详细剖析两大问题:
第一、 RAG 架构落地中常用的5种分块技术;
第二、企业 RAG 架构落地分块技术如何选型。
企业 RAG 架构落地,常常使用5种分块技术:固定大小分块、语义分块、递归分块、基于文档结构分块、基于 LLM 分块。
生成文本块最直观和简单的方法就是根据预先设定的字符数、单词数或 tokens,把文本切成大小一致的小段。
因为直接切分可能会打断文本的语义流畅性,所以建议在两个连续的文本块之间保留一些重叠部分(就像上面图中蓝色区域那样)。
这个方法很容易实现。而且,因为所有文本块大小都一样,所以批量处理起来也更简单。
但是,这样做有个大问题。它通常会把句子(或想法)从中间切断。这样一来,重要信息就可能会分散到不同的文本块里。
语义分块方法很简单。
就是根据有意义的单元来切分文档,比如:句子、段落或者主题部分。
然后,为每个部分创建嵌入向量(一种能表示文本意义的数字)。
假设我从第一个部分和它的嵌入向量开始。
输出的结果可能如下:
和固定大小的文本块不同,这种方法保持了语言的自然流畅性,并保留了完整的思想。
因为每个文本块包含的信息更丰富,它提高了检索的准确性,这反过来又使得大语言模型(LLM)生成的回答更加连贯和相关。
一个小问题是,它依赖于一个阈值来确定余弦相似度是否显著下降,这个阈值可能因文档而异。
递归分块方法也很容易理解。
首先,根据文档中的自然分隔符来分块,比如:段落或章节。
然后,如果某个块的大小超过了我们预先设定的块大小限制,就把它再分成更小的块。如果块的大小已经在限制范围内,就不用再分了。
可能的输出结果是这样的:
如上所示:
和固定大小的块相比,这种方法同样保留了语言的自然流畅性,并且保留了完整的语义。
不过,这种方法在实现和计算复杂度上会稍微复杂一些。
基于文档结构分块是一种很直观的方法。
它利用文档本身的结构,比如:标题、章节或段落,来确定分块的边界。
这样做的好处是,它能够保持文档结构的完整性,因为它和文档的逻辑部分是对齐的。
输出的结果可能看起来像这样:
话虽如此,这种方法假设文档有一个清晰的结构,但有时候可能并非如此。
而且,分出来的块长度可能会不一样,有可能超出大模型处理的字数限制。实际落地是会把它和递归分块结合起来使用。
既然每种分块方法都有优点和缺点,那为什么不让大语言模型(LLM)来创建文本块呢?
大语言模型可以被引导生成语义上独立且有意义的文本块。
很明显,这种方法将确保高语义准确性,因为大语言模型具备世界知识,能理解上下文和含义,这超出了上面四种方法中使用的简单启发式方法。
唯一的问题是,这是这里讨论的五种技术中计算量最大的文本块划分技术。
另外,由于大语言模型通常有一个有限的上下文窗口,这也是需要考虑的一点。
总之,每种技术都有它自己的优势和权衡,5种分块技术总结对比如下:
我们实际落地发现,语义分块在很多情况下都效果很好,你在 RAG 应用落地的时候可以首选,但是最好针对你的业务场景进行测试下。
RAG 架构落地过程中最终选择哪种分块技术,将很大程度上取决于你的内容性质、嵌入模型的能力、计算资源等等。