生产环境中的高级RAG技术:架构、工具及权衡因素
生产环境中的RAG技术概述:数据摄取、解析、分块、嵌入生成、向量存储、混合检索、重排序、评估与安全机制,以及各环节的权衡取舍。
来源: **Advanced RAG: Production-Ready Architecture, Technologies, Key Features & Limitations**
检索增强生成将搜索步骤与语言模型相结合。系统会提前对文档进行采集和索引,当有查询出现时便检索出相关内容,再由模型基于这些材料生成答案。不过在实际应用中,RAG很少仅仅是向量数据库加上大语言模型这么简单。真正的系统还会加入结构化文档解析、基于结构的切片处理、密集检索与关键词检索、重排序功能、上下文构建机制以及评估和监控手段。
下文将聚焦于实际系统中广泛使用的工具,而不涉及那些少用的实验性技术。
流程概览
一个实用的先进处理流程始于数据摄取、解析与清洗,接着是分块处理、元数据提取、嵌入向量生成以及索引构建。在查询阶段,则需要实现查询理解、混合检索、结果融合与重排序,随后进行上下文压缩、带引用内容生成,最后是评估与监控。具体的技术组合取决于文档类型、处理规模、延迟要求、隐私规范、预算以及质量标准。
数据摄取
本地文件。利用Python的pathlib、PyPDF、python-docx、openpyxl和pandas等库,可以低成本地处理PDF、Word文档、电子表格、CSV文件以及纯文本,且易于集成到批处理任务中。不过缺点是每种格式都需要对应的解析器,扫描版或结构复杂的PDF需要专门的提取工具,而大规模处理则要求并行处理与增量处理机制。
对象存储。Amazon S3、Google Cloud Storage和Azure Blob Storage能为大量数据集提供持久且可扩展的存储空间,同时非常适合与异步抓取技术结合使用。用户需支付云平台搭建费、访问控制实施成本,以及随数据规模增长而上升的存储和传输费用。
网页与API数据源。requests或httpx、BeautifulSoup、Playwright和Firecrawl等工具通过抓取网站、API及动态页面来保持知识库的更新。不过网站结构可能会发生变化,内容中JavaScript占比过高的页面需要浏览器自动化处理,而爬虫技术则可能面临速率限制、重复内容以及内容质量不均等问题。
解析与提取
非结构化处理能够支持PDF、Word、HTML、PowerPoint、图片等多种格式,可提取标题、段落和表格等元素,因此是非常通用的处理方式。不过其速度低于简单的文本提取方法,对于结构复杂的文档仍可能需要定制化处理。
PyMuPDF在从基于文本的PDF中提取文字和元数据方面速度很快,且易于集成到Python代码中。但它并非完整的文档理解系统,扫描文件需要先进行OCR处理,而复杂的布局或表格则需额外处理。
Apache Tika支持多种格式,并具备从混合文档集中提取文字和元数据的成熟功能。不过它在处理现代布局理解方面的能力较弱,因此复杂的视觉布局需要借助其他工具。
OCR与基于视觉的提取
Tesseract 是开源软件,可在本地运行,对普通印刷文本的识别效果较好。手写文字及复杂排版会降低识别精度,而质量较差的扫描文档还需进行预处理。
PaddleOCR 提供了强大的文本检测与识别功能,支持多种语言,非常适合处理扫描文档并进行结构化数据提取。不过复杂的文档可能仍需后续的排版处理,且部署时可能需要额外的模型依赖项。
视觉语言模型,如 GPT-4 级别的模型、Gemini 以及 Qwen-VL 系列,能够理解文本、图像、图表和页面布局,当仅使用 OCR 无法获取视觉上下文时这类模型能提供帮助,同时还能实现多模态 RAG 应用。不过它们的成本高于传统 OCR 工具,响应速度较慢,输出结果具有不确定性,需进行验证。
分块处理
分块方式决定了哪些内容会成为可检索的单元。不良的分块方式会将相关信息分开,或将无关内容混在一起。
- 递归字符分割(LangChain的RecursiveCharacterTextSplitter)是一种可靠的基准方法,它会尽量遵循段落和句子的边界,且易于调整。该方法基于语法而非语义,固定的分块大小并不适用于所有文档。
- 基于令牌的分割则是按照模型令牌的大小来划分分块,这有助于解决上下文窗口的限制问题。不过令牌边界并不一定与语义边界重合。
- 语义分块则通过相似度来识别主题变化,因此连贯的思想能比固定大小的分块方式更好地保持在一起。但这种方法需要更多的计算资源,依赖嵌入向量,还需用户自行设定阈值。
元数据
常见的字段包括文档ID、文件名、页码、章节、作者、时间戳、文档类型、租户或用户信息、访问权限、源URL以及版本号。优质的元数据能够在检索之前或检索过程中实现过滤,为引用和访问控制提供支持,并提升检索精度。反之,劣质的元数据会直接降低检索质量,而且在不同来源的混合环境中,元数据架构也更难维护。
嵌入向量
嵌入向量可将文本转化为能够体现其含义的向量。
- OpenAI嵌入向量具有管理完善、质量较高且调用简单等优点,通用检索性能优异。但其缺点在于API费用较高、存在对供应商的依赖,而且将数据传输到外部可能不适合敏感环境。
向量数据库
- pgvector 为 PostgreSQL 添加了向量搜索功能,可将关系数据、元数据与向量集中存储在一起,如果应用已使用 Postgres,则非常合适。对于规模极大的向量处理任务,可能需要专门的系统,且在数据量极大时扩展会变得更为复杂。
- Pinecone 是一种托管型向量数据库,无需进行基础设施配置即可实现扩展,并具备适合生产环境的过滤功能。用户需为该服务付费,依赖供应商,同时会失去一定的控制权。
- Qdrant 提供开源版本和云服务形式,对元数据的过滤效果良好,支持密集检索与混合检索方式,适合自托管的 RAG 系统。不过自托管意味着需要处理运营相关的工作,而分布式架构则要求进行周密的容量规划。
检索
密集向量搜索将向量数据库与嵌入模型相结合,从而找到语义上相似的内容,相比关键词更能处理同义表达。但它可能无法识别精确的标识符、稀有术语、代码和数字,且其效果在很大程度上取决于嵌入模型及文本分块方式。
BM25是一种强大的词汇法,非常适合处理精确的术语、名称、ID以及技术关键词,而且简单易理解。但它无法把握语义相似性,因此同义词和同义表达容易被忽略。
混合搜索通常会将BM25与密集向量搜索结合使用,通过结合词汇精度与语义覆盖能力,为不同类型的查询提供更可靠的结果。相比单一检索器,它需要进行分数或排名融合,并且需要更多的基础设施与调优工作。
查询转换
- 查询重写可将对话式或模糊的输入转换为便于检索的形式,从而有助于后续提问。糟糕的重写方式会丢失关键信息,还会增加大语言模型的延迟与成本。
- 多查询检索让模型生成多个替代查询并分别进行检索,以提高召回率并覆盖不同的表达方式。但这意味着需要更多的检索调用,进而增加延迟与成本,有时还会出现无关搜索结果。
- HyDE(假设文档嵌入)会生成一个虚构的答案并将其进行嵌入以便检索,这有助于处理那些查询词汇与文档词汇差异较大的难题。该方法需要额外调用一次大语言模型,且质量不佳的假设文档可能会影响检索结果。
融合
互斥排名融合会将多个检索器的排名结果合并起来。该方法简单可靠,适用于密集向量与BM25混合的场景,且无需不同系统的得分具备可比性。虽然增加了排名阶段,但仍需调整相关参数。
加权得分融合会为密集向量、稀疏向量或其他类型信号赋予不同的权重,适用于各检索器优势不同的情况。得分需要先进行标准化处理,而权重则取决于具体的工作负载。
重排
第一阶段的检索应以提升召回率为目标,随后通过重排在更小的候选集上提高精确度。
交叉编码器重排模型,如BGE Reranker、Cohere Rerank和Jina Reranker,会共同对每组查询-文档对进行评分,通常比单纯的嵌入相似度得分更高,并且在混合检索后表现优异。不过这类模型的成本高于向量搜索,因此仅应在有限的候选列表上使用。
大语言模型重排则让模型来判断相关性,能够处理复杂的评估标准,但速度较慢、对计算资源消耗大,且不如专用重排模型那样具有确定性。
最大边际相关性(MMR)会在相关性与多样性之间取得平衡,当前k个结果几乎为相同内容时它会剔除重复项。该方法会引入多样性参数,但多样性过高反而可能导致那些恰好重复的相关证据被排除。
上下文压缩
提取式压缩仅保留相关句子或片段,从而节省标记数量并保持原文表述,但可能会删去理解段落所需的上下文。基于大语言模型的压缩会对获取的内容进行总结,能够大幅缩减大型文档的上下文量,但会带来额外的成本和延迟,还存在压缩过程丢失信息或产生幻觉的风险。
生成
常见的实际应用模型包括OpenAI模型、Anthropic Claude、Google Gemini、Meta Llama和Qwen。这些模型具备强大的推理能力,可根据成本、延迟和任务难度来选择合适的模型。使用API模型会有成本支出且依赖供应商,开源模型则需要相应的基础设施,而规模较大的模型则会增加延迟和推理成本。
框架
LangChain 拥有庞大的生态系统,包括加载器、检索工具、向量存储集成以及模型接口,有助于快速构建处理流程。不过抽象层可能会变得复杂,而生产系统通常更适合采用简洁明确的请求路径。
LlamaIndex 的重点在于数据导入、索引构建与检索,为以文档为中心的 RAG 模型提供了实用的抽象层。但它会增加框架的复杂性,一些高级系统最终会转而使用更低级别的 SDK。
LangGraph 适用于需要状态管理、分支处理以及智能代理的工作流,支持迭代式检索和工具执行。它的功能比简单处理流程更为复杂,因此需要妥善处理状态管理和故障处理问题。
高级模式
- 校正型RAG会评估检索到的上下文,能够在检测到结果不佳时触发进一步检索并启用备用搜索方式,但会带来延迟和复杂度上升的问题。
- 自适应RAG允许模型自行决定何时进行检索以及如何判断检索结果。它能避免不必要的检索,但控制逻辑更为复杂,需要经过仔细评估并依赖模型支持。
- 智能代理型RAG通过代理来规划搜索流程、调用工具、迭代检索并验证结果,可处理涉及多个来源的复杂多步骤问题。不过其延迟和成本更高,故障概率更大,调试也更为困难。
结构化数据
Text-to-SQL能让模型将自然语言问题转换为针对结构化数据库的查询语句,非常适合对最新数据进行分析。不过生成的SQL语句可能存在错误或不安全之处,因此需要进行模式检索、验证以及访问控制。
混合文本与SQL RAG结合向量或关键词检索处理非结构化知识,同时运用SQL处理结构化数据,可在同一设计中涵盖PDF、文档、CSV文件及数据库。这种架构需要在不同检索模式之间进行切换,从而增加测试难度与安全风险。
评估
实际应用系统需要在检索层面和生成层面都进行评估。
检索指标(Recall@K、Precision@K、MRR、NDCG及命中率)用于判断检索系统是否找到了正确的证据;生成指标(忠实度、答案相关性、答案正确性、上下文相关性、上下文精确度及上下文召回率)则用于评估模型是否正确使用了这些证据。
Ragas 是专为RAG评估设计的,涵盖多个层级,适用于回归测试。其许多指标依赖于大型语言模型或嵌入模型作为评判标准,因此分数无法完全替代人工审核,且这些评判模型可能存在偏差。人工评估最能确保领域特定的质量标准,能够发现自动化指标遗漏的问题,但成本高昂、速度较慢,且需要统一的评估准则。
可观测性
LangSmith能够追踪调用链、检索请求、提示词及输出结果,帮助调试处理流程并对比不同实验效果。它是一个需要考虑成本与隐私问题的托管平台。Langfuse提供追踪、提示词管理及指标功能,支持开源自托管或云部署形式,不过自托管需由用户自行负责,并且需要相应的监控工具。OpenTelemetry是用于追踪、指标收集和日志管理的开放标准,可将RAG集成到现有基础设施中,但相比现成平台需要更多的技术工作。
缓存与性能
语义缓存会重用针对相似查询的响应,从而减少对大语言模型的重复调用、降低延迟并节省成本。但一旦数据发生变化,相似问题可能需要不同的答案,而实现缓存失效又十分困难。嵌入缓存则可以避免对重复出现的文本重新计算向量,虽然简单有效,但每当嵌入模型更新时就必须使其失效。异步与并行检索能够同时运行多个独立的检索器,从而缩短端到端的延迟,不过这会增加错误处理的复杂性,同时后端系统也需要承受并发负载。
安全性
- 提示注入。检索到的文档可能包含旨在控制模型的指令。
- 访问控制的检索。用户只能获取其有权限查看的文档。
没有任何单一措施能够解决安全问题,必须在数据摄入、存储、检索、授权、工具执行及内容生成等各个环节都设置相应的控制措施。
部署
常见的技术组件包括:用于API层的FastAPI、用于打包的Docker、用于大规模集群管理的Kubernetes、用于缓存的是Redis、用于存储关系型元数据的是PostgreSQL、用于对象存储的则是S3、GCS或Azure Blob、用于监控指标的是Prometheus、用于制作仪表板的则是Grafana、用于追踪的是OpenTelemetry,而用于实验记录的则是MLflow。这样的目标是构建一个可复现、可观测、可扩展且易于维护的RAG系统,而非仅在笔记本中显示准确结果的系统。
实用的组合方案
一个强大的通用设计可以保持相对简洁。文档首先经过非结构化处理、PyMuPDF或PaddleOCR处理,接着进行基于结构的或递归的分块处理,随后使用OpenAI、BGE、E5或Cohere生成的嵌入向量,再通过pgvector、Qdrant或Pinecone进行存储。检索过程结合了BM25与密集搜索,并融入RRF算法,通过交叉编码器重新排序,最后压缩后传递给大语言模型,同时附上相关引用作为依据。Ragas和人工审核用于评估质量,而LangSmith、Langfuse或OpenTelemetry则负责监控运行状态。
并非每个系统都需要所有组件。小型内部知识库可能仅需PostgreSQL、pgvector、嵌入向量以及一个大语言模型即可满足需求。只有在评估显示简单设计存在不足时,才需要添加混合检索、重排序、智能代理循环、图检索和多模态处理功能。
选择合适的工具
- 简单PDF文本:PyMuPDF。混合文档类型:非结构化数据。扫描图像:PaddleOCR。视觉上复杂的页面:视觉语言模型。
- 基础分块方式:递归分割器。语义边界划分:基于语义的分块方法。上下文关联处理:父子节点检索机制。
- 托管型嵌入模型:OpenAI或Cohere。开源嵌入模型:BGE或E5。
- 已集成在PostgreSQL中的方案:pgvector。托管型向量存储服务:Pinecone。自托管方案:Qdrant。原型系统:Chroma或FAISS。
- 基于语义的搜索方式:密集向量检索。精确关键词匹配:BM25算法。高覆盖率方案:混合搜索模型。排名合并方法:RRF算法。提升精确度的手段:交叉编码器重排器。减少重复结果的技巧:MMR算法。
- 复杂的多步骤查询处理:代理式RAG系统。实体关系分析:图结构RAG模型。表格与数据库处理:文本转SQL功能。
从小规模开始
最严重的架构错误是将大语言模型视为整个系统的核心。质量体现在从信息检索、上下文构建到内容生成的全流程,进而通过评估与监控来保障。再大的模型也无法可靠地弥补缺失的信息。
一个有效的改进循环包括:设定基准、进行评估、找出问题环节、修改某个组件、重新评估、部署并监控。对于大多数生产系统,应先从可靠的解析与结构化分块、优质的嵌入模型、混合检索方式以及重排器入手,之后再加入基于事实的内容生成与评估功能。只有在可量化的需求足以证明其成本与复杂度合理时,才引入智能检索、Graph RAG、多模态处理流程、纠错机制或微调技术。
优秀的RAG工程并非在于收集所有技术,而在于选择最简洁的架构,以满足在质量、延迟、成本、安全性和可维护性方面的目标。