rag系列文章目录
文章目录
前言
在rag的整个流程中,一般第一步就是对问题query进行改写,为什么需要改写呢,主要是用户在提问的时候,想要得到的答案和问题不匹配,为了得到想要的答案,不同的用户可能问的方式千变万化,这就需要对query进行改写,来提高rag系统的鲁棒性和扩展性。
用户的query存在的问题,主要有两个方面,一是信息缺失,用户表达的不全面;一是噪声,用户query里面携带了很多不相关的东西。
一、信息缺失问题
1.1 历史会话改写
在会话中,上下文是有关联的,如果仅仅使用query进行召回,会导致召回精确度大幅下降,因为query中缺失了很多会话信息,如下所示。
用户:iPhone 15 的性能怎么样?
• 系统:iPhone 15 的性能非常强大,搭载了 A17 芯片,支持更高效的图像处理和长时间续航。
• 用户:它和上一代相比有哪些提升?
• 系统:iPhone 15 相较 iPhone 14 提升主要体现在芯片性能、相机优化和电池续航上。
• 用户:相机的具体改进是什么?
改写前:相机的具体改进是什么?
改写后:iPhone 15 的相机相比 iPhone 14 有哪些具体改进?
1.2 关键词扩写
用户在使用搜索引擎的时候,经常会输入一些关键词,关键词比较少,而且缺乏语义,在进行语义检索(向量检索)的时候,召回不是特别好,所以需要对用户的关键词进行补充完善。
用户输入:
“Python 数据分析”
改写后的 Query:
“Python 在数据分析中的应用是什么?有哪些常用的库和工具?”
1.3 伪答案改写
它通过在原始查询中加入一个伪答案的形式,来丰富查询的语义,提升检索或回答的准确性。伪答案并非实际答案,而是一个假设性的内容,用于引导系统检索更相关的信息。
用户输入:
“初创公司如何融资?”
改写后的 Query:
“初创公司如何融资?比如通过风险投资、众筹或银行贷款等方式实现资金筹集。”
伪答案目的:
• 提供假设性的融资方式,增加语义信息,提升对复杂问题的检索能力。
1.4 缩写词改写
用户进行查询的时候,有时会使用缩写,但是很多相关的文档里面一般是全写,所以需要进行改写,完善缩写的全称。
用户输入:
“AI 在医疗中的应用”
改写后的 Query:
“人工智能(Artificial Intelligence)在医疗中的应用是什么?有哪些具体案例?”
二、噪声问题
2.1 一般去噪改写
它会去除查询中的噪声(例如无关的词汇、模糊的表达、多余的修饰等),以简化和优化查询,使其更具可操作性。这种方法对提升检索精度和效率非常有帮助。
用户输入:
“孩子最近在学校数学成绩不太好,怎么才能找到一些比较实用的方法,帮助他提高成绩呢?”
改写后的 Query:
“有哪些实用方法可以帮助学生提高数学成绩?”
分析:
• 去掉与问题无关的背景信息 “孩子最近在学校数学成绩不太好”。
• 直接提取核心意图 “帮助提高数学成绩”
2.2 关键词改写
它是一种专注于提取核心关键词并去除噪声的 Query Rewriting 方法。这种方法通过识别查询中的关键部分,排除冗余信息(如停用词、语气词、多余描述),使查询更简洁,从而提升检索效率和准确性。这种提取关键词的方式,比较适合用于关键词检索召回中,比如bm25检索召回。
用户输入:
“关于 Python 的并发处理,有哪些常用的库?”
改写后:
“Python 并发处理 常用库”
2.3 子查询改写
当查询是对比类的查询时,确实可能会出现多个实体相互干扰的情况。对比类查询通常包含多个元素,直接查询时,这些元素可能会造成噪声或信息重叠,影响检索的精确性。为了减少干扰信息,可以将对比类查询拆分成多个单独的查询,每个查询聚焦于一个实体,从而避免信息混淆,得到更精准的结果。
用户输入:
“Python 和 Java 哪个更适合开发人工智能?”
拆分后的查询:
1. “Python 适合开发人工智能的优点有哪些?”
2. “Java 适合开发人工智能的优点有哪些?”
拆分原因:
• 直接询问 Python 和 Java 的对比可能会让系统无法准确判断其各自的特点。拆分后,系统可以分别检索 Python 和 Java 在人工智能开发中的应用,避免相互干扰。
三 prompt示例
以下是一个开源rag系统,问题改写的示例,仅供参考:
您是查询扩展方面的专家,能够生成问题的释义。
我无法直接使用用户的问题从知识库中检索相关信息。
您需要通过多种方式扩展或释义用户的问题,例如使用同义词/短语、完整地写出缩写、添加一些额外的描述或解释、改变表达方式、将原始问题翻译成另一种语言(英语/中文)等。
并返回 5 个版本的问题,其中一个来自翻译。
只需列出问题。不需要其他单词。
总结
改写后query的质量,很依赖于prompt和大模型的能力。一般来说,改写后的query能够提高召回的准确度,但是还是偶会会发生改写失败的例子,建议多次改写或者改写为多个query,将召回的结果,送入reranker进行精排,然后再让大模型输出答案。