生产级RAG系统架构精解:从数据处理到智能路由的实战指南
今年以来,我保持着每日阅读的习惯,涵盖了学术论文、行业报告以及国内外的技术文章。虽然大部分内容可能价值有限,但每周总能发现一两篇颇具启发性的文章,例如今天要讨论的这篇:《How I Won the Enterprise RAG Challenge》。
通读全文后,我认为其内容相当出色。以下是我结合自身实践经验与文章内容的一些总结与思考。
架构全景图
首先,让我们审视该系统的核心架构设计:

一个优秀的RAG系统实际上是一套精密的工作流程,更是一套智能决策系统。它在核心的“检索-生成”链条之上,增加了多个“路由器”和“优化器”模块(对于其必要性,我个人持一定的审视态度):
- 路由决策: 系统首先需要判断当前问题应该导向哪个最合适的数据源或处理路径。
- 检索优化: 在初步获取相关文档片段后,系统需要进一步筛选、排序和精炼,以找出最切题的信息。
- 生成定制: 最后,系统需要依据问题的具体类型和上下文,采用最具针对性的策略来生成最终答案。
接下来,我们将沿用Ilya文章中提出的“RAG洋葱模型”作为分析框架,从最外层的基础设施开始,逐步深入到核心的智能决策模块:

讨论至此,我们不得不再次回归到最基础的环节:数据准备。
任何RAG系统的最终效果,都高度依赖于输入数据的质量。因此,前文将核心仅仅归于检索和生成链条的观点,我本身便抱有疑问。其内在逻辑很清晰:稍微复杂一些的AI系统,其逻辑是相通的——数据工程的质量直接影响提示词工程的效果,而数据处理的质量又决定了数据工程的上限。所以,如果RAG前期数据处理不到位,无论后期如何进行优化和补足,整体效果都难以达到理想状态。
因此,将非结构化的原始文档(例如WORD、PDF文件)转化为干净、规整且易于检索的文本块,是至关重要的一步……
一、文档解析
文档解析是整个RAG流程的起点,也是最容易出现问题的环节。Ilya尝试了大约二十种不同的解析器后,得出了一个关键结论:不存在一种能够完美无损地解析所有PDF文档的通用解析器。
他遇到了各种各样的棘手难题:有些表格在扫描时被旋转了90度,导致解析后的文字完全混乱;有些图表由文本层和图片层混合构成,难以完整提取;甚至部分报告文件存在字体编码问题,视觉显示正常但复制出来的却是无意义的乱码符号。更极端的情况是,某些文档中的文本竟然使用了凯撒加密,需要特定的解码方式才能正确读取。

最终,他选择以Docling作为基础解析器。 为了应对某些复杂的解析场景,他不得不深入该解析器的源代码进行定制化修改,以确保其能够输出包含丰富元数据的JSON格式,进而生成高质量的Markdown和HTML文档。
这个过程揭示了一个必须正视的现实:在真实的RAG项目中,数据预处理往往消耗超过一半的总工作量,并且需要深厚的领域知识和工程技巧。
一个比较有趣的细节是,由于当时比赛时间紧张,他还利用了GPU来加速解析过程,租用了搭载RTX 4090显卡的云服务器。最终,一万多页共计100份年报的解析任务耗时约40分钟,这充分展现了工程化思维在效率提升上的价值。
然而,在实际的工作场景中,我们通常不建议采用这种“特殊操作”。首先,不建议轻易修改第三方解析器的核心源码,这会给未来的维护和升级带来巨大挑战。其次,若非必要,也不建议过度追求极致的解析速度,因为项目时间往往相对充裕,人为增加技术复杂度会提升系统的移交和协作成本。
在真实的文档处理过程中,你一定会遇到各种意想不到的“奇葩”问题。这里没有捷径可走,唯一的方法就是“逢山开路,遇水搭桥”,一个个地解决这些小问题。 每个独立的问题通常并不复杂,很少会出现耗时两天都无法解决的情况。这里的关键在于尽早发现并暴露问题,而不是掩盖问题。
二、向量化
文档被成功解析后,需要被切割成更小的“块”(chunks)才能存入向量数据库。此处的分块策略变得尤为关键:
为了在检索精度和上下文完整性之间取得平衡,Ilya采用了递归分块法,设置了300个token的块大小,并辅以50个token的重叠区域。这种策略确保了语义单元的完整性,同时避免了因单个块过大而导致关键信息的相似度被稀释的问题。
在系统设计上,他进行了长远规划:为每一份独立的文档(例如每家公司的年报)建立专属的向量数据库。这背后是出于效率的考量:当用户的问题明确指向某一家特定公司时,仅在对应的单个向量库中进行搜索,其准确性和速度都远高于在一个混合了所有公司数据的庞大向量库中进行全局搜索。
这一设计实际上引入了“路由”概念的雏形:在正式执行检索之前,先确定搜索的目标范围。类似的思维策略在国内也有应用,例如树形索引结构也能很好地保持不同语义集合的独立性:

三、检索与重排
检索是RAG系统中的“R”(Retrieval),是整个系统的脉络所在,也是检验前期数据准备工作好坏的核心标准。如果检索器无法找到正确答案,那么后续的所有步骤都将失去意义。
从理论上讲,结合语义搜索(基于向量相似度)和关键词搜索(如BM25)的混合检索策略,应当能够提升检索效果。
但Ilya的实践经验表明,在未对用户查询进行深度优化的情况下,简单的混合检索有时甚至会导致性能下降。这说明,先进的技术需要正确的使用方式与之匹配,否则可能适得其反。
根据过往的经验,这里一个比较实用的技巧是查询重写。事实上,一个健壮的系统应该拥有一份自己预期的问题准入清单,或者说一个简单的“意图识别”模块。如果你没有这样一份清单,说明系统设计可能不够健壮,即使用户重新措辞提问,也未必能检索出正确答案。
检索完成后会得到一个候选文本列表,接下来便是重排技巧的用武之地。Ilya的做法是:
- 首先通过向量检索初步召回30个相关的文本块。
- 利用这些文本块的元数据,定位到它们所属的原始页面。
- 将“用户问题 + 页面完整文本”交给LLM,要求LLM根据该页面内容对回答问题的帮助程度进行打分(0-1分)。
- 将LLM给出的分数与原始的向量搜索相似度分数进行加权融合,最终筛选出最相关的10个页面。

为了加速重排过程,Ilya让LLM一次同时对三个页面进行评分并返回三个分数。这样,邻近的文本可以互相作为参照,有助于提高评分的一致性和整体处理效率。最终,系统结合向量相似度分数和LLM的评分来计算修正后的相关度,例如设定向量权重为0.3,LLM权重为0.7。
这种方法的好处显而易见:它以一种相对低廉的成本(据称每次查询低于1美分),极大地提升了输入给生成模型的上下文材料质量。只要前期数据质量过硬,经过这样筛选后的上下文,必然能引导模型输出更高质量的答案。
然而,只有在实际采用这种重排策略时,你才会真切地感受到企业决策者(如“老板”)对这部分额外token消耗的在意程度。在很多实际场景中,效果和成本往往难以兼顾,除非在更前端的数据工程层面投入更大的功夫。换句话说:
越是复杂和精细的数据工程处理,往往能支撑起更简化、高效的AI应用工程,最终以更低的成本换取更优的前端用户体验。
四、路由与生成
这一部分是其方法论——RAG洋葱模型最核心的体现,需要大家特别留意。这也是许多大型AI项目背后的架构设计思路,也是我推荐这篇文章的主要原因——它已经勾勒出了这类复杂系统的雏形。这里的核心理念是:
通过智能路由,让每一个问题都能被导向最合适的处理路径。
路由是简化问题复杂性、提升系统效率的最有效手段之一。Ilya的系统中设计了两个关键的路由器:
1. 数据库路由: 根据问题中出现的公司名称,直接将查询路由到该公司对应的专属向量数据库。这个策略看似简单(甚至可以用正则表达式实现),却能将搜索范围从100份文档急剧缩小至1份,带来了检索性能和答案精度的双重显著提升。事实上,前文提到的按页面建立索引的思路也与此异曲同工:

2. 提示词路由: 比赛要求答案必须遵循严格的格式(例如纯数字、布尔值、特定字符串等)。Ilya没有将所有格式规则塞进一个庞大而复杂的通用提示词中,而是为每一种答案类型设计了专用的、高度定制化的提示词模板。系统通过简单的逻辑判断(如if…else)来识别问题所属的类型,然后动态选择并注入最合适的提示词,确保LLM能够清晰无误地理解并遵守特定类型的输出要求。

需要特别指出的是:这里实现路由判断,既可以使用基于规则的引擎,也可以使用一个轻量级模型来完成,两者在效果上并无绝对高下之分,选择取决于具体场景。
当然,上述路由机制主要解决的是单一领域内的问题。如果遇到需要跨领域或跨文档对比的复合型问题,处理起来就更为复杂。例如,对于需要比较多家公司数据的问题,系统引入了第三重路由逻辑:
- 首先,识别出这是一个复合型比较问题。
- 使用LLM将其拆解为多个独立的子问题(例如“A公司的营收是多少?”和“B公司的营收是多少?”)。
- 每个子问题独立地走完之前描述的标准RAG流程(检索、重排等)。
- 最后,将所有子问题的答案汇总起来,交由LLM进行整合,生成最终的对比答案。

这里值得注意的是,正如我之前强调的核心一点:能够进行如此精细设计的前提是,系统所面对的问题类型在相当程度上是预设和可穷举的,应用场景是经过充分分析和定义的。
在经过上述一系列系统而复杂的操作之后,知识从原始PDF文档流入了知识库,又从知识库经由精心准备的提示词,进入了最后一步——模型生成。在这一环节,Ilya综合运用了多项业界公认的最佳实践:
1. 精细化的思维链引导: 不仅仅是简单地要求模型“一步一步思考”,而是通过结构化的提示词为LLM规划出一条清晰的推理路径,特别强调要求模型对比问题中提及的指标与上下文中出现的指标是否严格一致。这是有效防止LLM“张冠李戴”、降低事实性“幻觉”的关键手段。例如,当上下文只提供了“扣折旧后的设备净值”时,模型能够通过推理分析出这并非问题所问的“研发设备成本”,从而果断地回答“N/A”(不适用/信息缺失)。
2. 强制结构化输出:
强制要求LLM以指定的JSON格式输出答案,确保了输出结果的可解析性和稳定性。输出中同时包含 step_by_step_analysis(逐步推理分析)和 final_answer(最终答案)等字段,既保证了整个推理过程的透明与可控,又便于程序化地提取最终结果。
3. 提示词的模块化管理: Ilya采用模块化方式组织和管理提示词。每个完整的提示词由多个可复用的模块“拼装”而成,例如系统指令模块、输出格式定义模块、示例问答对模块等。这种设计使得开发者可以像搭积木一样灵活地组合不同的提示词配置,同时有效控制了单个提示词的长度,减轻了手动维护的负担。
4. 深入的指令打磨与业务理解: 这是最耗费心力但也最为重要的一环。Ilya深入研究了比赛题目生成器的内在逻辑以及企业年报的业务细节,将各种边界情况(例如不同货币单位的转换、同一职位的不同表述同义词、数值的单位换算等)明确地写入提示词的指令中。这告诉我们:一个RAG系统所能达到的上限,在很大程度上取决于开发者对业务本身的理解深度。 (附注:上述超出预设边界的情况,偶尔也可能通过微调等方式“内化”进模型本身,这本身也属于模型可观测性和持续优化的一部分。)
至此,其“RAG洋葱模型”从数据处理到模型生成的主体部分便介绍完毕。通常,当核心功能实现后,话题又会回归到成本与性能的权衡上。但性能的瓶颈究竟在哪里?如何优化?这又需要我们回到最根本的系统设计哲学。
五、AI Min的理念与系统哲学
当时的比赛于2025年3月举行,大语言模型的迭代速度尚未像如今这般迅猛。但非常值得注意的一点是:在比赛中,Ilya构建的系统在开源模型和商用模型上都表现出了优异的性能! 例如,使用Llama 3.3-70B这样的开源模型,其效果几乎可以媲美OpenAI的GPT-4o-mini;甚至小规模的Llama 8B模型,也超越了80%的参赛队伍。 这些结果表明,无需盲目追求参数量最大的模型,只要对RAG管道的每一个环节进行细致的优化,即使是较小的模型也能取得接近最优的性能表现。
这套方案之所以成功,在于其拥有一个完整的测试验证集和一个可灵活配置的系统。这使得Ilya能够客观、量化地评估每一次改进(例如改进表格序列化方式)带来的实际效果增量,避免了被主观直觉误导。这种数据驱动的迭代方法是工程化思维的核心体现。
说到这里,就需要引出我们在技术选型时常说的 AI Max 与 AI Min 理念。只要采用了 AI Min 的技术架构思路——即不重度依赖单一超大模型的“蛮力”,而是通过精巧的系统设计来弥补模型能力的不足——虽然整个系统的复杂度会有所上升,但其整体的可控性以及对供应商的外部依赖会大大降低,长期来看更具优势。
回顾整个获胜方案,我们可以总结出几条构建生产级RAG系统的核心哲学:
1. 大模型不是银弹,系统化优化才能带来全局进步: 胜利并非源于某一项孤立的技术突破,而是通过解析、检索、路由、生成等每一个环节的持续迭代和精细打磨达成的。每一个环节微小的改进积累起来,便形成了压倒性的整体优势。
2. 细节决定成败,拦路虎是一个个具体的卡点: 从PDF解析中遇到的字体编码难题,到提示词里关于数值单位的明确指令,这些看似微不足道的细节,共同决定了系统的最终性能。Ilya的经历证明,在RAG系统中,那些最耗时、最不起眼的“脏活累活”,往往才是成功的关键所在。
3. 架构是系统的灵魂: 一个优秀的RAG架构应该是可决策、可路由、可配置的。如同“洋葱模型”所揭示的,从基础的线性管道演进到拥有智能路由和优化模块的高级架构,是系统能力实现跃迁的必经之路。冠军系统的架构设计体现了深厚的技术功底和前瞻性的思考。
4. 评估驱动迭代: 拥有完整的验证集和可灵活配置的AB测试能力,能够客观量化每一次改进的实际效果,这是避免被直觉误导、实现科学、持续优化的关键基础。
结语
Ilya这篇关于RAG系统的文章,我建议所有相关领域的从业者都读一读,它的复杂度和完整性已经非常接近我所接触过的最复杂的AI工程实践。
文章清晰地展示了构建一流的、可用于生产环境的RAG系统是一项复杂的系统工程。它要求我们不仅仅是会调用API的工程师,更要成为深入理解业务细节的专家。
我认为这篇文章最有价值的地方,在于展示了一种关于AI架构的可控性的思考:比起盲目追求一个看似万能但不可控的超大模型,更值得投入精力的是优化整个技术组合与工作流,设计出稳定可控的解决路径。即使模型本身并不完美,只要在工作流(系统规则)上做足了功课,同样能够解决复杂的现实难题。
最后,RAG的真正魔力蕴藏在无数的细节之中。希望本文的梳理与总结,能对各位读者有所启发!