问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

LangChain核心构建模块:链(Chain)详解

创作时间:
作者:
@小白创作中心

LangChain核心构建模块:链(Chain)详解

引用
CSDN
1.
https://blog.csdn.net/sharloopSeason/article/details/140251627

链(Chain)是LangChain中一个非常核心的构建模块,它能够将大语言模型与提示词结合在一起,并支持多个构建模块的组合操作。本文将详细介绍三种不同类型的链:LLMChain、Sequential Chains和Router Chain,并通过代码示例展示它们的使用方法。

LLMChain

这是一个简单但非常强大的链,后面介绍的许多链都能够支持。

from langchain.chat_models import ChatOpenAI  # 导入OpenAI模型,LLM
from langchain.prompts import ChatPromptTemplate  # 提示词相关
from langchain.chains import LLMChain  

首先初始化我们的语言模型。我们先用一个比较高的temperature值初始化ChatOpenAI。

llm = ChatOpenAI(temperature=0.9)  

通过初始化提示词模板,接收名为product的变量。要求LLM根据产品名称,为制作该产品的公司取一个最佳的名字。

prompt = ChatPromptTemplate.from_template(
    "What is the best name to describe a company that makes {product}? "
)  

最后,我们把二者结合成为一条链,就是LLM和提示词模板的结合,将提示词模版和LLM按顺序连接起来。

chain = LLMChain(llm = llm, prompt = prompt)  

如果我们有一个名为“双人床床单套装”的产品,我们可以通过使用“chain.run”将它传入链,并运行链。

product = "Queen Size Sheet Set"
chain.run(product)  

它会在后台格式化提示词,并将格式化后的提示词传给LLM。可以看到已经起了一个名字。LLM是最基本的链类型,以后会经常用到。

Sequential Chains(顺序链)

顺序链是另一种类型的链。将多个链组合在一起,其中一个链的输出就是下个链的输入。

有两种类型的顺序链:

  1. SimpleSequentialChain:单个输入/输出
  2. SequentialChain:多个输入/输出

简单顺序链,每条链都有一个输入、一个输出,一条接一条。顺序链,链中的任意环节可以接收多个输入变量。当有复杂的下游链需要和多个上游链组合,会非常有用。顺序链是将一系列链一个一个地运行。

首先,导入顺序链。

from langchain.chains import SimpleSequentialChain  

当我们的子链都只需要一个输入并且只返回一个输出时,这个方法很有用。创建一条链,使用LLM和提示词模板。提示词模版将接受输入一个产品参数,并返回最佳的产品所属公司描述。

llm = ChatOpenAI(temperature=0.9)
# prompt template 1
first_prompt = ChatPromptTemplate.from_template(
    "What is the best name to describe a company that makes {product}? "
)
# chain 1
chain_one = LLMChain(llm=llm, prompt=first_prompt)  

我们创建第二条链。

# prompt template 2
second_prompt = ChatPromptTemplate.from_template(
    "Write a 20 words description for the following company company: {company_name} "
)
# chain 2
chain_two = LLMChain(llm=llm, prompt=second_prompt)  

通过创建一个SimpleSequentialChain,可以很容易实现这些链一条接一条运行的效果。第一条链会输出公司名称,会将它传递给第二条链。

overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two], verbose=True)  

现在可以在任何产品上描述运行这条链了。

overall_simple_chain.run(product)  

简单顺序链(SimpleSequentialChain)在只有一个输入和输出时表现非常好。但当有多个输入或多个输出该怎么办呢?可以使用SequentialChain来实现。

首先导入SequentialChain。

from langchain.chains import SequentialChain  

然后可以创建一系列链,后面我们将一次调用这些链。用第一条链将评论翻译成英语,用第二条链总结这篇评论,用第三条链识别最初的评论是什么语言,用第四条链接收多个输入,即第二条链的摘要及第三条链的语言,要求对摘要进行回复,使用其特定语言。

llm = ChatOpenAI(temperature = 0.9)
# prompt template 1: translate to english
first_prompt = ChatPromptTemplate.from_template(
    "Translate the following review to english:"
    "\n\n{Review}"
)
# chain 1
chain_one = LLMChain(llm=llm, prompt=first_prompt, output_key = "English_Review")
# prompt template 2: summarize the review
second_prompt = ChatPromptTemplate.from_template(
    "Can you summarize the following review in 1 sentence:"
    "\n\n{English_Review}"
)
# chain 2
chain_two = LLMChain(llm=llm, prompt=second_prompt, output_key = "summary")
# prompt template 3: find what language
second_prompt = ChatPromptTemplate.from_template(
    "What language is the following review:\n\n{Review}"
)
# chain 3
chain_three = LLMChain(llm=llm, prompt=third_prompt, output_key = "language")
# prompt template 4: follow up message
second_prompt = ChatPromptTemplate.from_template(
    "Write a follow up response to the following "
    "summary in the specified language:"
    "\n\nSummary: {summary}\n\nLanguage: {language}"
)
# chain 3
chain_three = LLMChain(llm=llm, prompt=third_prompt)
  

关于所有这些子链,需要注意,输入名和输出名要非常精确。如果出现任何错误,一定要检查下变量名是否一致。然后,我们可以轻松地将它们组合在顺序链(SequentialChain)中。

overall_chain = SequentialChain(
    chains=[chain_one, chain_two, chain_three, chain_four],
    input_variables=["Review"],
    output_variables=["English_Review", "summary", "followup_message"],
    verbose = True
)  

我们选择一条评论并传递给整条链,

review = df.Review[5]
overall_chain(review)  

如果更加复杂的操作呢?

Router Chain(路由链)

根据输入内容路由到某条链来处理你的输入。如果有多条子链,每条子链专门负责处理某种特定类型的输入,这种情况下可以使用路由链(Router Chain)。首先判断应该使用哪条子链,然后将输入传递到相应的子链中。我们来看个例子:第一个提示词回答物理问题,第二个提示词回答数学问题,第三个提示词回答历史问题,第四个提示词回答计算机问题。我们可以给每个模版起名字,然后写描述。接下来导入其他需要的链类型。

from langchain.chains.router import MultiPromptChain
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.prompts import PromptTemplate  

MultiPromptChain可以在多个不同提示词模版之间路由。RouterOutputParser可以将LLM输出解析成一个字典,根据字典内容可以在下游确定使用哪条链,以及该链的输入应该是什么。首先导入并定义语言模型。

llm = ChatOpenAI(temperature = 0)  

然后创建目标链。

destination_chains = {}
for p_info in prompt_infos:
    name = p_info["name"]
    prompt_template = p_info["prompt_template"]
    prompt = ChatPromptTemplate.from_template(template = prompt
    chain = LLMChain(llm = llm, prompt = prompt)
    destination_chains[name] = chain
destinations = [f"{p['name']}:{p['description']}" for p in
destinations_str = "\n".join(destinations)  

每个目标链本身就是一个语言模型,即LLMChain。除了目标链,我们还需要一个默认链。默认链是在路由找不到合适的子链调用时,用来备用的一条链路。上述问题中,若与物理、数学、历史或计算机无关,就会调用这条链路。

default_prompt = ChatPromptTemplate.from_template(
default_chain = LLMChain(llm = llm, prompt = default_prompt)  

我们定义一个提示词模版,让LLM根据提示词内容在不同链之间路由。包含了完成任务的说明及输出内容的格式。接下来构建路由链。这个模版适用于许多不同类型的目标。我们从这个模版创阿金提示词,传入LLM和整个路由器提示词,创建路由链。最后,把所有内容汇集,可以创建整条链。

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

接下来就可以向他提问了。

chain.run("What is black body radiation?")  

None的时候,就是直接当做一个通用的问题,去问语言模型了。我们可以尝试将这些链组合在一起,创建有趣的应用。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号