链载Ai

标题: 构建“生产就绪”的企业级RAG应用的6大优化考量【上】|深度探讨 [打印本页]

作者: 链载Ai    时间: 1 小时前
标题: 构建“生产就绪”的企业级RAG应用的6大优化考量【上】|深度探讨


关于RAG应用的一个共识是:你可以在10分钟甚至更短时间内构建一个原型;但是如果你希望它是一个足够健壮、性能卓越,能适用企业知识应用需求与多元数据环境的“生产就绪(Production Ready)”的系统,却是困难的。你可能会面临这些企业级RAG应用的常见挑战:

本文参考一些国内外的实践经验与分享,对构建企业级RAG应用中的一些关键优化考量做总结与解析,希望能够对我们开展实际项目有一定的指导意义(本文仅探讨方案,具体实践后续展开)。

  1. 选择合适的知识块大小
  2. 分离用于检索的块与用于生成的块
  3. 对大文档集知识库做分层检索
  4. 多模态知识的输入输出处理
  5. 考虑高级检索与查询重写
  6. 在投入生产之前对应用作全面评估
    ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">
    ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">


考量一

选择合适的知识块大小


首先是一个相对简单,但容易被忽视的基础参数问题。
无论我们借助LlamaIndex还是LangChain构建RAG应用,在将外部知识特别是文件进行向量化存储时,都会遇到chunk_size这个决定把原始知识拆分成多大块(chunk)的简单参数,而chunk也是后续从向量库中检索上下文知识的基本单位。因此chunk_size在很大程度上会影响到后续的检索与生成质量:


因此,确定最合适的块大小本质上就是取得某种“平衡”。在不牺牲性能的条件下尽可能捕获最重要的知识信息。而在企业级应用场景下,最好的办法就是借助成熟的LLM应用评估(evaluation)框架与测试数据集,来评估不同的chunk_size下的响应质量。包括响应答案与检索出上下文的相关性、响应对于输入问题的有用性、响应的正确率等。具体实现可以借助独立的评估框架RAGAS,或者LlamaIndex中的Evaluation模块,以形成不同的chunk_size下的评估结果,进而作出最优选择。

一个批量评估的过程输出



考量二

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;">分离用于检索的块与用于生成的块

虽然你可以尝试用最佳的chunk_size来试图在检索精准性与语义丰富性之间取得平衡,一劳永逸的解决问题。但企业数据环境的复杂性有时候决定了一个统一的chunk策略很难完全奏效。比如:


因此一种常见的优化策略是:对检索阶段(Retriever)的知识块与生成阶段(Generation)的知识块做分离考虑,即:输入给LLM的知识块不一定总是直接检索出来的top-k知识块。

这里假设,经典RAG应用的检索与生成过程中对知识块的传递如下:
那么考虑如下几种策略,以分离检索与生成阶段的知识块:

1. 从问题扩充到完整的问答对

如果原始知识是大量结构化的问答对,那么非常适合只对问题作向量嵌入。在精确检索到问题以后,再将关联的答案内容加入后一起输入LLM用作生成。此外,这里还会有一些常见的检索前(Pre-Retriever)处理:

ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: var(--articleFontsize);letter-spacing: 0.034em;"/>


2.动态扩充知识块的上下文窗口
对常见的连续文档型知识,在检索到相关知识块后,对其进行内容的扩展,将指定大小窗口内的上下知识块也同时带入LLM。比如,如果设定窗口大小为3,则在检索到这个块后,通过读取块的关系信息或者元数据,获得上下关联的各3个知识块,一起输入给LLM。显然,这种方案可以把每个知识块的粒度相对减小 ,以提高召回的精准性,但同时又能提供足够的生成上下文给LLM。
3. 从知识摘要扩充到原始内容
这种模式下会构建两种类型的知识块,一种用于保存知识摘要,一种则保存了原始知识内容。检索基于知识摘要进行,在命中到相关的摘要块后,通过链接获得关联的一个或者多个知识内容块,并把其作为LLM生成的上下文。这种方案提供了一种在更高层面检索知识的手段,而非直接检索知识。可能更适合原知识内容较为细节,但问题输入则相对概括且单一的场景。

4. 从“小”知识扩充到“大”知识
这是一种多层知识分割与嵌入方案。即对相同的知识内容在多个不同的粒度上(多个Chunk_size)进行分割并嵌入,在不同的语义粒度上提供多层的检索能力,比如在chunk_size为128,512两个粒度上进行分割与嵌入,同时保存大小块之间的关系。在检索到关联的小知识块后,根据关系信息查找到包含更丰富内容的大知识块,并输入给LLM。

上面几种拆分“检索块”与“生成块”的策略虽然在实现方法上各有差异,但基本思想是一致的:用相对小的知识块提升检索的精准度,同时又能扩展到更大的知识块,以保证LLM有足够的上下文用来生成。



考量三

对大文档集知识库做分层检索


如果你只是用笔记本电脑上的一个简单pdf文档来构建经典RAG应用,你可能永远不会有这个问题的困惑。但在企业复杂的知识密集型应用中,你可能会面临几百个不同知识来源与类型的知识文档。虽然在管理与维护上,可以通过多级管理进行简化;但是在向量存储与检索的方法上,如果只是简单依赖于传统的文本分割+top-k检索,那么就会遇到精度不足、知识相互干扰等问题导致效果不佳,而这里最主要的问题仍然是检索阶段。一个重要的方法是实现大文档集下的“分层”过滤与检索。考虑以下三种不同的分层检索策略:

【元数据过滤+向量检索】

这种方案在向量知识库构建时根据文档信息对拆分的每个知识块做元数据标识(比如这里的地区、类型),然后生成向量并存储。那么在检索时的流程变为:

这种方案的好处是简单的借助了向量库的能力,可以快速自动过滤并检索;但缺点是:

【摘要检索 +内容检索】

这种方案就是利用了上文提到的“小块”到“大块”的多层向量方案。对每个文档做摘要信息提取,并在摘要与原始文档两个级别上分别做嵌入与向量存储,并做好两者的关联。检索时的流程为:

这种方案的好处是在两个层次上都可以做语义检索。缺点是:

【多文档AI Agent】

与上面两种不同的是,这是一种基于AI Agent思想的方案。虽然也是一个“两级”的方案,但是并不是通过简单的两级向量来实现分层递归检索,而是一个两级的AI Agent,并利用Agent的思维链模式进行推理。其核心思想是:

所以这不是一个简单的知识检索优化方案,而是一个基于RAG之上的多级Agent方案(Agentic RAG)。其最大的好处是具备了极大的灵活性与扩展性,几乎可以完成任意基于知识的复杂任务。知识既可以是这里向量化的知识,也可以是外部系统的结构化/非结构化知识。其主要优势来自于两点:

当然这种方案的缺点是具有一定的实现复杂性,后面我们也会用专门的文章与实例单独探讨Agentic RAG的应用。

我们将在【下】篇中继续探讨RAG应用的另外三个常见优化考量。












欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5