学习笔记9《链(下):想学“育花”还是“插花”?用RouterChain确定客户意图》

82 阅读3分钟

任务设定

今天我们要完成的任务是构建一个智能客服ChatBot,它能够根据问题的种类,将问题路由到不同的处理链。具体来说,我们需要处理两类问题:

  1. 鲜花养护(如何浇水、施肥等)
  2. 鲜花装饰(如何搭配花、装饰场地等)

整体框架

我们将使用RouterChain(路由链)来动态选择用于给定输入的下一个链。根据用户的问题内容,RouterChain会确定问题更适合哪个处理模板,然后将问题发送到该处理模板进行回答。如果问题不适合任何已定义的处理模板,它会被发送到默认链。

具体步骤

  1. 构建处理模板:为鲜花护理和鲜花装饰分别定义两个字符串模板。
  2. 提示信息:使用一个列表来组织和存储这两个处理模板的关键信息。
  3. 初始化语言模型:导入并实例化语言模型。
  4. 构建目标链:根据提示信息中的每个模板构建对应的LLMChain,并存储在一个字典中。
  5. 构建LLM路由链:使用LLMRouterChain选择与给定问题最相关的提示。
  6. 构建默认链:如果输入不适合任何已定义的处理模板,这个默认链会被触发。
  7. 构建多提示链:使用MultiPromptChain将LLM路由链、目标链和默认链组合在一起。

具体实现

构建提示信息的模板

flower_care_template = """你是一个经验丰富的园丁,擅长解答关于养花育花的问题。
                        下面是需要你来回答的问题:
                        {input}"""

flower_deco_template = """你是一位网红插花大师,擅长解答关于鲜花装饰的问题。
                        下面是需要你来回答的问题:
                        {input}"""

prompt_infos = [
    {
        "key": "flower_care",
        "description": "适合回答关于鲜花护理的问题",
        "template": flower_care_template,
    },
    {
        "key": "flower_decoration",
        "description": "适合回答关于鲜花装饰的问题",
        "template": flower_deco_template,
    }
]

初始化语言模型

from langchain.llms import OpenAI
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI Key'
llm = OpenAI()

构建目标链

from langchain.chains.llm import LLMChain
from langchain.prompts import PromptTemplate

chain_map = {}
for info in prompt_infos:
    prompt = PromptTemplate(template=info['template'], input_variables=["input"])
    chain = LLMChain(llm=llm, prompt=prompt, verbose=True)
    chain_map[info["key"]] = chain

构建路由链

from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE as RouterTemplate

destinations = [f"{p['key']}: {p['description']}" for p in prompt_infos]
router_template = RouterTemplate.format(destinations="\n".join(destinations))
router_prompt = PromptTemplate(
    template=router_template,
    input_variables=["input"],
    output_parser=RouterOutputParser(),
)
router_chain = LLMRouterChain.from_llm(llm, router_prompt, verbose=True)

构建默认链

from langchain.chains import ConversationChain

default_chain = ConversationChain(llm=llm, output_key="text", verbose=True)

构建多提示链

from langchain.chains.router import MultiPromptChain

chain = MultiPromptChain(
    router_chain=router_chain,
    destination_chains=chain_map,
    default_chain=default_chain,
    verbose=True
)

运行路由链

print(chain.run("如何为玫瑰浇水?"))
print(chain.run("如何为婚礼场地装饰花朵?"))
print(chain.run("如何考入哈佛大学?"))

总结

通过使用RouterChainMultiPromptChain,我们可以将不同的问题路由到不同的处理链,从而实现更复杂的决策逻辑。这种方法可以灵活地扩展,以适应更多种类的问题和处理链。

思考题

  1. 尝试将verbose=True设置为False,观察输出结果的变化。
  2. 尝试将default_chain替换为LLMChain,看看是否能正常工作。

这些题目可以帮助你更深入地理解和实践LangChain中的链功能。