RAG------Retrieval Augmented Generation检索增强生成,是一种提升LLM生成内容的质量的方式。原理很简单,通过将"知识"持久化到某一个数据源中比如向量数据库,调用LLM生成时检索相关的知识一起加入到提示词中,提高生成结果的质量。
虽然原理比较简单,但是实际落地在工程化上,有多个步骤需要考量,也有许多细节需要敲定。本文介绍RAG系统工程化相关内容。
RAG数学
LLM的公式:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> P θ ( x ) = ∏ i = 1 n p θ ( x i ∣ p r o m p t , x < i ) P_{\theta}(\mathbf{x})=\prod_{i=1}^{n} p_{\theta} \left( x_{i} \mid \mathsf{prompt},\mathbf{x}_{<i} \right) </math>Pθ(x)=i=1∏npθ(xi∣prompt,x<i)
这是一个自回归的概率模型,基于现有的大数据集拟合规则得到一条临摹的式子。输入数据是式子的自变量,得到的结果是因变量。自回归的概率模型始终存在幻觉,RAG的本质就是在优化LLM的自回归条件,通过检索合适的材料构建prompt enging(检索的方式有多种,sql、搜素引擎、向量数据库、文件等等)。通过改变条件影响分布,用新知识与关联的知识对抗幻觉。
RAG应用类型
-
原生RAG,基于简单文档分割并存入单一的向量数据库。每一次请求进入找到结果并返回。应用:简单问答机器人。
-
多阶段RAG,多阶段RAG会有更多的处理步骤来得到最终结果。应用:需要高精度检索的应用------金融年报、医学文献。
-
混合RAG,更加庞大的RAG,用了多种方式增强了检索能力与增加结果的准确度,适配了更加复杂的环境,甚至可以支持多模态RAG。
- Text2SQL RAG。将自然语言查询转换为SQL语句,用于数据库交互。将用户自然语言处理为标准化的查询,进而查询数据库中的内容。
- KG RAG 知识图谱增强RAG。用ER关系统筹数据,得到知识图谱,基于知识图谱辅助检索。
- 基于Semantic Search语义搜索核心的RAG
工程化

-
知识处理
-
数据上传,RAG数据入口。入口的核心就两点,一是如何触发,二是数据结构性处理------如果是pdf文件,是直接解析成结构性的,还是调用LLM总结得到Transform后的数据。
-
数据压缩与分块,压缩与分块是标准化,便于业务检索。需要根据数据性质与业务性质决定压缩与分块的策略,相同的数据集用不同的分块策略形成的效果可能是天差地别的。
- 如果是在做编码工具相关rag,比如针对golang项目的代码文件做rag,数据分块最好是按文件,因为golang的代码规范中文件是一个相对独立的实体。
- 如果是针对金融年报方面的rag,注重专业术语表达,那么使用200个字的切片不如20个字的切片。
- 如果是需要对超长文本(这个性质也适用于视频)的检索且检索的时候不可以切割的,可以将超长文本总结,只对总结的结果索引,找到后,根据策略决定是否引入超长文本。
- 分块的原子性、关联性、有效性应该如何权衡是需要仔细考虑的。因为一句话切开它就不完整了,业务视角下,信息的最小检索单位是如何?确定了最小的原子性,怎么取舍保留住原子性的关联与依赖?又如何取舍数据分块后对于构建结果是比较有效的?
-
embedding------数据向量化,将数据分块调用LLM转化为向量,这些向量就是RAG检索的核心数据。
-
将人类可理解的数据转化为目标LLM可理解的数据(携带着LLM的世界观),后续检索是用数学概念计算向量距离得到想要的向量------也就是数据。
-
所以,向量化的过程目标LLM的选取很重要,决定了向量化后的数据质量。需要评估数据集与LLM的训练倾向,选择合适的LLM。
在硅谷,生意通常有三种类型:第一种是降维打击,比如特斯拉用电动汽车替代传统燃油车;第二种是"他们挖金子,我卖水",即通过提供基础设施支持来盈利;第三种是差异化竞争,即在相似产品中定位不同市场。例如,Anthropic 专注于安全;OpenAI 则更侧重于帮助用户解决问题,而且它不喜欢说"不",不愿意承认自己不懂;Gemini 的模型则表现得比较不稳定,其目标和定位不太明确。
Claude 注重安全性,表现得像一个 60 岁的老者,谨慎且不敢冒险;Gemini 则像是一个充满惊喜的黄毛青年,偶尔给你带来意外的回答;而 GPT 更像是一个大学生,时常表现出天真与自信,即便犯错也不愿承认。
------尹一峰(news.qq.com/rain/a/2025...
-
如果是对golang代码执行embedding,直接对代码文件向量化不如多调用一个领域模型理解了代码功能后,再将结果embedding。因为LLM的训练集(世界观)中,自然语言的语料多过代码语言,构建出来的向量会倾向自然语言的规则,在匹配的时候可以命中相似的规则。
-
-
索引设计,类比数据库索引,是检索的关键。索引与数据结构共生,自然又到了选择的时候:哈希map结构(hash)、tree树结构、graph图结构、ivf倒排索引。
- 索引内容选择。常规流程中,得到向量化是数据后,会调用工具库的距离计算方法(如计算欧几里得距离)运算得到索引对象,用这个对象就是rag的_id。整个过程的原理就是,将向量化后的数据内容,映射到一个统一的坐标系下,标准化方便后续编排索引的结构。核心在于,如何选择距离计算公式?余弦距离、欧式距离、三角不等式等,有各自面向数据集的场景。使用余弦距离就只考虑方向,适合在推荐系统方面的应用,比如电影推荐。
- 索引的数据结构:hash结构查找快,但是准确性一般;tree结构在高维数据表现差;图结构对高维数据非常友好,且相对省内存但是难以处理模糊查询与构建复杂。ivf则构建过程十分漫长。
- 行业的最佳实践是遇事不决用图结构,首选 Hierarchical Navigable Small World------HNSW算法。
- 另外一种大型的检索结构是类似关系表的"实体-联系"关系,基于这种关系诞生了知识图谱(KG)的形式,通过将索引编排为知识图谱,在检索的时候可以发现额外的关系,可以让LLM得到更加全面的上下文与联系。
-
向量存储设计。存储与隔离又是密不可分的概念,得到了具体的向量数据后,应该存储到数据库中------可以是常规向量数据库,也可以是某些存储实体。
- 不同大类(专业知识)的数据,是否应该隔离存储?毕竟复杂的系统总是需要分层。
- 或者期望用数学的方式统一所有,形成大而全的存储中心,然后制定一些固定方式检索内容?
- 面向不同的应用场景,可能会有不同的场景设计。如果是实时推荐系统的RAG,可能同一份数据源会形成两份向量库并使用不同的索引,支持先找到关联数据再找到详细数据。
-
-
知识检索
-
意图识别(查找路由)与查询优化。这个环节属于触发检索的前置逻辑,如果是简单的RAG应用,可以省略这个步骤;如果是大型RAG系统,意图识别就是检索的另外一个关键。
- 前置预测用户意图,选择合适的检索路径,并可以优化上下文。因为人类自然语言总是不能准确描述自己的需求,比如在提问物理学计算的时候,如果这个时候由"路由层"采用"step back prompting"(后退提示)的方法,告诉大模型涉及那些物理原理与公式,就可以更好检索出上下文。
- 面对宽泛复杂的查询,可以在前置中拆解为多个子查询,分别处理后再将结果融合到一起。
-
检索模式,定位到具体数据后应该怎么得到本次查询的结果。基于数据集的关系确定合适的检索模式。
- 第一种,找到数据的同时,将同文档的数据块也都一起返回。
- 第二种,找数据的时候先找知识图谱中有关联的索引,再找到对应的数据块。
- 第三种,找到数据后,重新构建查询,再继续调用系统检索。
-
结果处理
- 重排与压缩,检索出的多个数据块,需要重排,挑选出合适的数据。压缩数据去掉冗余信息的干扰------因为只是需要用这些信息来构造prompt,还不是实际LLM结果生成所以应该压缩。
- 过滤与上下文增强。
- 合并数据,将多个检索、增加后的向量归一化,得到最终的检索结果。
-
-
内容输出
- 结果输出,RAG从数据层中检索到结果之后,用来增强prompt,减少幻觉。基于用户的输入与检索出的结果,构造prompt,调用LLM,得到输出结果。
- 内容生成,LLM的输出内容可能只是初版信息,实际业务需要进一步处理,比如可视化、图片生成。
-
评估与可持续
-
检索评估。评估是一个RAG设计的重点,基于数据集与目的制定评估方案,评估结果也可以用来提升系统生命力。
- 评估指标:准确率(需要有数据集与人工检查)、召回率的大小、相关性的评分、多样性评分
- 调用LLM检查结果与问题的相关性,并检测幻觉,得到模型侧评分。
- 收集用户反馈。
-
高级RAG------text2SQL、知识图谱、多模态RAG
-
总结
上述介绍了RAG系统工程化的步骤,不涉及具体的技术选型。最近有文章说统一化的RAG系统都是伪需求,核心是因为RAG面向的数据源与需求从不固定,也没有统一,所以期望一套RAG规范解决所有需求是不现实的,工程化各个节点里总是不断取舍,最终得到接近需求的实现方式。