微信扫码
添加专属顾问
一、为什么需要重排序?
检索增强生成(Retrieval Augmented Generation,RAG)技术看似充满无限可能,但在实际应用中,许多人发现构建的RAG系统结果并不尽如人意。
尽管RAG相对容易入门,但要真正掌握其精髓却相当困难。实际上,建立一个有效的RAG系统远不止将文档存入向量数据库并叠加一个大语言模型那么简单。虽然这种方法有时会有效,但并非总能保证成功。
我们知道,RAG 通过在大量文本文档中进行语义搜索来工作,这些文档的数量可能达到数十亿。为了实现大规模搜索的快速响应,我们通常采用向量搜索技术。具体而言,就是将文本转化为向量后,放入一个向量空间内,再通过余弦相似度等度量标准来比较它们与查询向量的相似度。
向量搜索的前提是需要向量,这些向量通常将文本背后的意义压缩成768或1536维的形式,这一过程不可避免地会丢失一些信息。因此,我们常常会发现,即使是排名前三的文档,也可能遗漏了一些关键信息。
在此,我们关注的指标是召回率,即“我们检索到的相关文档的比例”。需要注意的是,召回率不考虑检索到的文档总数。
因此,理论上通过返回所有文档可以实现完美的召回率。然而,这在实际操作中是不可行的,因为大语言模型对可处理的文本量有限制,这个限制称为上下文窗口。
如果较低位置的文档包含了有助于大语言模型更好地形成回答的相关信息,该怎么办?一个简单的方法是增加返回的文档数量(即增加top_k值),并将它们全部传递给大语言模型。但是这样做有一定的条件:
第一,这样做的一个劣势,就是需要消耗更多的token,意味着成本的增加。
第二,尽管大模型拥有高达100K Token的巨大上下文窗口,理论上可以包含大量文档,但我们仍然不能返回所有文档并填满上下文窗口来提高召回率。
第三,当我们在上下文窗口中填充过多内容时,会降低大语言模型在该窗口中检索信息的能力。研究表明,当上下文窗口被过多Token填满时,大语言模型的回忆能力会受到影响。此外,过度填充上下文窗口还会使模型较难按指令执行,因此,这种做法是不可取的。
为了解决这一问题,我们可以通过检索尽可能多的文档来最大化检索召回率,然后通过尽量减少最终传递给大语言模型的文档数量。为此,我们重新排序检索到的文档,并只保留最相关的文档。
二、什么是重排序算法?
重排序模型(也称为Cross-Encoder)是一种能够针对查询和文档对输出相似度分数的模型。通过利用这些分数,我们可以根据文档与查询的相关性对它们进行重新排序。
一个包含两个阶段的检索系统通常在向量数据库(vector DB)阶段采用双编码器(bi-encoder,Bi-Encoder)或稀疏嵌入模型。搜索工程师长期以来在这种两阶段检索系统中使用重排序模型。第一阶段的模型(嵌入模型或检索器)负责从大数据集中提取一组相关文档。随后,第二阶段的模型(重排序器)对提取出的文档进行重新排序。
采用两阶段策略的原因在于,从大数据集中快速检索少量文档的速度远快于对大量文档进行重排序。简而言之,重排序器处理较慢,而检索器速度较快。我们将在后面详细解释其原因。
三、为何选择使用重排序器?
关键在于,重排序器的精确度远超过嵌入模型。
双编码器(bi-encoder)精度较低的根本原因在于,它必须将文档的所有潜在含义压缩成一个向量——这无疑导致了信息的丢失。此外,由于查询是在收到后才知道的,双编码器对查询的上下文一无所知(我们是在用户提出查询之前就已经创建了嵌入)。
而重排序器能够在大型Transformer中直接处理原始信息,这大大减少了信息丢失。由于重排序器是在用户提出查询时才运行,这让我们能够针对具体查询分析文档的含义,而非仅生成一个泛化的、平均化的含义。
重排序器避免了双编码器的信息丢失问题——但它也有代价,那就是时间。
双编码器模型将文档或查询的含义压缩成单一向量。值得注意的是,无论处理的是文档还是查询,双编码器的处理方式相同,都是在用户查询时进行。
使用双编码器和向量搜索时,所有繁重的Transformer计算都在创建初始向量时完成。这意味着,一旦用户发起查询,我们已经准备好了向量,接下来需要做的只是:
运行一个Transformer计算生成查询向量。
使用余弦相似度(或其他轻量度量)将查询向量与文档向量进行比较。
而对于重排序器,我们不进行任何预计算。相反,我们将查询和某个文档直接输入到Transformer中,进行完整的推理步骤,最终生成一个相似度分数。
重排序器通过一个完整的Transformer推理步骤,针对查询和单一文档生成一个相似度分数。请注意,这里的文档A实际上等同于我们的查询。
假设我们的系统有4000万条记录,使用像BERT这样的小型重排序模型在V100 GPU上运行,我们可能需要超过50小时来返回一个查询结果。而采用编码器模型和向量搜索,相同的查询结果可以在不到100毫秒的时间内完成。
四、重排序代码实现
现在我们了解了使用重新排序器进行两阶段检索背后的想法和原因,让我们看看如何实现它,首先,我们将设置我们的必备库:
!pip install -qU \datasets==2.14.5 \openai==0.28.1 \pinecone-client==2.2.4 \cohere==4.27
在设置检索管道之前,我们需要检索数据!我们将使用 Hugging Face Datasets 中的 jamescalam/ai-arxiv-chunked 数据集。该数据集包含 400 多篇关于 ML、NLP 和 LLMs 的 ArXiv 论文,包括 Llama 2、GPTQ 和 GPT-4 论文。
关键代码如下:
from datasets import load_datasetdata = load_dataset("jamescalam/ai-arxiv-chunked", split="train")data
import timeindex_name = "rerankers"existing_indexes = [index_info["name"] for index_info in pc.list_indexes()]if index_name not in existing_indexes:pc.create_index(index_name,dimension=1536,metric='dotproduct',spec=spec)while not pc.describe_index(index_name).status['ready']:time.sleep(1)index = pc.Index(index_name)time.sleep(1)index.describe_index_stats()
def compare(query: str, top_k: int, top_n: int):# first get vec search resultsdocs = get_docs(query, top_k=top_k)i2doc = {docs[doc]: doc for doc in docs.keys()}# rerankrerank_docs = co.rerank(query=query, documents=docs.keys(), top_n=top_n, model="rerank-english-v2.0")original_docs = []reranked_docs = []# compare order changefor i, doc in enumerate(rerank_docs):rerank_i = docs[doc.document["text"]]print(str(i)+"\t->\t"+str(rerank_i))if i != rerank_i:reranked_docs.append(f"[{rerank_i}]\n"+doc.document["text"])original_docs.append(f"[{i}]\n"+i2doc[i])for orig, rerank in zip(original_docs, reranked_docs):print("ORIGINAL:\n"+orig+"\n\nRERANKED:\n"+rerank+"\n\n---\n")53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-07-03
RAG 检索优化策略:从命中率到答案质量的一套工程打法
2026-07-03
RAG 落地总翻车?全球赛事冠军架构,改造适配企业级生产
2026-07-01
提升 RAG 准确率全攻略 让你的 AI 知识库 真正靠谱起来!
2026-06-30
教程:如何用AutoRAG + Milvus避免RAG 与Agent 中出现串租问题
2026-06-30
知识库不是文件堆——我把RAG准确率从60%调到了92%
2026-06-30
本体论语义建设新思路,另类RAG来解决检索问题
2026-06-30
别把RAG当架构:Ontology(本体)才是Agent的业务世界
2026-06-29
PixelRAG:伯克利团队颠覆传统 RAG,用截图代替文本检索! 28 天狂揽 3000+ Star!
2026-04-06
2026-04-27
2026-04-23
2026-04-20
2026-04-09
2026-04-12
2026-04-22
2026-04-10
2026-05-14
2026-04-30
2026-06-23
2026-06-23
2026-06-15
2026-06-10
2026-06-10
2026-05-20
2026-05-18
2026-05-11
欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。
在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。
一、 定义
本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。
会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。
知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。
二、 账号注册与登录
登录方式:本网站支持以下登录方式,您可根据实际情况选择:
微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。
手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。
账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。
实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。
未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。
三、 服务内容与规范
知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。
服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。
禁止行为:您在使用服务时不得实施以下行为:
利用技术手段批量爬取、下载、转存知识库内容;
将知识库内容用于商业目的或未经授权地向第三方传播;
干扰本网站正常运行或侵犯其他用户合法权益;
发布违法违规信息或从事违反公序良俗的活动。
四、 知识产权声明
权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。
有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。
侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。
五、 个人信息保护
我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。
您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。
您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。
六、 免责声明
内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。
不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。
第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。
七、 违约责任
如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。
如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。
八、 法律适用与争议解决
本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。
因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。
九、 其他
本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。
本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。
我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。