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

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

目录

  • 1 基本思想
  • 2 Logical routing
    • 2.1 基本思想
    • 2.2 代码演示
  • 3 Semantic routing
    • 3.1 基本思想
    • 3.2 代码演示

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年代中国的照片"))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/39170.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亲测解决argument --/--list: conflicting option string: --list

在设置一个变量的时候,需要输入一个list。按照教程设置后,如果设置了两个list变量,会出现这个错误。 环境 python3.12 + win11 解决方法 去掉"–list"即可。 Group.add_argument("--xiaohu", "--list", nargs="+",type=int, de…

等保测评应该选择什么样的SSL证书

选择适合等保测评的SSL证书,需考虑证书的加密强度、认证机制以及是否满足国家相关的密码技术要求 1、证书类型:应选择符合国家或行业标准的SSL证书,这些证书通常采用RSA、DSA或ECC等国际认可的加密算法。同时,考虑到国内特定的合规…

使用explain优化慢查询的业务场景分析

问:你最害怕的事情是什么?答:搓澡问:为什么?答:因为有些人一旦错过,就不在了 Explain 这个词在不同的上下文中有不同的含义。在数据库查询优化的上下文中,“EXPLAIN” 是一个常用的 …

基于Hadoop平台的电信客服数据的处理与分析②项目分析与设计---需求分析-项目场景引入

任务描述 需求分析是软件生命周期中一个非常重要的过程,它决定着整个软件项目的质量,也是整个软件开发的成败所在。本环节任务是完成软件需求规格说明书。 知识点 :软件需求规格说明书的编写 重 点 :软件需求规格说明书内容的…

基于gcn的半监督分类代码整理2

一、说明 对论文《Semi-Supervised Classification with Graph Convolutional Network》的代码整理。 第一部分主要说明了数据预处理和初始化等工作,这节主要说明gcn和mlp模型建模以及数据训练过程,以下是笔记和代码逻辑的整理。 注:本人是…

Android启动时间分析

在Android启动过程中,“NHLOS” 和 “LK” 是两个与启动时间相关的术语,它们分别指的是: 各阶段时间 I Minidump: Enabled with max number of regions 200 I KPI : Bootloader start count = 59264 I KPI : Bootloader end count = 101746 I KPI : Boo…

【Spring Boot】spring boot环境搭建

1、环境准备 JDK安装:确保安装了Java Development Kit (JDK) 1.8或更高版本。JDK是Java编程的基础,Spring Boot项目需要它来编译和运行。Maven或Gradle安装:选择并安装Maven或Gradle作为项目构建工具。Maven通过pom.xml文件来管理项目的依赖…

Hbase/Hive连接数过多导致阻塞问题处理

HBase库连接数过多造成库堵塞 netstat -aoe(netstat -tunap| grep 50070)查看主机端口运行状态,可以看到有很多的CLOSE_WAIT。 Hiveserver2连接数过多造成库堵塞 netstat -aoe(netstat -tunap| grep 10000)查看主机端口…

如何在Java中使用JSON:解析与生成

如何在Java中使用JSON:解析与生成 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨在Java中如何使用JSON进行解析和生成&#xff…

Centos7网络配置(设置固定ip)

文章目录 1进入虚拟机设置选中【网络适配器】选择【NAT模式】2 进入windows【控制面板\网络和 Internet\网络和共享中心\更改适配器设置】设置网络状态。3 设置VM的【虚拟网络编辑器】4 设置系统网卡5 设置虚拟机固定IP 刚安装完系统,有的人尤其没有勾选自动网络配置…

Qt/C++开发经验小技巧296-300

国内站点:https://gitee.com/feiyangqingyun 国际站点:https://github.com/feiyangqingyun 官方店:https://shop114595942.taobao.com// 公众号:Qt实战,各种开源作品、经验整理、项目实战技巧,专注Qt/C软件…

弹出解锁登陆密钥环对话框提示解决方法

可能原因及角:(重启生效) 原因一:设置自动登录,取消自动登陆后 执行sudo rm -rf ~/.local/share/keyrings/* 命令删除配置文件 原因二:系统缺少依赖文件,执行 sudo apt-get update &&…

MeowBot:ESP32 语音控制宠物猫 DIY 教程——玩转语音识别与 MQTT 智能家居控制 (附代码解析)

摘要: 本文将手把手教你打造一只名为 MeowBot 的智能宠物猫!它不仅可以通过舵机灵动地打招呼,还能听懂你的语音指令,帮你控制智能家居设备。让我们一起开启这段充满乐趣的 DIY 之旅吧! 关键词: ESP32、语音识别、MQTT、智能家居、…

SpringSecurity中文文档(Servlet RememberMe)

Remember-Me Authentication Remember-me 或持久登录身份验证指的是网站能够在会话之间记住主体的标识。这通常是通过向浏览器发送 Cookie 来完成的,Cookie 将在以后的会话中被检测到,并导致自动登录的发生。Spring Security 为这些操作提供了必要的钩子…

RS232、RS485与RS422初步学习

目录 电平 传输方式 共模和差模干扰 ps:双绞线 485总线结构 ps:终端电阻 RS232接口(DB9) 优缺点 RS232优缺点 RS485较RS232的优点 为什么RS232还在使用? 电平 RS232、RS485与RS422的电平 区间逻辑备注RS232…

巧用Fiddler中的Comments提升接口测试效率

有没有同学在使用Fiddler时跟我遇到了同样的问题,就是想给某个抓包的请求进行注释!!!但是奇怪的是,根本没有Comments相关信息呀? 设置Comments 设置Comments非常容易,选中一个请求&#xff0c…

基于ESP32 IDF的WebServer实现以及OTA固件升级实现记录(一)

webserver即运行在esp32上的web服务,相当于esp32作为web服务器,它可以处理web浏览器等客户端的http相关请求(常见的get/post/put等http方法)。 ota即在线固件升级,idf已经提供了丰富的官方ota示例,不过主要…

mybatis多数据源操作

最近项目,一个后端代码被两个前端页面调用,代码数据库都冗余了,写着很难受感觉跟吃狗屎一样。因此决定先把数据库分开,然后之后把项目分成多模块化得。 想把数据库分开其实就只是需要实现多数据源操作,我考虑得不多&a…

DSPy的BootstrapFewShot

这是官方文档 官方文档给示例数据的量划分了10/50/300等档位,对应BootstrapFewShot/BootstrapFewShotWithRandomSearch/MIPRO. 我们以10条示例数据example为例,即选用BootstrapFewShot DSPy认为用原始数据直接做few-shot效果不好的原因是:…

Golang-context理解

golang-context笔记整理 golang为何设计context?代码上理解原理空context类cancelCtx类.withcancelctx方法 timerCtx类valueCtx类 golang为何设计context? 有并发特性的语言中,都会有一种说法:创建异步线程或者携程的时候&#x…