RAG from scratch: Part 10 (Routing) by LangChain
路由的本质是将经过查询翻译后的问题,根据其内容和特征,导向最合适的处理途径或数据源,以实现高效准确的信息检索和处理。
RAG from scratch: Part 10 (Routing) by LangChain
路由 (Routing)
“路由(Routing)” 指的是一种在系统中引导信息或请求流向特定目标的机制或过程。
路由的本质是将经过查询翻译后的问题,根据其内容和特征,导向最合适的处理途径或数据源,以实现高效准确的信息检索和处理。
一、查询翻译
接收用户输入问题后,最先进行查询翻译。它将用户表述的原始问题,通过特定方法(如逐步提示分解等)转化为更利于检索的形式,改善问题的表达,为后续处理奠定基础。
二、 路由位置
在查询翻译之后。经查询翻译优化后的问题,会进入路由阶段。路由根据问题的内容、特征等,将问题导向合适的数据源(如不同类型数据库、不同文档集合 )或处理路径(如匹配到合适提示 ) ,使后续检索能从恰当资源中获取信息,以支持最终答案的生成。
三、逻辑路由 代码
1. 原理
赋予大语言模型(LLM)有关各类数据源的知识储备,让LLM基于这些知识,运用自身内在逻辑去判定应将问题导向哪个数据源。这一过程类似给LLM设定规则和条件,使其能根据问题特征做出合理决策。
2. 实现步骤
- 构建数据模型:以包含python文档、JS文档、golang文档的简单场景为例,创建一个数据模型,该模型能够与LLM绑定。其作用是限定LLM的输出范围,使输出为特定结构化对象,且该对象只能是预先设定的几个选项(如这三种文档对应的数据源 )之一。
- 转换与绑定:把期望LLM输出的结构化对象定义,转化为开放函数模式,然后将此函数模式传递并绑定到LLM。这样LLM在处理问题时,就会依据这个函数模式进行操作。
- 问题处理与输出:当向LLM提出问题(如python代码相关问题 )时,LLM会调用绑定的函数,生成符合指定模式的输出。例如输出一个代表数据源的对象,该对象是之前设定的Json字符串选项之一。之后,利用解析器将Json字符串解析为具体对象,以确定问题应被路由到哪个数据源(如确定调用python文档 )。
- 后续处理:通过选择路由函数对输出结果进一步处理,将问题连接到对应的检索器链(如python文档对应专门处理python信息的检索器 ),完成整个路由过程。

3. 优势与应用场景
具有很强的通用性,不仅适用于不同编码语言相关数据源的路由选择,还能推广到不同类型数据库(如vector存储、graph db、关系数据库 )等场景。LLM在推理过程中能返回可配对的具体类型对象,方便后续基于对象类型进行针对性推理和处理。
四、语义路由 代码
1. 原理
基于语义相似度进行操作。先将不同提示(如物理提示、数学提示 )进行嵌入处理,然后对待处理的用户问题也进行嵌入,通过计算问题与各个提示之间的相似度,挑选出相似度最高的提示。
2. 实现步骤
- 提示嵌入:对各类提示(如设定的物理提示和数学提示 )进行嵌入操作,为后续计算相似度做准备。
- 问题嵌入与计算:当获取到用户输入问题(如“什么是黑洞” )后,对问题进行嵌入处理,接着计算该问题与已嵌入提示之间的相似度。
- 提示选择:根据计算得出的相似度结果,选取最相似的提示,以此确定问题的处理方向。

3. 优势与应用场景
相较于逻辑路由,语义路由的操作逻辑相对直观。在一些对语义关联度要求较高的场景中表现出色,例如在处理学术领域不同学科问题时,能依据问题语义快速匹配到相关学科的提示,进而找到更合适的处理路径和信息源。

五、视频原文
第二页:我们讨论的是查询翻译,也就是接受问题并以某种方式翻译的过程。它可以使用逐步提示或其它方式进行分解,但这里的想法是将问题转换为更适合检索的形式。现在,路由是下一步,它基本上是将可能分解的问题路由到正确的来源,在很多情况下,这可能是一个不同的数据库。假设在这个例子中,我们有一个向量存储,一个关系数据库和一个图数据库,我们用路由重新做的是根据问题的内容将问题路由到相关的数据源。
第三页:有几种不同方法可以做到这一点,其中一种是我们所说的逻辑路由,在这种情况下,我们基本上为LLM提供有关我们可以使用的各种数据源的知识,然后让LLM自行决定将问题应用于哪个数据源,这有点像LM应用某种逻辑来确定哪个数据存储
第四页:或者,您可以使用语义路由,也就是我们提出一个问题,然后将其嵌入,例如,我们嵌入提示,然后计算问题与这些提示之间的相似度,然后根据相似度选择一个提示。所以,总体思路是,在我们的图表中,我们讨论的是路由到例如不同的数据库,但他可以非常通用,可以路由到不同的提示,也可以任意地将这个问题发送到不同的地方,无论是不同的提示,还是不同的vector。
第五页:所以,让我们稍微浏览一下代码,这样你就可以看到,就像之前我们做了一些pip安装一样,我们已经设置了Lsmith,让我们先讨论一下逻辑路由,所以在这个玩具例子中,假设我们有三个不同的文档,比如python文档,JS文档,和golang文档,我们想要做的是将问题路由到这三个文档中的一个,所以我们实际上在做的是建立一个数据模型,它基本上将绑定到我们的LLM并允许LLM将这三个选项之一输出为结构化对象,因此您可以将其视为分类加上函数调用以生成结构化输出,该输出受限于这三种可能性,因此我们所做的就是稍微放大一下,我们可以定义一个我们想要从LLM中获取的结构化对象,就像在这种情况下,我们想要例如这三个数据源之一作为输出,我们可以接受它,我们实际上将其转换为开放的,例如开放的函数模式,然后我们实际上将其传递进去并将其绑定到我们的LLM,所以会发生什么,我们问一个问题,我们的LM在输出上调用此函数以生成遵循我们指定的模式的输出,因此在这种情况下,例如,我们输出,就像你知道这个玩具示例中,假设我们想要一个输出作为数据源向量存储或SQL数据库,输出将包含一个数据源对象,它将是您指定为Json字符串的选项之一,我们还从该对象实例化一个解析器来解析它,例如,将Json字符串转换为类似于繁琐对象的输出,这只是一个玩具示例,让我们在这里展示一个,在这种情况下,我们再次拥有三个文档源,我们将其绑定到我们的LLM,因此您可以看到我们基本上在底层使用结构化输出,即将对象定义转换为函数模式,并将该函数模式绑定到我们的LLM,我们调用提示,您是一位根据用户所指的编程语言路由用户问题的专家,所以让我们在这里定义路由器,现在我们要做的就是问一个python代码问题,我们将调用它,现在它完成了,您会看到我们得到的对象确实是一个路由查询对象,所以它完全遵循我们设置的这个数据模型,在这种情况下,它是正确的,所以它调用这个python文档,因此我们可以在此处将其提取为字符串,现在我们有了这个,您就可以轻松地设置路由,所以这可能就像我们的完整链条,我们采用应该在这里定义的路由器,然后这个选择路由函数基本上可以获取该输出并对其进行处理,例如,如果python文档中存在这个问题,那么就可以将问题应用到像一个充满python信息的检索器,或者js也是一样,所以在这里,你可以将这个问题连接到不同的链条中,就像你知道的检索器链一用于python,检索器链二用于JS等等,所以这有点像路由机制,但它实际上承担了繁重的工作,将输入问题转换为结构化对象,将输出限制位我们在路由问题中关心的几种输出类型之一,所以这就是所有这些链接在一起的方式。现在,语义路由实际上可能更直接一些,基于我们之前看到的内容,所以在这种情况下,假设我们有两个提示,一个物理提示,一个数学提示,我们可以嵌入这些提示,没问题,我们在这里这样做现在假设我们有一个来自用户的输入问题,比如在这种情况下,什么是黑洞,我们将其传递过去,然后应用这个可运行的lambda函数,它在这里定义。我们在这里做的是嵌入问题,计算问题和提示之间的相似度,我们取最相似的,然后根据相似度选择题诗。您可以看到,让我们运行他并尝试一下,我们使用物理提示,然后是黑洞区域和空间,这样向您展示了如何使用语义路由来嵌入问题,例如,嵌入各种提示,根据语义相似度选择提示,这样实际上就为您提供了两种路由方式,一种是逻辑路由,函数调用,它可以非常普遍地使用,在这种情况下,我们将它应用于不同的编码语言,但想象一下,这些可以互换,例如,我的python,我的vector存储,我的graph db,我的关系数据库,您可以非常简单地了解每个是什么,然后您知道,LLM不仅可以进行推理,而且还会返回一个可以配对的对象。非常清晰地生成一些具体的类型,然后你可以像我们在路由函数中所做的那样进行推理,这样就可以给你一个大概的想法,这些都是非常有用的工具,我鼓励你尝试一下,谢谢。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)