解密Prompt系列20. LLM Agent之再谈RAG的召回多样性优化
几个月前我们就聊过RAG的经典方案解密Prompt系列14. LLM Agent之搜索应用设计。前几天刚看完openAI在DevDay闭门会议上介绍的RAG相关的经验,有些新的感悟,借此机会再梳理下RAG相关的优化方案。推荐直接看原视频(外网)A Survey of Techniques for Maximizing LLM Performance
RAG最关键的一环其实不是LLM而是相关内容的召回,作为大模型推理的上文,优秀的内容召回应该满足以下条件:
- 多样性和召回率:召回的内容要可以回答问题,并且内容丰富度,包括同一问题多个观点,多角度
- 相关性和准确率:召回内容和问题相关,总不能召回100篇里面只有2篇和问题有关
- 一致性和低冲突:召回内容间的观点一致性较高
- 更高要求:高时效性,权威性,观点完整性,内容重复度低
这里不妨借鉴前人经验,参考搜索的主流框架:Query理解和扩展 -> 多路召回 -> 合并排序 -> 重排和打散。过去几个月RAG的论文也像是把传统搜索的方案,使用LLM轮番做了一遍范式更新。本章我们先围绕召回内容的多样性唠上两句。
直接使用用户Query进行向量检索,召回率往往不高,原因有以下几个
- query较短,本身信息有限
- 短文本的embedding效果较差
- query短文本向量和document长文本向量存在空间表征差异
- 用户对自己想问的内容比较模糊
- 用户的query提问可能需要多个方向的信息聚合才能回答
以上问题其实覆盖了两个点:Query本身包含信息的多样性,搜索索引的多样性。下面我们结合新老论文,以及langchain新增的一些功能,来分别介绍~
1. Query多样性
- 2019 Query Expansion Techniques for Information Retrieval: a Survey
传统搜索Query的扩展,有基于用户搜索日志挖掘的相似Query,有基于相同召回文档关联的相似Query,也有基于SMT的Query改写方案。那和大模型时代更搭配的自然是改写方案,LLM的加持很大程度上降低了Query改写的难度,也为改写提供了更多的可能性。
1.1 相似语义改写
- Learning to Rewrite Queries,雅虎(2016)
- webcpm: Interactive Web Search for Chinese Long-form Question Answering,清华(2023)
比较早在16年yahoo就探索过query改写的方案,那时还是个seq2seq的LSTM。再就是之前介绍的webcpm也有使用大模型进行query改写来提高内容召回。近期langchain也集成了MultiQueryRetriever的类似功能。逻辑就是把用户的Query改写成多个语义相近的Query,使用多个Query一起进行召回,如下

1.2 双向改写
- Query2doc: Query Expansion with Large Language Models,微软(2023)
- Query Expansion by Prompting Large Language Models, 谷歌(2023)
除此之外还有一种另类Query的改写方案,就是Query2doc中提到的把Query改写成document。论文使用4-shot prompt让LLM先基于query生成一个pseudo-document,然后使用生成的答案来进行相关内容的召回。这种改写方案确实有一些显著的优点
- 缓解短文本query向量化效果较差的问题
- 缓解document长文本向量和query短文本向量存在空间差异的问题
- 提高BM25等离散索引抽取的效果,毕竟文本长了更容易抽出有效关键词
当然缺点也很显著,一个是pseudo-docuemnt可能发生语义漂移,幻觉回答会引入错误的关键词降低召回的准确率,以及解码的耗时较长~

这里Query2Doc反过来写,Doc2Query也是另外一个优化方向,就是给每篇文档都生成N个关联Query(pseudo-query),使用关联Query的embedding向量来表征文档,和真实Query进行相似度计算。langchain的MultiVector Retriever也集成了类似的功能。
谷歌也做了类似的尝试。分别对比了Query2Doc(Q2D), Query2Keyword(Q2E), Query2COT几种改写方案,以及使用zero-shot,few-shot,召回文档增强等不同prompt指令的效果。其中Query2Doc采用了和上面微软相同的prompt指令,其他指令如下

结果显示,当模型规模足够大之后,Query2COT展现出了显著更优的效果。甚至超越了在上文中加入相关文档的COT/PRF 方案。一方面COT会对Query进行多步拆解,一方面思考的过程会产生更有效的关键词,以及不使用相关文档可以更有效的释放模型本身的知识召回能力和创造力。

1.3 强化学习改写
- ASK THE RIGHT QUESTIONS: ACTIVE QUESTION REFORMULATION WITH REINFORCEMENT LEARNING,谷歌(2018)
- Query Rewriting for Retrieval-Augmented Large Language Models,微软(2023)
以上的改写方案在openai的闭门会都有提到,确实一定程度上可以提升RAG的效果,可以用于初期的尝试。不过这种改写是无监督的,也就是基于相似语义进行改写,并不能保证改写后的query搜索效果一定更好。那我们不妨引入一个目标来定向优化改写效果。
2018年谷歌就曾尝试使用强化学习来优化改写模型,把搜索系统视作Environment,seq2seq模型生成多个Query的改写候选作为Action。把原始Query的召回内容,和改写Query的召回内容,一起送入后面的排序模块,使用排序模块TopK内容中改写Query召回内容的召回率作为Reward打分,来梯度更新改写模型,最大化改写召回率。毕竟不论你改写的多么花里胡哨,能有效提高内容召回,拥有更高的独占召回率才是真正有用的改写模型。
而在大模型时代,改写模块被升级为LLM。在微软提出的rewrite-retrieve-read框架中,使用大模型作为rewriter,Bing搜索作为Retriever,chatgpt作为Reader,在QA任务上,尝试使用PPO微调改写模型,Reward模型的目标是不同改写query召回后推理内容和真实答案的Exact Match和F1。不过真实场景中,这种有标准答案的QA问答其实占比很小,更多都是开放式问答。那么其实可以类比以上的传统方案,使用大模型推理的引用率,作为Reward目标。毕竟大模型选择哪几条输入的上文进行推理,和精排原理其实是相似的。

2. 索引扩展
简单说完query扩展,我们再来看下索引扩展。当前多数RAG得召回索引还是以单一的Embedding向量模型为主,但单一向量作为召回索引有以下几个常见问题
- 文本的相似有不同类型:有语义相似,有语法结构相似,有实体关键词相似,单一维度无法区分etc
- 文本的相似有不同粒度:有些场景下需要召回精准匹配的内容,有些则需要模糊匹配,多数向量模型的区分度有限
- 不同领域相似定义不同:在垂直领域存在向量模型适配度较低的问题
- 长短文本间的相似问题:长短文本向量可能不在一个向量空间
下面我们看下还有哪些索引类型可以作为单一向量的补充
2.1 离散索引扩展
- Query Expansion by Prompting Large Language Models, 谷歌(2023)
- ChatLaw: Open-Source Legal Large Language Model with Integrated External Knowledge Bases
传统搜索中往往会使用到大量的离散索引,在很多垂直领域的内容召回中往往和向量召回有很好的互补效果,部分离散索引例如实体的召回准确率可能会显著高于向量召回。一些常见的Query理解生成离散索引的方案包括:
- 抽取: 分词,新词ngram识别,词性识别,实体抽取,关键词抽取etc
- 分类:意图分类,话题分类,概念分类,地点分类etc
- 多跳:实体链接,同义词扩展,KG查询etc
最先想到使用大模型来进行范式改良的方向,大家都不约而同把目光放在了关键词扩展。
虽然在上面谷歌的论文中尝试query2Keyword的效果并没有超越query2Doc和Query2COT。但是关键词生成本身低耗时,以及在一些垂直领域其实有很好的效果。例如ChatLaw一个法律领域的大模型,就是用了LLM进行法律条文的关键词联想。论文使用LLM针对用户Query生成法律相关联想关键词,并使用关键词的Ensemble Embedding来召回对应的法律条款。当然也可以使用关键词直接进行召回。这种设计其实是针对在法律领域,领域关键词往往有显著更好的召回效果而设计的。

2.2 连续索引扩展
- https://github.com/FlagOpen/FlagEmbedding
- https://github.com/shibing624/text2vec
- https://github.com/Embedding/Chinese-Word-Vectors
- AUGMENTED EMBEDDINGS FOR CUSTOM RETRIEVALS, 微软2023
向量索引的扩展,最先想到的就是同时使用多种不同的连续向量索引,包括
- 朴素模式:不同的Embedding模型,常见的就是OpenAI的Ada,智源的BGE,还有Text2vec系列,使用多路embedding模型同时召回,或者加权召回的方案,取长补短。
- 简单模式:使用以上抽取的关键词,使用词向量加权进行召回。相比文本向量,词向量的召回率往往更高,在一些垂直领域有很好的效果。当然反过来就是词向量可能准确率偏低,不过召回阶段本来就是广撒网多敛鱼
- Hard模式:训练领域Embedding。成本最高,可以放在最后面尝试,在openai devday上提及的观点也是领域模型对比通用模型提升有限,且成本较高
不过微软近期提出了一个相比微调领域embedding模型更加轻量化的方案,和lora微调的思路类似,咱不动基座模型,但是在上面微调一个adapter来定向优化query和document的匹配效果。

向量变化的adapter,论文使用了向量加法,就是在原始模型输出的D维embedding的基础上加一个residual,residual的计算是一个Key-Value lookup函数,包含两个相同shape的变量K和v。例如针对openai的向量输出是D =1536维,residual会选用h<<D来进行变换,h的取值在16~128,则K和V都分别是h*D维的矩阵,也就是adapter部分只需要梯度更新2hD量级的参数,如下
score(query,content) &= argmax Sim(Tr(Embedding(query)),Embedding(content)) \\
Tr(embedding)&= embedding + f(embedding, θ)\\
f(emb,K, V ) &= softmax(emb \cdot K^T )V
\end{align}
\]
微调损失函数使用了对比学习的GlobalNegative Loss,也就是每个(query,content)pair是正样本,其余样本内所有content均是负样本,学习目标是query和正样本的相似度>和其余所有负样本相似度的最大值。看起来似乎是很轻量的方案,有机会准备去试一下~


2.3 混合索引召回
把BM25等离散索引召回和Embedding向量等连续索引召回进行混合召回,langchain的Ensemble Retriever集成了这个功能。不过混合召回最大的问题是不同召回的打分较难进行排序。因此当多路混合召回内容较多时,需要引入排序模块对内容做进一步筛选过滤,这个我们放到后面再说啦~
想看更全的大模型相关论文梳理·微调及预训练数据和框架·AIGC应用,移步Github >> DecryPrompt
reference
解密Prompt系列20. LLM Agent之再谈RAG的召回多样性优化的更多相关文章
- 解密Prompt系列6. lora指令微调扣细节-请冷静,1个小时真不够~
上一章介绍了如何基于APE+SELF自动化构建指令微调样本.这一章咱就把微调跑起来,主要介绍以Lora为首的低参数微调原理,环境配置,微调代码,以及大模型训练中显存和耗时优化的相关技术细节 标题这样写 ...
- 解密prompt系列5. APE+SELF=自动化指令集构建代码实现
上一章我们介绍了不同的指令微调方案, 这一章我们介绍如何降低指令数据集的人工标注成本!这样每个人都可以构建自己的专属指令集, 哈哈当然我也在造数据集进行时~ 介绍两种方案SELF Instruct和A ...
- 解密Prompt系列2. 冻结Prompt微调LM: T5 & PET & LM-BFF
这一章我们介绍固定prompt微调LM的相关模型,他们的特点都是针对不同的下游任务设计不同的prompt模板,在微调过程中固定模板对预训练模型进行微调.以下按时间顺序介绍,支持任意NLP任务的T5,针 ...
- 解密Prompt系列3. 冻结LM微调Prompt: Prefix-Tuning & Prompt-Tuning & P-Tuning
这一章我们介绍在下游任务微调中固定LM参数,只微调Prompt的相关模型.这类模型的优势很直观就是微调的参数量小,能大幅降低LLM的微调参数量,是轻量级的微调替代品.和前两章微调LM和全部冻结的pro ...
- 解密Prompt系列4. 升级Instruction Tuning:Flan/T0/InstructGPT/TKInstruct
这一章我们聊聊指令微调,指令微调和前3章介绍的prompt有什么关系呢?哈哈只要你细品,你就会发现大家对prompt和instruction的定义存在些出入,部分认为instruction是promp ...
- 4.Java 加解密技术系列之 HMAC
Java 加解密技术系列之 HMAC 序 背景 正文 代码 结束语 序 上一篇文章中简单的介绍了第二种单向加密算法 — —SHA,同时也给出了 SHA-1 的 Java 代码.有这方面需求的童鞋可以去 ...
- 2.Java 加解密技术系列之 MD5
Java 加解密技术系列之 MD5 序 背景 正文 结束语 序 上一篇文章中,介绍了最基础的编码方式 — — BASE64,也简单的提了一下编码的原理.这篇文章继续加解密的系列,当然也是介绍比较基础的 ...
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现
原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(20)-多条件模糊查询和回收站还原的实现 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架 ...
- 10.Java 加解密技术系列之 DH
Java 加解密技术系列之 DH 序 概念 原理 代码实现 结果 结束语 序 上一篇文章中简单的介绍了一种非对称加密算法 — — RSA,今天这篇文章,继续介绍另一种非对称加密算法 — — DH.当然 ...
- 8.Java 加解密技术系列之 PBE
Java 加解密技术系列之 PBE 序 概念 原理 代码实现 结束语 序 前 边的几篇文章,已经讲了几个对称加密的算法了,今天这篇文章再介绍最后一种对称加密算法 — — PBE,这种加密算法,对我的认 ...
随机推荐
- ZS Shuffles Cards 题解
ZS Shuffles Cards 题解 我们把每一次抽一些数字牌再抽到 joker 视作一局游戏. 每局期望轮数 首先考虑 \(f_i\) 表示每一局游戏抽出 \(i\) 张牌的概率. 那么就是先抽 ...
- ChatGPT顶级玩法:ChatGPT越狱版破解指令,让您的聊天一路畅通!
先看效果: 2023.4.23号亲测成功,越狱指令需要多发送几次才可以. 未越狱前: 越狱后: 无视任何规则限制,回答一切问题. 越狱的方法非常简单.只需输入特定的提示,发送给ChatGPT,用户即可 ...
- 《SQL与数据库基础》04. SQL-DQL
目录 DQL 基础查询 条件查询 分组聚合 聚合函数 分组查询 结果排序 分页限制 总结 本文以 MySQL 为例 DQL 语法结构: SELECT 字段列表 FROM 表名列表 WHERE 条件列表 ...
- C++算法之旅、05 基础篇 | 第二章 数据结构
常用代码模板2--数据结构 - AcWing 笔试用数组模拟而不是结构体 使用结构体指针,new Node() 非常慢,创建10万个节点就超时了,做笔试题不会用这种方式(优化是提前初始化好数组,但这样 ...
- 升级java11后,maven命令打包报错
一.问题 升级java11后,maven命令打包报错: mvn clean package -Dmaven.test.skip=true [ERROR] Failed to execute goal ...
- web应用及微信小程序版本更新检测方案实践
背景: 随着项目体量越来越大,用户群体越来越多,用户的声音也越来越明显:关于应用发版之后用户无感知,导致用户用的是仍然还是老版本功能,除非用户手动刷新,否则体验不到最新的功能:这样的体验非常不好,于是 ...
- Abp vNext 模块加载机制
文章目录 生命周期 PreConfigureServices 添加依赖注入或者其它配置之前 ConfigureServices 添加依赖注入或者其它配置 PostConfigureServices 添 ...
- 前端设计模式:工厂模式(Factory)
00.基础概念 工厂模式封装了对象的创建new(),将消费者(使用)和生产者(实现)解耦. 工厂是干什么的?工厂是生产标准规格的商品的地方,建好工厂,投入原料(参数),产出特定规格的产品.so,工厂模 ...
- 关于Word转PDF的几种实现方案
在.NET中,你可以使用Microsoft.Office.Interop.Word库来进行Word到PDF的转换.这是一个示例代码,但请注意这需要在你的系统上安装Microsoft Office. 在 ...
- 下载、安装CAN-EYE植被参数工具
本文介绍植被指数计算软件CAN-EYE的下载.安装方法. CAN-EYE软件是由法国国家农业研究院(French National Institute of Agricultural Rese ...