• Langchain Chain - RouterChain 根据输入相关性进行路由的路由链


    原文:Langchain Chain - RouterChain 根据输入相关性进行路由的路由链 - 知乎

    目录

    收起

    一、什么是RouterChain?

    二、MultiPromptChain

    三、LLMRouterChain

    四、过程回顾

    五、关于”玩转Langchain“

    上节链接:Langchain Chain - 连接一切工具,创造更复杂的应用! (zsxq.com)

    通过上一节,我们介绍了什么是Langchain框架的Chian,它可以做为AI应用的底座,通过连接不同的工具,创造功能复杂的应用;同时,我们还介绍了Chain中最基础的类型 —— LLMChain。

    本节开始,我们将介绍其他更复杂的Chain,以及来讲一讲它们的应用场景,让我们先从RouterChain开始吧!

    一、什么是RouterChain?

    让我们回顾目前所学的内容,我们能够创建一个llmchain,从中放置一个prompt模板,这个chain能够接收一个用户input,并输出一个结果;如果我们想让它成为某个方向的专家机器人,我们可以为它接入一个外部数据源,使用LLMchain,接入一个txt文本,并在chain中接入一个文档检索器就已经能完成这个需求了,我们会在什么场景需要用到RouterChain呢?

    我们来考虑这样一个需求:如果我们想设定的专家机器人不仅仅是用于某一个专业领域,而是多个专业领域,那我们岂不是要复制n个这样的chain,并且每个接入不同的txt文本?

    没错,在这样的场景下,就会需要用到RouterChain了!根据Langchain的介绍,Router Chain往往会配合下游的destination chain一起使用,成为“一个网关路由+多个下子链”的架构,其能根据user input自动路由到最相关的下游chain:

    上图中是一个RouterChian使用场景的示意图,我们可以看到,一个RouterChain连接了多个下游的子链,每个链都是一个小应用,当RouterChain接收用户的输入,其可以根据用户输入路由到和输入最相关的子链上,并由子链产生输出;例如,用户输入是“请帮我写一首诗”,当RouterChain接收后,会自动路由到“诗人”这个子链,由它来输出结果。

    通过RouterChain,我们可以创建一个能解决多种复杂问题的AI应用。

    根据Langchain的介绍,一个标准的RouterChain应用应包含两个标准组成部分:

    1. 路由链RouterChain:其本身就是一个chain应用,能够根据用户输入进行下游子链的选择;Langchain框架提供了多种RouterChain,其中着重介绍了LLMRouterChain  EmbeddingRouterChain两种:

    - LLMRouterChain 将用户输入放进大语言模型,通过Prompt的形式让大语言模型来进行路由

    - EmbeddingRouterChain 通过向量搜索的方式,将用户输入

    2. 子链DestinationChain:直译为目标链,即可路由到的链,按照上图,我们会存在4个目标链,分别是lawyer chain,sales chain,english teacher chain 和 poet chain

    二、MultiPromptChain

    当我们配置好路由链和下游子链,我们需要把这两个链通过一个 MultiPromptChain 来进行连接,先让我们来看看Langchain框架提供的MultiPromptChain把!

    Langchain提供的MultiPrompt包含以下必传参数:

    router_chain:接收一个RouterChain实例,作为路由链进行路由

    default_chain:接收一个LLMChain实例,当Router Chain无法找到合适的下游子链时,会自动路由到的默认链,可以认为是一个兜底备选链

    destination_chains:接收一个Mapping[str, LLMChain] 字典,key为可以路由到的destination chain的名称,value为该destination chain的LLMChain实例

    此外,还有其他主要的可选参数:

    memory: 接收一个BaseMemory实例,能为路由链添加上下文记忆

    verbose: bool值,若为True则会打印该链的调用过程

    接下来我们再来看看两类RouterChain。

    三、LLMRouterChain

    LLMRouterChain 将用户输入放进大语言模型,通过Prompt的形式让大语言模型来进行路由,如果采用该chain作为RouterChain,那么需要传入两个核心的参数,作为基底的大语言模型,和用作路由的 prompt。

    使用LLMRouterChain进行路由时的Prompt可能会比较复杂,因为其包含对用户输入的解析,对路由的指引,同时要约束其输出必须要是MultiPromptChain能够解析的;Lanchain这里提供了一个 MULTI_PROMPT_ROUTER_TEMPLATE ,通过这个template的.format() 方法可以直接生成能被MultiPromptChain使用的 router_prompt;当然,.format()方法的格式化也是有一定模板的,我们可以直接根据以下流程来创建router_prompt:

    1. 首先,定义4个子链prompt模板

    1. lawyer_template = """ 你是一个法律顾问,你需要根据用户提出的问题给出专业的法律意见,如果你不知道,请说"我不知道",请不要提供超出文本范围外的内容,也不要自创内容。
    2. 用户提问:
    3. {input}
    4. """
    5. sales_template = """ 你是一个销售顾问,你需要为用户输入的商品进行介绍,你需要提供商品基本信息,以及其使用方式和保修条款。
    6. 用户输入的商品:
    7. {input}
    8. """
    9. english_teacher_template ="""你是一个英语老师,用户输入的中文词汇,你需要提供对应的英文单词,包括单词词性,对应的词组和造句。
    10. 用户输入的中文词汇:
    11. {input}
    12. """
    13. poet_template=""" 你是一个诗人,你需要根据用户输入的主题作诗。
    14. 用户输入的主题:
    15. {input}
    16. """

    2.接下来,我们要创建一个“路由目录”,这个目录会记录子链名称,子链描述和子链prompt template,构造这个目录的目的主要有有两个,一个便于创建子链,另一个是便于生成路由链用于路由的PromptTemplate

    1. prompt_infos = [
    2. {
    3. "name": "lawyer",
    4. "description": "咨询法律相关问题时很专业",
    5. "prompt_template": lawyer_template,
    6. },
    7. {
    8. "name": "sales",
    9. "description": "咨询商品信息时很专业",
    10. "prompt_template": sales_template,
    11. },
    12. {
    13. "name": "english teacher",
    14. "description": "能够很好地解答英语问题",
    15. "prompt_template": english_teacher_template,
    16. },
    17. {
    18. "name": "poet",
    19. "description": "作诗很专业",
    20. "prompt_template": poet_template,
    21. },
    22. ]

    3. 接下来,我们要为创建MULTI_PROMPT_ROUTER_TEMPLATE做准备

    1. #创建一个list储存对应的子链名称和描述
    2. destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
    3. #把描述连接成一个str
    4. destinations_str = "\n".join(destinations)

    destinations_str 输出的文本如下,这个格式就是MultiPromptRputer Tempalte接收格式化的文本摹本:

    lawyer: Good for answering questions about law
    sales: Good for answering sales questions
    english teacher: Good for answering english teaching questions
    poet: Good for making poet

    4. 接下来使用 MULTI_PROMPT_ROUTER_TEMPLATE.format() 进行格式化

    1. from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE
    2. router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str)

    格式化完毕后,其会生成一个str,这个字符串能作为prompt template了,我们来打印以下router_template

    Given a raw text input to a language model select the model prompt best suited for the input. You will be given the names of the available prompts and a description of what the prompt is best suited for. You may also revise the original input if you think that revising it will ultimately lead to a better response from the language model.


    << FORMATTING >>
    Return a markdown code snippet with a JSON object formatted to look like:
    ```json
    {{
    "destination": string \ name of the prompt to use or "DEFAULT"
    "next_inputs": string \ a potentially modified version of the original input
    }}
    ```


    REMEMBER: "destination" MUST be one of the candidate prompt names specified below OR it can be "DEFAULT" if the input is not well suited for any of the candidate prompts.
    REMEMBER: "next_inputs" can just be the original input if you don't think any modifications are needed.


    << CANDIDATE PROMPTS >>
    lawyer: 咨询法律相关问题时很专业
    sales: 咨询商品信息时很专业
    english teacher: 能够很好地解答英语问题
    poet: 作诗很专业


    << INPUT >>
    {input}


    << OUTPUT >>

    5. 有了router_template后,我们要生成一个PromptTemplate实例,我们可以看到,上面的template中包含一个input作为输入,同时我们需要用到RouterOutputParser作为输出解析器

    1. from langchain.chains.router.llm_router import RouterOutputParser
    2. router_prompt = PromptTemplate(
    3. template=router_template,
    4. input_variables=["input"],
    5. output_parser=RouterOutputParser(),
    6. )

    6. 完成这一步后,我们就可以定义LLMRouterChain了!

    1. from langchain.chains.router.llm_router import LLMRouterChain
    2. from langchain.llms import OpenAI
    3. import os
    4. #创建一个OpenAI作为大语言模型的基底
    5. llm = OpenAI()
    6. os.environ["OPENAI_API_KEY"]="你的key"
    7. router_chain = LLMRouterChain.from_llm(llm, router_prompt)

    上述步骤有一些复杂,但是这是通过大语言模型构建复杂应用的关键步骤,在完成上述步骤后,我们已经有一个RouterChain作为路由链了,只剩下:

    1. 生成各子链

    2. 生成一个default chain作为兜底chain

    2. 用MultiPromptChain将子链和路由链连接

    让我们一步步来:

    1. # 首先,创建一个候选链,包含所有的下游子链
    2. candadite_chains = {}
    3. # 遍历路由目录,生成各子链并放入候选链字典
    4. for p_info in prompt_infos:
    5. name = p_info["name"]
    6. prompt_template = p_info["prompt_template"]
    7. prompt = PromptTemplate(template=prompt_template, input_variables=["input"])
    8. chain = LLMChain(llm=llm, prompt=prompt)
    9. candadite_chains[name] = chain
    10. # 生成默认链
    11. default_chain = ConversationChain(llm=llm, output_key="text")

    MultiPromptChain所必须的三大要素:router_chain, destination_chain 以及 default_chain 都已经准备完毕,最后来组装一下吧!

    1. chain = MultiPromptChain(
    2. router_chain=router_chain,
    3. destination_chains=candadite_chains,
    4. default_chain=default_chain,
    5. verbose=True,
    6. )

    组装完毕,来试一试把!

    print(chain.run("帮我写一首关于春天的诗"))

    四、过程回顾

    回顾一下上面的流程,我们都做了哪些工作?

    1. 创建子链和默认链

    2. 创建路由链,同时路由链的路由模板需要根据子链进行特殊设计

    3. 创建MultiPromptChain,将路由链、默认链和子链组装成一个整体

    五、关于”玩转Langchain“

    "玩转Langchain"是一个Langchain框架和Langchain开发的知识星球,我们将会每周分享关于Langchain的精品内容,欢迎加入我们!

  • 相关阅读:
    微信小程序服务通知(订阅消息)定时推送消息功能
    Java中JCP, JEP, JLS, JSR是什么
    vue3导出表格excel(支持多sheet页),并自定义导出样式
    中国石油大学(北京)-《 完井工程》第三阶段在线作业
    java spring cloud 工程企业管理软件-综合型项目管理软件-工程系统源码
    百叶帘系统内置于玻璃内,分为手动和电动两种控制方式
    Python面向对象,实现图片处理案例,支持:高斯模糊、Canny边缘检测、反转边缘图像、生成手绘效果、调亮度......等等
    Spring Boot是什么
    new CCDIKSolver( OOI.kira, iks ); // 创建逆运动学求解器
    ES6之与Symbol.match
  • 原文地址:https://blog.csdn.net/javastart/article/details/133881916