检索增强生成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,一经查实,立即删除!

相关文章

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

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

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

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

【Spring Boot】spring boot环境搭建

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

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

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

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

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

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

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

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示例,不过主要…

Golang-context理解

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

【TS】TypeScript 入门指南:强大的JavaScript超集

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 TypeScript 入门指南:强大的JavaScript超集一、TypeScript 简介1.1 …

SpringBoot实现图片添加水印(完整)

提示:昨天不是写了一个类似与图片添加水印的版本吗,今天来写一个带数据库,并且可以完整访问的版本 文章目录 目录 文章目录 引入库 配置文件 数据库配置 字段配置 索引配置 数据库表语句 启动文件 前端代码 整体代码目录 配置类AppConfig Contro…

用可视化的方式学统计学

本次分享一个统计学学习工具:看见统计。 看见统计致力于用数据可视化 (使用D3.js完成) 让统计概念更容易理解,源于布朗大学几位作者👇 看见统计共有6个章节, 下面来看看具体内容, 中心极限定理 对于一个(性质比较好的)分布,如果我们有足够大的独立同分布的样本,其…

Java高级重点知识点-19-Lambda

文章目录 Lambda表达式函数式编程思想Lambda表达式写法代码讲解 Lambda表达式 函数式编程思想 强调做什么,而不是以什么形式做。 以函数式接口Runnable为例讲解: public class LambdaDemo {public static void main(String[] args) {Runnable runnab…

C语言实现简单的minishell

探索开源项目:MiniShell 引言 在计算机编程的世界里,Shell 是一个至关重要的组成部分,它允许用户与操作系统交互,执行命令和程序。MiniShell 是一个简化版的 Shell 程序,通常用于教学和学习目的。在本文中&#xff0…

《梦醒蝶飞:释放Excel函数与公式的力量》8.2 COUNTA函数

8.2 COUNTA函数 COUNTA函数是Excel中用于统计指定区域内所有非空单元格数量的函数。它能够统计数值、文本、错误值以及公式返回的结果,是数据分析中常用的统计工具。 8.2.1 函数简介 COUNTA函数用于统计指定区域中所有非空单元格的数量。它与COUNT函数不同&#…

创新校园服务模式 跑腿小程序平台源码构建与实践 前后端分离 带完整的安装代码包以及部署教程

系统概述 本项目是一个集任务发布、接单、支付、评价于一体的跑腿服务小程序平台,专为高校校园设计。系统采用前后端分离架构,前端负责用户界面展示和交互逻辑,后端处理业务逻辑、数据存取等,两者通过API接口进行通信&#xff0c…

二叉树的右视图-二叉树

199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 层序遍历&#xff0c;广度优先 queue先进后出&#xff0c;每层从左往右进树&#xff0c;最后一个就是最右边的数&#xff1b;pop掉这层的。push下一层&#xff1b; class Solution { public:vector<int> r…

楼层分户项目分析

文章目录 1. 区域绘制2. 户型切分3. 楼房分层4. 编辑房户信息5. 查看房户信息6. 数据库6.1. 楼栋数据库6.2. 单位数据库 7. 房户数据库 1. 区域绘制 点击绘制图形&#xff0c;激活画笔&#xff0c;右键结束绘制。 输入框可以更换地址前缀。 分户坐标是由绘制的多个点组成的&…

深度学习笔记: 最详尽解释混淆矩阵 Confusion Matrix

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家&#xff01; 混淆矩阵 假设我们有包含临床测量数据的医疗数据&#xff0c;例如胸痛、良好的血液循环、动脉阻塞和体重…