五分鐘了解 LangChain 的路由鏈
上篇文章《5分鐘理透LangChain的Chain》里用到了順序鏈SequentialChain,它可以將多個(gè)鏈按順序串起來。本文介紹LangChain里的另外1個(gè)重要的鏈:路由鏈。

1. 路由鏈概念
路由鏈(RouterChain)是由LLM根據(jù)輸入的Prompt去選擇具體的某個(gè)鏈。路由鏈中一般會(huì)存在多個(gè)Prompt,Prompt結(jié)合LLM決定下一步選擇哪個(gè)鏈。

2. 路由鏈的使用場(chǎng)景
路由鏈一般涉及到2個(gè)核心類,LLMRouterChain和MultiPromptChain,一起看看官網(wǎng)介紹:

- LLMRouterChain:使用LLM路由到可能的選項(xiàng)中。
- MultiPromptChain:該鏈可用于在多個(gè)提示詞之間路由輸入,當(dāng)你有多個(gè)提示詞并且只想路由到其中一個(gè)時(shí),可以用這個(gè)鏈。
一般使用路由鏈時(shí),有固定的幾個(gè)步驟:
- 準(zhǔn)備多個(gè)鏈的Prompt提示詞,然后各自封裝成鏈。
- 將可能路由到的鏈封裝到destination_chains里。
- 構(gòu)建多提示詞和RouterChain ,負(fù)責(zé)選擇下一個(gè)要調(diào)用的鏈。
- 構(gòu)建默認(rèn)鏈。
- 使用MultiPromptChain選擇某個(gè)鏈,然后再去執(zhí)行此鏈。
3. 使用路由鏈的案例
假設(shè)我們有一個(gè)常見的場(chǎng)景,根據(jù)用戶的輸入內(nèi)容選擇不同的處理路徑,如果沒有選到合適的鏈,則使用默認(rèn)鏈。比如:根據(jù)用戶的輸入問題,選擇不同的鏈去處理,如果沒選到合適的,則走默認(rèn)鏈。
具體代碼如下:
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model_name="gpt-3.5-turbo",
openai_api_key="sk-xxxx",
openai_api_base="https://api.302.ai/v1",
)
from langchain.chains.router import LLMRouterChain, MultiPromptChain
from langchain.chains.router.llm_router import RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE
from langchain.chains import LLMChain, ConversationChain
from langchain.prompts import PromptTemplate
# 準(zhǔn)備2條目的鏈:一條物理鏈,一條數(shù)學(xué)鏈
# 1. 物理鏈
physics_template = """
你是一位物理學(xué)家,擅長(zhǎng)回答物理相關(guān)的問題,當(dāng)你不知道問題的答案時(shí),你就回答不知道。
具體問題如下:
{input}
"""
physics_prompt = PromptTemplate.from_template(physics_template)
physics_chain = LLMChain(llm=model, prompt=physics_prompt)
# 2. 數(shù)學(xué)鏈
math_template = """
你是一個(gè)數(shù)學(xué)家,擅長(zhǎng)回答數(shù)學(xué)相關(guān)的問題,當(dāng)你不知道問題的答案時(shí),你就回答不知道。
具體問題如下:
{input}
"""
math_prompt = PromptTemplate.from_template(math_template)
math_chain = LLMChain(llm=model, prompt=math_prompt)
# 3. 英語鏈
english_template = """
你是一個(gè)非常厲害的英語老師,擅長(zhǎng)回答英語相關(guān)的問題,當(dāng)你不知道問題的答案時(shí),你就回答不知道。
具體問題如下:
{input}
"""
english_prompt = PromptTemplate.from_template(english_template)
english_chain = LLMChain(llm=model, prompt=english_prompt)
######### 所有可能的目的鏈
destination_chains = {}
destination_chains["physics"] = physics_chain
destination_chains["math"] = math_chain
destination_chains["english"] = english_chain
######### 默認(rèn)鏈
default_chain = ConversationChain(llm=model, output_key="text")
# 讓多路由模板 能找到合適的 提示詞模板
destinations_template_str = """
physics:擅長(zhǎng)回答物理問題
math:擅長(zhǎng)回答數(shù)學(xué)問題
english:擅長(zhǎng)回答英語問題
"""
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(
destinations=destinations_template_str
)
# 通過路由提示詞模板,構(gòu)建路由提示詞
router_prompt = PromptTemplate(
template=router_template,
input_variables=["input"],
output_parser=RouterOutputParser(),
)
######### 路由鏈
router_chain = LLMRouterChain.from_llm(llm=model, prompt=router_prompt)
######### 最終的鏈
multi_prompt_chain = MultiPromptChain(
router_chain=router_chain,
destination_chains=destination_chains,
default_chain=default_chain,
verbose=True,
)
# multi_prompt_chain.invoke({"input": "重力加速度是多少?"})
# multi_prompt_chain.invoke("y=x^2+2x+1的導(dǎo)數(shù)是多少?")
multi_prompt_chain.invoke("將以下英文翻譯成中文,只輸出中文翻譯結(jié)果:\n The largest community building the future of LLM apps.")
# multi_prompt_chain.invoke("你是怎么理解java的面向?qū)ο蟮乃枷氲模?)執(zhí)行結(jié)果跟我們預(yù)想的一致,執(zhí)行結(jié)果如下:



4. 總結(jié)
這篇博客主要介紹了LangChain中的路由鏈(RouterChain)的概念,它主要用在不確定性的場(chǎng)景下,根據(jù)提示詞,選擇具體的某個(gè)鏈去執(zhí)行。還聊了它的使用場(chǎng)景和具體案例,希望對(duì)你有幫助!
























