即检索增强技术(retrieval argumented generation)。是一种结合信息检索和文本生成的技术。旨在通过引入外部知识库来提升模型的事实准确性、相关性和多样性。
使用场景
在做一些偏企业内部的知识助手和电商客服的时候,内部的手册和知识库往往会超过大模型的上下文。通常会有以下问题:
- 模型无法读取所有内容
- 模型推理成本高
- 模型推理慢
于是 rag 便有他的意义了。
整体流程
建库
首先第一步是收集数据,往往在现实工作中不会有提供好的现成的数据用,我们需要去把不同格式的数据(pdf、网站、数据库、api)。然后 就是需要对数据进行分割,把数据分成指定大小的块,通常会有按字数分割、按章节分割。再接着使用预训练模型(BGE、BERT)对原始数据进行 embedding 表示,这些向量表明了文本的语义。具体的可以参见这篇博客。最后再把向量和文本都存在数据库中,建立索引关系,来实现快速检索。
检索
当用户提交查询时,对待查询的文本采用相同的编码器,然后根据得到的向量来进行相似度计算(余弦相似度、欧式距离等方法),然后选择出相似度最高的 n 个选择,作为查询的参考;然后再对选择进行重排(rerank),选出最终的 m 个选择(n>m)。
生成
对于用户的问题和上面的 m 个选择进行整合,一块发送给大模型,最后生成答案。然后可以添加一些合理的后处理,比如置信度评估,候选答案评选。

上图中可以比较清晰的知道 rag 整个的流程。
具体技术
下面介绍一下具体的技术细节
query transition
属于rag pipeline的第一阶段,目的是为了将question变成更容易检索的形式,提升retrieval的效果。
multi query
将 question 按多个角度重写例如同义词替换、相似语义拓展、删除冗余词、纠正错误和标准化表述等。然后再对每个问题都进行 retrieve 将得到,再对得到的结果取并集,然后把并集都丢给 llm。

rag fusion
对于检索得到的文档进行排名,通过加权各个question在文档中的排名得到一个综合的排名。

decomposition
把初始问题切分成n个问题,然后按照以下;两种方式处理
- 前一个问题的答案输入到下一个问题。
- n 个问题互相独立,最终拼接成最终答案。


stepback
从一个具体的问题出发,通过给一些few-shot的方式,生成一个更高层次、更抽象的问题,以便于检索到相关文档。例如从问某人的学习成绩到问对某人的评价。
HyDE
与以上不同,HyDE根据用户输入的question生成一些假设的doc,这些doc与文档更接近,利用这些doc检索相关的知识。这样做的直觉是:由模型生成的回答会包含与查询语义相关的词汇和信息,可以作为查询的丰富语义表示,从而找到那些没有直接关键词匹配但语义相关的文档。
比如对于用户查询“保险销售技巧”。传统检索可能只针对“销售”或“保险”检索,结果不一定全面。应用 HyDE 时,我们先让 LLM 根据这一查询生成一段假设回答,例如:“保险销售技巧包括了解客户需求、建立信任、提供专业建议”,假设回答丰富了查询关键词,有更大概率找到相关的文档。
routing
路由,顾名思义,就是将不同的 query 按照一定的规则分流到不同的流程。
routing 属于 rag pipeline 的第二阶段,目的是为了让 query 能够查询到争取的数据源(数据源都不对的话,那就不要扯其他的了)。
通常会有以下几种 routing 方式
- 基于规则的方法
在现实工作场景中,我们可以人为的给项目设定路由规则,比如如果用户 query 中包含“报销”“费用”等关键词,判定为报销流程查询;如果包含“销售”“技巧”等词,判定为保险产品销售技巧。
- 基于机器学习的方法
收集大量的样本,对于一个预训练模型(bert)进行微调,来让这个模型判断分流,而不是简单的根据一些字词来判断。
- 基于提示词工程的方法
通过精心设计的Prompt直接让大模型判断意图类别。可以提供若干意图类别描述,让模型选择最适合的类别。此方法不需要额外训练数据,在零样本或少样本场景下效果好。
logical routing
有多个数据库(知识库),将问题 route 到不同的数据库来查询。

semantic routing
根据语义相似度来 route,就是在对 query 进行 embedding 之后得到对应的语义向量,然后用这个语义向量去匹配对应的数据库。
一种特别有用的技术是使用embeddings将query路由到最相关的prompt。

Query Construction
这个是 ragpipeline 的第三部分,利用命名实体识别技术,将 query 转化成适合用于搜索的keywords 或者参数。比如:
用户query:how to use multi-modal models in an agent, only videos under 5 minutes输出:content_search: multi-modal models agent、title_search: multi-modal models agent、max_length_sec: 300

Indexing
rag pipeline的第四部分,将文档拆成 vector 形式,并建立索引。
chunking
分块(chunking)是将大块文本分解成小段的过程,直接影响系统的检索质量和生成效果:
- 检索精度和相关性:合理的切分能保证每个chunk的语义完整性,更准确的匹配用户意图,降低不相关内容被一同检索的可能性。
- 向量表示与相似度计算:能产生更精确的语义向量表示,使相似度计算更加准确,并且可以加速相似度计算和索引查找过程
- 生成质量优化:合理的切分能在不超过模型最大输入限制的情况下提供足够上下文,提高输入给模型的信息密度和质量,减轻模型幻觉
- 实际应用考量:不同领域可能有不同的切分策略,保留和添加适当的元数据可以提升检索效果。
现有的 chunking 策略有:FastGPT、Langchian-Chat、 Baidu千帆知识库、星火知识库、Jina。
基于Langchain的分块方案:
- Character:按固定字符数分割。 可以设置重叠字符来保持上下文
- Recursive:Langchain的默认文本分割器,它按不同的字符递归地分割文档(默认使用[“\n\n” ,"\n" ," ",""]),按照顺序逐个遍历列表中的分隔符直到块足够小为止,可以实现结构化的文档切分。 可以设置重叠字符来保持上下文。
- Token:按照token数量进行分块。常用的分词器有BPE、tiktoken等
- Document:使用特定的分隔符或规则进行分割,如markdown中的标题符号、Python代码中的类和函数等。
- Semantic:通过计算句子间embedding距离,把具有相似主题或内容的句子分为一块。
- Agentic:最高级别的chunking方法,通过LLM做决策,将文本分块为独立的命题。
chunking 这一块非常有说法,下一篇博客具体讲一下。
Retrieval
检索,即根据上面 已经过 construction 的query 和经过 chunking 的数据库(知识库)来检索得到匹配的内容。主要有以下知识点,以后会专门介绍。
- 混合检索
- reranking
- 检索评估指标
Generation
将检索到的相关文档与原始查询合并,形成更丰富的上下文信息,作为生成模型的输入,生成连贯、准确且信息丰富的回答或文本。
from langchain.prompts import ChatPromptTemplate
# 一个参考模板
template = """你是一个xx领域的专家,请结合从知识库中检索到的相关文档,回答用户问题:
### 问题:
{question}
### 上下文:
{context}
### 答案:
"""
prompt = ChatPromptTemplate.from_template(template)在现实的生产环境中,经常容易出现以下三个问题:
- 多轮对话的语义连贯性不足:在用户多轮提问时,如果新问题是对上一轮回答的跟进(例如用户问:“这个怎么申请?”),系统需要理解“这个”指代什么。缺少对话上下文的关联可能导致LLM误解提问,给出不相关或幻觉的答案。
- 多模态知识的利用困难:金融保险领域的知识库包含PDF手册、PPT演示、文本说明、视频讲解等多种形式。如果不对这些不同格式的数据进行预处理和结构化,检索时可能遗漏关键信息,导致答案不全面。
- 缺少来源引用降低可解释性:用户希望了解答案出处以建立信任。如果生成的答案没有标注来源,用户无法追溯信息真实性。特别是从长文档提取内容时,不注明具体出处会降低答案的可信度和可检查性。
具体解决也可以参考以下方法:
- 维护对话上下文,确保连贯:在每次用户提问时,检测问题是否包含代词或省略(如“这个”“它”等)以判断是否为跟进问答。如果是跟进问题,将之前的相关问答摘要或关键术语添加到当前查询中。一种常见做法是问题重写:将用户的新问题与上下文合并重写成完整问题,再送入检索和LLM。与此同时,系统应维护一个对话历史状态,让LLM参考之前的问答或已检索的知识,避免因缺少背景造成误解。
- 整合多模态知识,提高答案全面性:预先对PDF、PPT、文本、视频等资料进行解析和结构化处理,存入统一的向量数据库以便检索。比如:
- PDF/PPT:提取文字内容,保留章节标题、表格数据等结构信息,将长文档按段落或页面切分成知识片段(chunks),并为每个片段添加文档名称、页码/幻灯片编号等元数据。
- 视频:对讲解视频执行语音转文本(ASR),获得字幕稿。根据时间戳将字幕稿切分成短段,并存储视频ID和时间段元数据。必要时可结合视频说明文字或关键帧截图的文字说明。
- 将不同模态的数据转换为统一的文本嵌入向量,以便用同一种检索方式获取相关片段(例如使用同一嵌入模型表示文本和语音转文本)。或者采用多模态检索策略:分别在文本库、图像/视频库中检索,再融合结果。
- 在生成答案时,允许LLM综合多个来源的片段。例如同时引用保单PDF中的条款和培训视频中的说明,以形成完整答案。
3. 在答案中加入来源引用,增强可解释性:设计提示(Prompt)要求LLM在给出答案时标注信息来源。例如,让模型在句末用括号注明来源文档名称或索引编号。实现方法可以是:在将检索到的文档片段传递给LLM时,附加标记(如【1】、【2】)或者直接提供“引用格式”的文本,让模型仿照引用格式回答。对于长文档的引用,如果答案来自同一资料的不同部分,可以拆分引用为【文档A,第10页】、【文档A,第15页】等,精确指明出处。生成策略上,可以使用RAG的引用增强模式,即模型严禁脱离提供的知识片段编造答案,确保每句都有据可依。最终答案输出时,将源文件名称或链接映射为用户可查看的引用,以便用户点开核实内容。这种动态插入引用的方式保证了答案的可溯源性,减少幻觉,增加用户信任。
面临问题
- 内容缺失:知识库中缺失上下文,rag只能提供不精确、甚至是错误的答案。
- 解决方案:可以通过数据清洗和prompt优化(比如在prompt中加入“如果你不确定答案是什么,就告诉我你不知道”的提示,防止模型胡说八道)缓解。
- 错过排名靠前的文档:由于检索时缺乏上下文,导致检索到的关键的文档排名靠后,没有返回给用户。
- 解决方案:可以通过chunk_size 和 similarity_top_k平衡计算效率和质量,以及采用Rerank算法。
- 不在上下文中:无法将检索到的文档全部放在输入模型的上下文中,尤其是检索到大量文档时。
- 解决方案:使用长上下文的方法,例如需要对文档进行合并、插值等。
- 未提取:LLM倾向于检索近似值而不是精确值,导致包含很多不相关的甚至互相矛盾的信息,可能因为这些噪音损害响应质量。
- 解决方案:数据清洗,压缩prompt,避免中部丢失问题(模型对输入上下文开头和结尾的信息理解能力更强,应避免将关键的信息放在中部)。
- 格式错误: LLM 忽视了提取特定格式的信息(如表格或列表)的指令。
- 解决方案:prompt中给出示例,简化清晰prompt,对输出进行解析。
- 特异度不正确:输出的粒度与输入不一致,比如用户问题很具体,模型回答很宏观;或者用户问题包含详细的上下文,模型生成简短的回复。
- 解决方案:改进检索策略,如从小到大检索、句子窗口检索、递归检索;在prompt中引导模型生成特定粒度的内同。
- 不完整:输出只回答了输入的部分问题。
- 解决方案:之前RAG的文章中提到的一些方法,如routing到最相关的文档库,用户查询重写和分解成子问题。
效果评估
准确率/召回率评估
评估RAG系统回答问题的正确性和检索相关性,更多指标详见3.1.6 Retrieval 检索评估指标。主要包括:
- 答案准确率:比较生成的答案与标准答案的匹配程度,可使用自然语言处理中的评价指标如 BLEU(衡量n元语法匹配程度)、ROUGE(衡量召回的n元语法覆盖率)等来量化答案与参考答案的相似度。
- 检索召回率:评估检索模块是否找到了包含正确答案的文档。例如计算 Top-k召回率(正确答案所在文档是否出现在前k个检索结果中)以及 MRR(平均倒数排名)、NDCG(归一化折损累计增益),以衡量正确文档在检索结果中的位置(MRR越高表示相关文档排名越靠前)。
可信度评估
衡量生成的答案在多大程度上有文档支持,以及答案内容和检索到的文档是否一致、可靠。具体包括:
- 答案与支持文档匹配度:验证生成答案中的关键信息是否能在检索文档中找到。可以计算答案和支持文档之间的相似度或重合率,例如关键词重叠度。
- 文档覆盖率:检查检索到的文档是否覆盖了回答所需的所有要点。如果答案涉及多个要点,评估这些要点是否均能在提供的文档集合中找到依据。
响应速度评估
评估RAG系统处理查询的速度,包括:
- 平均响应时间:系统处理单个查询的平均用时。
- P95/P99 延迟:95%和99%的请求在多少时间内完成(尾部延迟),用于评估最慢响应的情况。
- 整体响应分布:可以绘制响应时间分布图(如直方图)来了解大部分查询的延迟范围。
可扩展性评估
测试RAG系统在不同数据规模和负载下的性能表现,包括:
- 数据规模扩展:增大知识库或文档集规模,观察检索和生成性能的变化(如响应时间是否随数据量线性增长,检索准确率是否保持稳定)。
- 吞吐量:衡量系统每秒可处理的查询数(QPS),以及在高并发情况下的性能表现。
用户体验评估
系统给用户带来的主观感受和易用性,包括:
- 人工满意度评价:通过人工评估或用户反馈来打分,衡量用户对答案的满意度。例如收集用户评分(1-5分)或对答案是否解决问题的二元反馈,以计算平均满意度分或满意率。
- 答案可读性:评价生成答案表述的清晰易懂程度。可以使用可读性评分(如基于句子长度和词汇复杂度的指标)来定量分析答案文本的可读性,确保答案语言简洁明了,便于用户理解。
评论
注册或登录后即可评论。