RAG效果优化

如果您在使用阿里云百炼应用的 RAG 功能时遇到知识召回不完整或内容不准确的问题,可以参考本文的建议和示例以提升 RAG 效果。

1. RAG 流程简介

RAG(Retrieval Augmented Generation,检索增强生成)是一种结合了信息检索和文本生成的技术,能够在大模型生成答案时利用外部知识库中的相关信息。其效果由三个核心阶段决定:

  1. 建立索引:知识的解析、切片与向量化。

  2. 检索召回:根据用户查询(Prompt),从向量存储中匹配并召回相关的知识片段。

  3. 生成答案:大模型根据召回的知识片段和用户查询,生成最终答案。

image.jpeg

本文将围绕以上三个阶段,介绍多个优化策略,帮助您提升 RAG 的效果。

2. 建立评估基线

在优化前,须建立一套可量化的评估基准,用于客观衡量后续改进措施的效果。

  1. 创建评测集

    • 目的:定义一套标准、可重复执行的测试用例。每个用例应包含一个问题和对应的预期结果。

    • 操作:借助阿里云百炼提供的自动评测功能,创建至少包含 100 组问题的评测集,须覆盖核心真实提问场景,建议包含以下类型:

      • 事实型:“产品X”的保修期是多久?

      • 比较型:对比“产品X”和“产品Y”的主要差异。

      • 教程型:如何安装“产品X”。

      • 分析型:为什么近3个月“产品X”的销量在不断上升?

  2. 执行评测并记录结果

    • 目的:记录初始配置下的 RAG 应用的表现,作为后续优化的对照组。

    • 操作:完整运行一次评测集,并记录每个用例的召回内容与诊断结果。

完成此步骤后,你将获得一份完整的RAG基线性能报告,标明了当前配置在各测试用例上的成功与失败情况,以及诊断结果。

3. 诊断与改进

对照基线测试报告中失败的用例(大模型打分 < 4),根据诊断结果针对性改进。

3.1 检索无效:没有找到相关知识

解决方案:

  1. 包含相关知识:若知识库中没有相关知识,那么大模型大概率无法回答相关问题。解决方案就是更新知识库,补充相关知识。

  2. 优化源文件内容与排版:检查并修正源文件,避免因格式问题导致关键内容在解析时丢失。推荐实践如下:

    • 确保各级标题层次分明,内容结构清晰。

    • 移除页面水印。

    • 避免使用结构复杂的表格,如包含合并或跨页单元格的表格。

    • 优先使用 Markdown 格式。对于 PDF/DOCX 等格式,建议先转换为 Markdown 再导入。

      PDF转成Markdown:可借助阿里云百炼的DashScopeParse工具。具体使用方法详见阿里云大模型ACP课程的 RAG 章节。
  3. 与提示词语言一致:若用户的提示词/问题更多使用外语(如英语),建议源文件内容也使用相应语言。对于专业术语,可进行多语言处理。

  4. 消除实体歧义:对相同实体的表述进行统一。例如,“ML”、“Machine Learning”和“机器学习”可以统一规范为“机器学习”。

    可尝试使用大模型统一规范(若内容较长,可先将其拆为多个部分,再逐一输入)。
  5. 启用“多轮会话改写”:根据历史对话自动补全用户查询,确保大模型能正确理解多轮对话中的指代和上下文省略。

    说明:多轮会话改写

    想象一下,在多轮会话中,您的用户某次使用了类似“阿里云百炼手机X1”这样提示词进行提问。看似简短,却可能导致 RAG 系统在检索时缺乏必要的上下文信息,原因是:

    • 一款手机产品通常会有多个代际版本同时在售。

    • 对于同一代产品,厂家通常会提供多种存储容量选项,比如128GB、256GB等。

      ...

    而这些关键信息可能用户在之前的会话中已经给出,如果能够有效利用,将能够帮助 RAG 更准确地进行检索。

    针对这种情况,您可以使用阿里云百炼的多轮会话改写功能。系统会根据之前的会话,自动将用户的提示词改写为更完整的形式。

    比如用户提问:

    阿里云百炼手机X1。

    在启用多轮会话改写功能的情况下,系统会根据与该用户此前的历史会话,在检索前对该用户的提示词进行改写(仅示例):

    请提供产品库中所有在售版本的阿里云百炼手机X1及其具体参数信息。

    显然,这样改写后的提示词可以帮助 RAG 更好地理解用户的意图,让回答更加准确。

    多轮会话改写功能可以在创建知识库时开启,如下图所示。

    image

    请注意,多轮会话改写功能是与知识库绑定的,开启后仅对当前知识库相关的查询生效。且如果您在创建知识库时未启用该配置,则后续无法再为该知识库开启,除非重新创建知识库。

3.2 检索无效:召回知识不相关

  1. 典型问题:知识库中含多个“类别”的文件。希望在A类文件中检索时,召回结果中却包含其他类别(比如B类)的文本切片。

    解决方案:为文件添加标签,知识库会在向量检索前根据标签筛选相关文件

    说明:标签过滤

    想象一下,您在使用一些音乐APP时,可能有时会通过歌手名称来筛选歌曲,从而快速找到同一类(该歌手唱的)歌曲。

    类似地,为上传文件添加标签可以引入额外的结构化信息。这样应用在检索知识库时,会先根据标签筛选文件,从而提升检索的准确性和效率。

    目前阿里云百炼支持以下两种方式设置标签:

    • 在上传文件时设置标签:控制台操作步骤请参见导入数据,相关APIAddFile

    • 在数据管理页面编辑标签:对于已上传的文件,可单击右侧的标签进行编辑,相关APIUpdateFileTag

      image

    目前阿里云百炼支持以下两种方式使用标签:

  2. 典型问题知识库中含多个结构内容相同/相近的文件,如文件A和文件B的内容都包含“功能概述”章节,只希望在A文件的“功能概述”中检索。

    解决方案:为文件定义元数据,知识库会在检索前使用元数据进行结构化搜索,从而精准定位目标文件并提取相关信息。

    说明:提取元数据

    将元数据嵌入文本切片,可以有效增强每个切片的上下文信息。在特定场景下,这种方法能够显著提升非结构化知识库的 RAG 效果。

    假设以下场景:

    某知识库中有大量手机产品说明文件,文件名称为手机的型号(比如阿里云百炼X1、阿里云百炼Zephyr Z9等),且所有文件都包含「功能概述」章节。

    当该知识库未启用元数据时,用户输入以下提示词进行检索:

    阿里云百炼手机X1的功能概述。

    通过命中测试,您可以查看检索实际召回了哪些切片(如下图所示)。由于所有文件都包含“功能概述”,因此知识库会召回一些与查询实体(阿里云百炼手机X1)无关但和提示词相似的文本切片(如下图中的切片1、切片2),它们的排名甚至高于我们实际需要的文本切片。这显然会影响到 RAG 的效果。

    命中测试的召回结果只保证排名,相似值的绝对值大小仅供参考。当绝对值的差别不大时(5%以内),可基本认为召回概率一样。

    image

    接下来,我们将手机名称,按照知识库一文Meta信息抽取中提到的步骤,设置为元数据(相当于让每篇文件相关的文本切片带上各自对应的手机名称信息),然后再进行一次相同的测试作为对比。

    image

    此时,知识库会在向量检索前增加一层结构化搜索,完整过程如下:

    • 从提示词中提取元数据 {"key": "name", "value": "阿里云百炼手机X1"}。

    • 根据提取的元数据,找到所有包含“阿里云百炼手机X1”元数据的文本切片。

    • 再进行向量(语义)检索,找到最相关的文本切片。

    启用元数据后的命中测试实际召回效果如下图所示。可以看到,知识库此时已经可以精准找到与“阿里云百炼手机X1”相关且包含“功能概述”的文本切片。

    image

    除此以外,元数据的一个常见应用是在文本切片中嵌入日期信息,以便过滤最近的内容。更多元数据用法,请参见metadata抽取

3.3 切片不完整

导入知识库的文件会被解析和切片,以减少后续向量化过程中干扰信息影响,同时保持语义的完整性。切片方式选取不当会导致以下问题:

文本切片过短

文本切片过长

明显的语义截断

image

image

image

文本切片过短会出现语义缺失,导致检索时无法匹配。

文本切片过长会包含不相关主题,导致召回时返回无关信息。

文本切片出现了强制性的语义截断,导致召回时缺失内容。

在实际应用中,应尽量让文本切片包含的信息完整,同时避免包含过多的干扰信息。

解决方案:

  1. 采用“智能切分”策略:基于语义相关性进行切分,有助于保留语义完整性。

    说明:智能切分

    选择适合您知识库的文本切片长度并非易事,因为这必须考虑多种因素:

    • 文件的类型:例如,对于专业类文献,增加长度通常有助于保留更多上下文信息;而对于社交类帖子,缩短长度则能更准确地捕捉语义。

    • 提示词的复杂度:一般来说,如果用户的提示词较为复杂且具体,则可能需要增加长度;反之,缩短长度会更为合适。

      ...

    当然,上述结论并不一定适用于所有情况,您需要选择合适的工具反复试验(例如LlamaIndex提供对不同切片方法的评估功能),才能找到合适的文本切片长度,但显然这并非易事。

    如果您希望在短时间内获得良好的效果,建议您在创建知识库时,切片方式选择智能切分,这是阿里云百炼在经过大量评估后总结出的推荐策略。

    应用这一策略时,知识库会:

    1. 首先利用系统内置的分句标识符将文件划分为若干段落。

    2. 基于划分的段落,根据语义相关性自适应地选择切片点进行切分(语义切分),而非根据固定长度进行切分。

    在上述过程中,知识库将努力确保文件各部分的语义完整性,尽量避免不必要的划分和切分。

    此策略将应用于该知识库中的所有文件(包括后续导入的文件)。

  2. 人工检查和修正文本切片内容:确保文件被正确地解析和切分。

    说明:修正文本切片内容

    在实际切片的过程中,仍然存在一定几率会出现意外的切分,或者出现其它问题(例如文本中的空格有时切片后会被解析为%20)。

    image

    因此,在成功将文件导入知识库后,可进行一次人工检查,以确认文本切片内容的语义完整性和正确性。如果发现意外的切分或其他解析错误,可直接编辑文本切片进行修正(保存后,文本切片原有的内容将失效,新的内容将用于知识库检索)。

    说明

    此处只是修改了知识库中的文本切片,并未修改数据管理(临时存储)中的源文件或数据表。因此后续将此文件/数据表再次导入知识库时,仍需人工检查和修正。

3.4 重排不佳

在知识库找到和用户提示词相关的文本切片后,会先将它们发送给重排模型(Rank模型)进行重排序,而相似度阈值则用于筛选经过Rank模型重排序后返回的文本切片,只有相似度分数超过此阈值的文本切片才有可能被提供给大模型。

image

调低此阈值,预期会召回更多文本切片,但也可能召回一些相关度较低的文本切片;提高此阈值,预期会减少召回的文本切片。

若该值设置得过高(如下图所示),知识库可能会丢弃所有相关的文本切片,这将限制大模型获取足够背景信息生成回答。

image

解决方案:

  1. 提高“相似度阈值”:放宽召回条件,避免因过滤标准过于严格而导致漏召回。

    说明:调整相似度阈值

    没有最好的阈值,只有最适合您场景的阈值。您需要通过命中测试反复试验不同的相似度阈值,观察召回结果,找到最适合您需求的方案。

    命中测试建议步骤

    1. 设计能够覆盖客户常见问题的测试用例;

    2. 根据知识库的具体应用场景和前期导入文档的质量,选择一个合适的相似度阈值;

    3. 执行命中测试,查看知识库召回结果;

    4. 基于召回结果,重新调整您的知识库的相似度阈值,具体操作请参见编辑知识库

    image

  2. 提高“召回片段数”:对于需要总结、列举或比较的复杂问题,适当增加该值有助于大模型生成更完整的答案。

    说明:提高召回片段数

    召回片段数即多路召回策略中的K值。经过前面的相似度阈值筛选后,如果文本切片数量超过K,系统最终会选取相似度分数最高的 K 个文本切片提供给大模型。也正因为此,不合适的K值也可能会导致 RAG 漏掉正确的文本切片,从而影响大模型生成完整的回答。

    比如下面的这个例子,用户通过以下提示词进行检索:

    阿里云百炼X1手机有什么优势?

    从下方示意图可以看到,目标知识库中实际与用户提示词相关,需要返回的文本切片总共有7个(下图左侧,已用绿色标出),但由于已经超出了当前设定的最大召回片段数K,因此包含优势5(超长待机)和优势6(拍照清晰)的文本切片被舍弃,没有提供给大模型。

    image

    由于 RAG 本身无法判断需要多少个文本切片才能给出“完整”的答案,因此即使最终提供的文本切片有遗漏,随后大模型仍然会基于缺失的文本切片生成不完整的回答。

    大量实验结果表明:在诸如“列举...”、“总结...”,“比较一下X、Y...”等场景中,提供更多高质量的文本切片(例如K=20)给大模型,比仅提供前10个或前5个文本切片效果更好。虽然这样做可能会引入噪声信息,但如果文本切片质量较高的话,大模型通常能够有效抵消噪声信息的影响。

    您可以在调试阿里云百炼应用时调整召回片段数

    调整值后,需手动点击页面右上方的保存,使设置生效。

    image

    image

    请注意,召回片段数也并非越大越好。因为有时召回的文本切片在拼装后,其总长度会超出大模型的输入长度限制,导致部分文本切片被截断,反而影响了 RAG 的效果。

    因此,推荐您选择按拼装长度。这一策略会在不超过大模型最大输入长度的前提下,尽可能多地为您召回相关的文本切片。

3.5 模型理解有误

  1. 典型问题:大模型并未理解知识和用户提示词之间的关系,感觉答案是生硬拼凑的。

    解决方案:更换生成模型,从而有效地理解知识和用户的提示词之间的关系。

    说明:选择合适的大模型

    由于不同大模型在指令遵循、语言支持、长文本、知识理解等方面存在能力差异,可能导致:

    模型A未能有效理解检索到的知识与提示词之间的关系,从而生成的答案无法准确回应用户的提示词。在更换为参数更多或者专业能力更强的模型B后,该问题可能就能得到解决。

    比如用户提问:

    我是中华人民共和国公民,我想收养一名未成年人,我必须具备哪些条件?

    先后使用通义千问2-开源版-7B通义法睿-Plus大模型,结合包含相关资料的知识库进行测试:

    通义千问2-开源版-7B

    通义法睿-Plus

    image

    image

    可以看出,在这个例子中,此模型没能很好地理解用户提示词中的限制以及检索到的知识。

    更换大模型后,该问题得到了解决。

    您可以在编辑阿里云百炼应用时,根据实际需求选择模型。建议选择通义千问的商业模型,例如通义千问Max通义千问Plus等大模型。这些商业大模型相比开源版本,具备最新的能力和改进。

    • 如果只是简单的信息查询总结,小参数量的大模型足以满足需求,例如通义千问Flash通义千问Turbo

    • 如果您希望RAG能完成较为复杂的逻辑推理,建议选择参数量更大、推理能力更强的大模型,例如通义千问Max或是QwQ

    • 如果您的问题需要查阅大量的文档片段,建议选择上下文长度更大的大模型,例如通义千问Long通义千问Plus

    • 如果您构建的 RAG 应用面向一些非通用领域,例如法律领域,建议使用面向特定领域训练的大模型,例如通义法睿

  2. 典型问题:返回的结果没有按照要求,或者不够全面。

    解决方案:优化提示词模板。通过调整提示词来影响大模型的行为(例如怎样利用检索到的知识等),间接提升 RAG 的效果。

    说明:优化提示词模板

    我们知道,大模型本身是基于给定的文本来预测下一个Token的。这意味着您可以通过调整提示词来影响大模型的行为(例如怎样利用检索到的知识等),间接提升 RAG 的效果。

    以下为您介绍三种比较常见的优化方法:

    方法一:对输出的内容进行限定

    您可以在提示词模板中提供上下文信息、指令以及预期的输出形式,用于指示大模型完成任务。例如,您可以加入以下输出指示要求大模型:

    如果所提供的信息不足以回答问题,请明确告知“根据现有信息,我无法回答这个问题”。切勿编造答案。

    来减少大模型出现幻觉的几率。

    方法二:添加示例

    使用少样本提示(Few-Shot Prompting)的方法,将希望大模型模仿的问答示例添加到提示词中,引导大模型正确利用检索到的知识(下方示例使用的是通义千问-Plus)。

    提示词模板

    用户提示词和阿里云百炼应用返回的结果

    # 要求
    请从下方文本中提取技术规格,并以 JSON 格式展示。
    ${documents}

    image

    # 要求
    请从下方文本中提取技术规格,并以 JSON 格式展示,请严格按照示例给定的字段展示。
    ${documents}
    
    # 示例
    ## 输入:星尘S9Pro, 突破性6.9英寸1440 x 3088像素屏下摄像头设计,带来无界视觉享受。512GB存储与16GB RAM的顶级配置,配合6000mAh电池与100W快充技术,让性能与续航并驾齐驱,引领科技潮流。参考售价:5999 - 6499。
    ## 输出:{ "product":"星尘S9 Pro", "screen_size":"6.9inch", "ram_size": "16GB", "battery":"6000mAh" }

    image

    方法三:添加内容分隔标记

    检索召回的文本切片如果随意混杂在提示词模板中,不利于大模型理解整个提示词的结构。因此,建议您将提示词和变量${documents}明确分开。

    此外,为了保证效果,请确保您的提示词模板中变量${documents}只出现一次(请参考下方左边的正确示例)。

    正确示例

    错误示例

    # 角色
    你是一名客服人员,专注于分析和解决用户的问题,并通过检索知识库提供准确的解决方案。
    
    # 要求
    **直接返回结果**:请根据用户输入的提示词以及知识库中的内容给出直接返回结果,无需
    进行推理。
    **返回的结果中不要包含具体联系方式**:返回的结果中仅需包含对用户提示词的总结、相
    关在职人员的姓名及其负责的内容。
    **默认联系人**:如果找不到相关的在职人员,请直接返回“今日值班人:阿里云百炼客服01”。
    
    # 知识库
    请记住以下材料,它们可能对回答问题有帮助。
    ${documents}
    
    # 角色
    你是一名客服人员,专注于分析和解决用户的问题,并通过检索知识库提供准确的解决方案。
    请利用${documents}中的信息来辅助解答。
    
    # 要求
    **直接返回结果**:请根据用户输入的提示词以及知识库中的内容给出直接返回结果,无需
    进行推理。
    **返回的结果中不要包含具体联系方式**:返回的结果中仅需包含对用户提示词的总结、相
    关在职人员的姓名及其负责的内容。
    **默认联系人**:如果找不到相关的在职人员,请直接返回“今日值班人:阿里云百炼客服01”。
    
    # 知识库
    请记住以下材料,它们可能对回答问题有帮助。
    ${documents}

    了解更多提示词优化方法,请参阅Prompt工程

  3. 典型问题:返回的结果中包含了大模型自身的通用知识,并未严格基于知识库。

    解决方案:开启拒识,仅限于根据知识库检索到的知识回答。

    说明:开启拒识

    如果您希望阿里云百炼应用返回的结果严格基于从知识库中检索到的知识,排除大模型自身通用知识的影响,您可以在编辑阿里云百炼应用时开启召回过滤策略

    image

    对于在知识库中找不到相关知识的情况,您还可以通过开启干预智能体回复设置固定回复(自动)。

    image

    回答范围:知识库 + 大模型知识

    回答范围:仅知识库范围

    image

    image

    阿里云百炼应用返回的结果将综合从知识库中检索到的知识和大模型自身的通用知识。

    阿里云百炼应用返回的结果将严格基于从知识库中检索到的知识。

    关于知识范围判定,系统会先通过相似度阈值筛选潜在文本切片,再由一个大模型裁判,通过您设置的判断Prompt对关联度进行深入分析,从而进一步提高了判定的准确性。

    image

    以下是一个判断Prompt的示例,供您参考。此外,当在知识库中未找到相关知识时,设置一个固定回复:抱歉,未找到相关的手机型号。

    # 判断规则:
    - 问题和文档匹配的前提是问题中涉及的实体与文档描述的实体完全相同。
    - 问题在文档中完全没有提到。

    用户提示词和阿里云百炼应用返回的结果(命中知识时)

    用户提示词和阿里云百炼应用返回的结果(未命中知识时)

    image

    image

  4. 典型问题:提示词相同,希望每次返回的结果相同或不同。

    解决方案:调整大模型参数。

    说明:调整大模型参数

    相似的提示词,如果您希望每次返回的结果相同或不同,您可以在编辑阿里云百炼应用时,修改参数配置来调整大模型参数。

    image

    上图中的temperature可以控制大模型生成内容的随机性:值越高,生成的文本越多样,反之,生成的文本越确定。

    • 具有多样性的文本,适用于创意写作(如小说、广告文案)、头脑风暴、聊天应用等场景。

    • 具有确定性的文本,适用于有明确答案(如问题分析、选择题、事实查询)或要求用词准确(如技术文档、法律文本、新闻报道、学术论文)的场景。

    其他两个参数:

    最长回复长度:用于控制大模型生成的最多Token个数。如果您希望生成详细的描述可以将该值调高;如果希望生成简短的回答可以将该值调低。

    enable_thinking:是否开启思考模式。

4. 后续步骤

4.1 持续迭代

  1. 重新评估:建议每次完成配置变更后,重新运行前面步骤中创建的评测集。

  2. 对比分析:并将结果与基线报告进行对比,量化分析变更带来的效果(解决了哪些问题、是否引入了新问题)。

  3. 持续迭代:根据数据分析结果,决定下一步的优化策略。

4.2 模型调优

最后,如果上述方法均已尝试且希望进一步提升效果,可考虑针对具体场景,选择一个大模型进行模型调优