LangChain 动态任务分发:开启大模型任务流的巅峰之术(三)
续文之言:
继
掌握大模型高效任务流搭建(一):构建LangChain任务流_大模型任务链定制-CSDN博客
掌握高效大模型任务流搭建术(二):链式流程如何赋能 AI 处理能力提升-CSDN博客
接下来,让我们深入探究 LangChain 中的 Router Chain —— 这一强大工具能够依据不同的问题,精准地匹配并选择相应的提示词模板。
一:Router Chain 使用指南
在 LangChain 的强大生态中,Router Chain 以其独特的功能脱颖而出,成为实现任务精准分发的关键利器。它能够依据输入内容的特性,智能地将任务分配给最适合的链(Destination Chain)进行处理。倘若输入内容未能匹配到任何既定的目标链,Router Chain 则会无缝切换至默认链(Default Chain)进行处理。这种灵活而高效的设计,使其在面对多类型问题或任务时,能够游刃有余地应对各种复杂场景,例如根据不同用户输入的问题类别,精准调用相应的模型提示或算法。
1:Router Chain 的核心架构清晰而精妙
主要由以下几个关键部分构成:
1.1Router Chain :
作为整个任务分发流程的“大脑”,它负责对输入内容进行分析和判断,从而决定调用哪一个目标链(Destination Chain)来处理当前任务。它就像是一个智能的“交通指挥官”,根据任务的性质和需求,将其精准地引导至对应的处理通道。
1.2Destination Chain:
这些是为特定任务量身定制的链,它们各自专注于处理某一类特定的问题或任务。例如,针对数学问题的链能够运用专业的数学模型和算法进行精准求解;而物理问题的链则具备处理物理现象和规律分析的能力。每一个 Destination Chain 都是针对特定领域或问题类型的专家,能够高效地完成其擅长的任务。
1.3Default Chain :
当输入内容无法归类到任何已定义的类别时,Default Chain 就会发挥其兜底的作用。它就像是一个“万能备用方案”,确保即使在面对未知或无法明确分类的任务时,系统也能够提供一个基本的处理方式,避免任务因缺乏合适的处理链而陷入停滞。
那为了能够让模型能够进行判定,我们其实有几个预先的工作需要完成。
2. 精准定位各学科场景,定制专属模板字符串
在大模型的应用过程中,精准的角色定位与场景匹配至关重要。不同的场景对大模型的输出风格与内容深度有着截然不同的需求。以编程问题为例,我们期望大模型化身为资深程序员专家,能精准剖析代码问题、提供高效的解决方案;而在学习辅导场景下,我们则希望大模型扮演一位循循善诱的老师,用通俗易懂、富有启发性的方式帮助我们理解知识要点。正因如此,我们首要的任务便是全面梳理并明确需要设置的各类场景,为后续的模板定制奠定坚实基础。
3. 构建 prompt_infos:整合学科模板信息,助力精准链路匹配
在完成各学科模板字符串的定义后,为了让大模型能够高效、准确地判断问题所对应的模板,我们需要为每个学科搭建一个专属的目标链。这个目标链的核心功能在于清晰阐述每个链的职责与作用,便于大模型在判定问题归属后,精准调用对应的链进行处理。
而 prompt_infos 正是实现这一功能的关键载体。它本质上是一个列表,列表中的每个元素都是一个字典,详细记录了以下关键信息:
3.1 name :
作为唯一标识,明确对应学科的名称或目标提示(destination),确保每个学科链都能被准确识别。
3.2description :
对目标链的职责与功能进行简要而清晰的描述,让大模型快速了解每个链的处理范畴。
3.3 prompt_template:
即之前精心定义好的模板字符串,为每个学科链提供专属的处理模板。
这些信息将作为构建对应链(chain)的基础,后续大模型将依据这些详尽的描述,精准匹配问题与链路,确保任务处理的高效与准确。
4. 组装目标链(destination_chains)
下一步我们就需要导入一些Router Chain里必要的库。并把我们需要用来判断具体是使用哪一个合适的提示词的大模型也进行导入。
然后我们就可以开始对 destination_chains
进行组装了,那首先我们需要先初始化一个空的字典,它会用来存放“不同学科对应的 LLMChain”
比如说这个 destination_chains
可能得到的结果是:
这样我们可以通过 destination_chains["physics"]
快速调用到物理学回答所用的链,destination_chains["math"]
调用到数学回答所用的链,以此类推。
然后我们可以根据前面定义的 prompt_infos
来提取我们所需要的信息了。那首先我们通过for循环对 prompt_infos
这个列表进行遍历,里面每个元素(p_info
)都是一个字典。在循环里,我们依次取出这些信息来构建对应的链。
通过字典的操作把
prompt_infos
里所有学科/领域的名字(name)以及当前学科所使用的“提示模板字符串”(prompt template)都提取出来
可以借助 `ChatPromptTemplate.from_template(...)` 方法,将之前获取的纯文本形式的 `prompt_template` 进行封装,转化为一个专门用于“聊天模型对话”的 Prompt 对象。简单来说,这一步操作实现了从“字符串模板”到“能够嵌入用户问题的聊天 Prompt” 的转变。在此基础上,进一步创建 LLMChain 实例,将已经初始化完成的大语言模型对象 llm 与新生成的 prompt 结合起来。通过这一组合,就能得到一个具备执行能力的链对象。后续只需调用 `chain.run("用户问题")`,即可向大语言模型发起请求,并顺利获取到相应的回答。
最终,我们可以将“学科名与对应的链”这一映射关系存储到名为 `destination_chains` 的字典中。以 `name = "physics"` 为例,我们会将对应的 `LLMChain` 实例赋值给 `destination_chains["physics"]`。这样一来,`destination_chains` 字典将涵盖多个键值对,涵盖了诸如物理、数学、历史、计算机科学等多个学科领域。通过这种方式,我们构建了一个总路由机制,能够根据不同的学科问题,精准地将其分流到相应的链进行处理,从而实现高效的任务分发与管理。
最终我们就可以把这个“学科名 -> 对应的链”存到字典 destination_chains
里。例如,若 name = "physics"
,则 destination_chains["physics"] = <对应的LLMChain>
。 destination_chains
会包含多个键值对(分别是物理、数学、历史、计算机科学等),实现“一条总路由,不同学科分流”的效果
从本质上讲,`destination_chains` 就像是一个指挥中心的调度字典,它精准地映射着“学科名称”与“对应的 LLMChain”之间的关系。在后续的“多Prompt路由”(MultiPromptChain)流程中,当路由器经过分析判定某个问题属于物理学范畴时,它便能迅速且准确地调用 `destination_chains["physics"]` 这条链,从而高效地获取针对该问题的回答。
5. 配置 destinations 和 destinations_str
这两个变量主要服务于“Router Chain”。Router Chain 需要明确知晓可供选择的学科范围(例如物理、数学、历史、计算机科学等),以及每个学科的简要描述,以便准确地将问题分配到合适的链。
在 LangChain 的应用中,`destinations_str` 是一个拼接而成的字符串,它通常会被嵌入到一个“Router Prompt”中。这个提示的作用是告知模型:“以下是可供选择的目的地,请根据用户的问题选择一个。” 基于输入问题,模型能够判断出应该选择“physics”、“math”,或者在无法匹配时选择“DEFAULT”。
为了构建这样一段描述性的文本,我们首先需要利用列表推导式(list comprehension),遍历 `prompt_infos`。在每次循环中,从 `p` 中提取 `p['name']` 和 `p['description']`,并将它们组合成一段描述性的字符串,例如 “physics: 适合回答有关物理的问题”。
把所有拼好的字符串存到一个列表 destinations
里。因此,如果 prompt_infos
中有四个学科,destinations
就是一个含四个字符串的列表。
我们就可以将上一步得到的字符串列表,用换行符 \n
连接成一个大的多行字符串。
我们会得到:
这个多行字符串后续会在 MULTI_PROMPT_ROUTER_TEMPLATE
中用到,用于告诉模型:“我们有哪些可选目标?每个目标的用途是什么?”
6. 构建默认提示词 default_prompt
及链 default_chain
那除了特定场合的提示词以外,那其实我们也是需要准备上假如问题不是特定场景的话,就应该让模型去调用默认的提示词及链。那这个默认的提示词其实就不需要加上任何处理,只需要直接输入问题即可。
记住:"destination" 必须是以下候选提示的名称之一, 或者如果输入不适合任何候选提示,可以选择 "DEFAULT"。 记住:"next_inputs" 可以是原始输入内容, 如果你认为不需要任何修改。
<< 候选提示 >> {destinations}
<< 输入 >> {{input}}
<< 输出 (记得包含 ```json)>>"""
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format( destinations=destinations_str )
7. 组装 Router Chain 与 Destination Chain 构建 MultiPromptChain
至此,我们已经准备好了所有关键组件,接下来只需将这些部分巧妙地组合起来,即可打造出功能强大的 MultiPromptChain。
8. 使用 chain.run()
进行测试调用
在构建完router_chain后,我们就可以拿几个问题来进行测试了。比如我们问一下“1+1等于几”这个问题。
小结
在本节中,我们深入探索了 LangChain 的 Router Chain,解锁了动态任务分发的高效秘籍。通过精心设计不同场景下的提示词模板,并构建对应的目标链,系统能够依据用户的输入精准地挑选出最契合的链进行处理。即便面对无法精准匹配目标链的输入,兜底的默认链也能确保问题妥善解决。这种设计不仅极大地提升了系统的灵活性与准确性,更使其在教育、客服以及多任务处理等诸多领域大放异彩,充分彰显了模块化与动态化所蕴含的强大能量。