首页 > 其他分享 >检索增强生成RAG系列5--RAG提升之路由(routing)

检索增强生成RAG系列5--RAG提升之路由(routing)

时间:2024-07-02 13:27:31浏览次数:3  
标签:RAG prompt -- question routing import 路由

在系列3和系列4我讲了关于一个基本流程下,RAG的提高准确率的关键点,那么接下来,我们再次讲解2个方面,这2个方面可能与RAG的准确率有关系,但是更多的它们是有其它用途。本期先来讲解RAG路由。

目录

1 基本思想

说起路由我们最熟悉不过,无论是代码中通过switch语句或者网络中通过网关等方式,我们可以实现代码逻辑或者一个请求去分发到不同的模块或者服务中。那么RAG的路由又有什么不一样。
我们知道传统的路由可能是通过匹配字符串内容相同的模式去分发的,但是RAG路由是通过大模型语义去做匹配,也就是通过理解请求或者查询的字符串的语义去匹配对应的分发

在这里插入图片描述

RAG routing某种程度上可以提高RAG的准确率,但是其更大的功能是提升整个RAG系统的功能性。因为通过语义理解之后,后面的操作可能是通过不同路由到不同数据源、或者调用API工具、甚至是其它Agent等等,这样你的RAG就更为丰富,因此RAG routing的作用如下:

  • 增加RAG系统功能丰富度。你可以增加多种数据库查询、可以增加多种API、可以增加多个Agent等等,常见于搜索助手、客服系统、问答系统等等
  • 解耦RAG与其它系统。其实路由一般都有解耦的作用,你可以一个模块一个模块的上线,比如开始你的搜索系统只是一个文本搜索,后面慢慢可以增加图片生成、语言生成、翻译等功能,而且是以模块化方式
  • 提高RAG准确度。这个前面已经提到过,如果你的RAG只是一个基于某个数据库检索后生成答案,有可能你的数据库知识有限,搜索不到相关信息,这是你可能需要去网上找其他资料等等,这样可能能更好提高你的RAG准确度

一般来说,基于语义理解的RAG routing分为2种不同实现模式:

  • Logical routing:使用大模型对问题进行推理,通过理解的内容并选择更合适的方式。
  • Semantic routing:将问题和一组prompt向量化,让后计算其相似性选择合适的prompt。

2 Logical routing

2.1 基本思想

这是一种基于大模型的推理能力,将你要查询的问题进行逻辑推理,最终选择选项中最为接近的答案,当然有可能答案中并不存在,那么我们可以设置一些兜底方案,比如直接回答不知道。步骤如下:

  • 让大模型对问题进行语义分析,选出对应选项
  • 通过选项,进入路由引擎,对其进行路由选择最终操作

在这里插入图片描述

2.2 代码演示

这里只是简单演示以下流程,通过一个prompt,让大模型分析问题语义,给出路由的选项,然后再通过路由函数进行选择最终操作。其中prompt和路由函数在实际应用中就是更为复杂或者使用路由引擎来代替。

前置条件

  • 这里采用智谱AI的API接口,因此可以先去申请一个API KEY(当然你使用其它模型也可以,目前智谱AI的GLM4送token,就拿它来试验吧)
from langchain_openai import ChatOpenAI
from langchain_core.runnables import RunnableLambda
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser


# 前置工作:创建llm
llm = ChatOpenAI(
    temperature=0.01,
    model="glm-4",
    openai_api_key="你的API KEY",
    openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)

# 第一步:通过大模型进行对问题的语义分析,将结果返回出来
system = """根据用户的问题,将其分类为:'python代码问题'、'java代码问题'、'js代码问题'。如果无法分类,则直接回答不知道。

问题:{question}
输出格式直接返回选项内容
"""
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", system),
        ("human", "{question}"),
    ]
)
router = prompt | llm | StrOutputParser()
question = """为什么下面这段代码报错,错误信息是System.out.printIn找不到

public class HelloWorld {
    public static void main(String[] args) {
		System.out.printIn("Hello World");
	}
}

"""
response = router.invoke({"question": question})
print(response)


# 第二步:根据返回结果,进行router选择,这里是将前面第一步也串联起来
def route_fun(result):
    if "python代码问题" in result:
        return "由python文档库查询"
    elif "java代码问题" in result:
        return "由java文档库查询"
    elif "js代码问题" in result:
        return "由js文档库查询"
    else:
        return "无法识别"


final_chain = router | RunnableLambda(route_fun)
print(final_chain.invoke({"question": question}))

3 Semantic routing

3.1 基本思想

这个方法是将问题和一组prompt向量化,让后计算其相似性选择合适的prompt。其实在前面问题优化中,问题在向量数据库中查询最接近答案的方式是一样的,只不过将向量数据库和相似度用于路由选择。步骤如下:

  • 将问题和一组事先准备好的prompt向量化
  • 对其问题与prompt直接计算相似度,取最相似的一个

在这里插入图片描述

3.2 代码演示

这里使用m3e-base的embedding模型将一组prompt向量化,再将查询问题向量化,计算其相似度,获得相似度最高的结果。

前置条件

  • 下载m3e-base的embedding模型
from langchain.utils.math import cosine_similarity
from langchain_core.prompts import PromptTemplate
from langchain_core.runnables import RunnableLambda, RunnablePassthrough
from langchain_huggingface import HuggingFaceEmbeddings


# 前置工作:初始化embeddings模型
encode_kwargs = {"normalize_embeddings": False}
model_kwargs = {"device": "cuda:0"}
embeddings = HuggingFaceEmbeddings(
    model_name='/root/autodl-tmp/model/AI-ModelScope/m3e-base',  # 换成自己的embedding模型路径
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

# 第一步:将一组prompt进行向量化
search_template = """你是一个智能搜索机器人。
你可以通过搜索互联网内容结果并总结出最终答案。但搜索无结果是,请回答不知道

这里有一个问题:
{question}"""

picture_template = """你是一个图片生成机器人。
你很擅长将文本内容生成图片。

这里有一个问题:
{question}"""
prompt_templates = [search_template, picture_template]
prompt_embeddings = embeddings.embed_documents(prompt_templates)


# 第二步,计算相似度
def similarity_fun(question_temp):
    # 将问题向量化
    query_embedding = embeddings.embed_query(question_temp["question"])
    # 计算相似度
    similarity = cosine_similarity([query_embedding], prompt_embeddings)[0]
    most_similar = prompt_templates[similarity.argmax()]
    # 选择结果
    print("使用 搜索Agent" if most_similar == search_template else "使用 文生图Agent")
    return PromptTemplate.from_template(most_similar)


chain = (
    {"question": RunnablePassthrough()}
    | RunnableLambda(similarity_fun)
)

print(chain.invoke("请生成一种80年代中国的照片"))

标签:RAG,prompt,--,question,routing,import,路由
From: https://blog.csdn.net/linwu_2006_2006/article/details/140091064

相关文章

  • GPT-4o文科成绩超一本线,理科为何表现不佳?
    目录01评测榜单02 实际效果什么?许多大模型的文科成绩竟然超过了一本线,还是在竞争激烈的河南省?没错,最近有一项大模型“高考大摸底”评测引起了广泛关注。河南高考文科今年的一本线是521分,根据这项评测,共有四个大模型的分数大于或等于这个分数,其中最值得关注的是前两名:......
  • steam游戏商城怎么共享游戏给好友?最详细的操作方法介绍
    在Steam平台上共享游戏给好友,实际上是通过Steam的家庭图书馆共享功能实现的。这允许你在一个家庭内与最多五位家庭成员共享你的游戏库,但他们必须使用同一台电脑。请注意,你不能直接将游戏共享给不在同一物理位置的好友。以下是启用家庭图书馆共享的步骤:1.登录Steam:首先,确保你......
  • 诺森德塔防游戏启动故障:msvcp110.dll文件缺失的高效解决策略
    《诺森德塔防》是一部以二战为背景的“肉鸽塔防”游戏,拥有着极为火爆的战场表现,让你能充分感受到收割成片敌人的快感,同时在玩法及策略性上都有着突出表现,然而最近很多用户都遇到了启动故障:msvcp110.dll文件缺失的问题,下面一起来看看解决方法介绍吧!重新安装MicrosoftVisualC......
  • ros -slam - microros- PID控制器实现
    上一节我们通过编码器完成了对机器人单个轮子的速度测量,完成了电机速度闭环控制的重要一步-反馈。 有了反馈,接着我们需要设计一个控制器来帮助我们实现这个需求,这个控制器的输入是当前的速度和目标速度,输出是应该给到电机的PWM占空比。一、PID控制器介绍PID控制器是一种广泛应......
  • Swin Transformer:最佳论文,准确率和性能双佳的视觉Transformer | ICCV 2021
    论文提出了经典的VisionTransormer模型SwinTransformer,能够构建层级特征提高任务准确率,而且其计算复杂度经过各种加速设计,能够与输入图片大小成线性关系。从实验结果来看,SwinTransormer在各视觉任务上都有很不错的准确率,而且性能也很高 来源:晓飞的算法工程笔记公众号论......
  • vim学习笔记——三种基本模式和相关操作
    vim的三种模式一般模式以vim打开一个文件就直接进入一般模式了。在这个模式中,你可以使用hjkl按键移动光标,也可以使用删除字符或删除整行来处理文件内容,也可以使用复制粘贴处理文件内容。编辑模式在一般模式中按下A,a,I,i,O,o,R,r任何一个按键,就可以进入编辑模式,在界面左下方会......
  • vmdk to vhdx 虚拟磁盘格式转换qemu-img
    qemu-img是创建、转换、修改磁盘映像的工具,我们可以用它非常方便的转换虚拟磁盘格式,比如在vmdk、vhdx、qcow2、vdi之间相互转换,它在流行的Linux、macOS、Windows平台上都发布有对应的版本。本文介绍的是Windows版本,它支持下图中所示的格式。转换格式需要使用它的convert命令,为......
  • NAML论文阅读笔记
    NeuralNewsRecommendationwithAttentiveMulti-ViewLearning论文阅读笔记这篇也是比较老但是比较经典的文章,来读一下Abstract​ 现有的新闻推荐方法通常基于单一的新闻信息(如标题)来学习这些表征,这可能是不够的。在本文中,我们提出了一种神经新闻推荐方法,它可以通过利用不......
  • C-特性和新特性
    C++特性和新特性C++11C++11是C++编程语言的一个重要标准版本,是C++98标准发布后13年来的第一次重大修正,它引入了许多新特性和改进,极大地增强了C++语言的表达能力和开发效率。C++11是C++编程语言的一个重要标准版本,由国际标准化组织(ISO)和国际电工委员会(IEC)旗下的C++标......
  • 如何在Oracle、MySQL、PostgreSQL中改变SQL提示格式
    HowtoChangeinSQLPromptformatinOracle,MySQL,PostgreSQL像UNIX的PS1环境变量可以改变shell操作提示符,在日常工作环境中可以提升一些效率可以防止一些误操作,很多年前在看tom关于在练习oracle操作前的一些环境配置像login.sql,比起”SQL>”还可以显示当前的用......