【笔记】LangChain最关键的构建模块——链Chain

学习资料来源:基于LangChain的大语言模型应用开发4——链_哔哩哔哩_bilibili

链通常将大语言模型与提示词结合在一起。有了链,还可以将一堆这样的构建模块组合在一起,对文本或其他数据按顺序进行操作。

import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read loval .env file

import pandas as pd
df = pd.read_csv('Data.csv') # 加载一些数据

df.head()

这些行中的每一行都是一个不同的数据记录,我们可以开始通过我们的链进行传递。这些链的强大的地方在于,它们可以一次处理多个输入。

(1)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是最基本的链类型,以后会经常用到。

(2)Sequential Chains 顺序链

Sequential chain is another type of chains. The idea is to combine multiple chains where the output of the one chain is the input of the next chain.

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

There is two type of sequential chains:

1. SimpleSequentialChain: Single input/output

2. SequentialChain: multiple inputs/outputs

有两种类型的顺序链:
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)

如果更加复杂的操作呢?

(3)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的时候,就是直接当做一个通用的问题,去问语言模型了。

我们可以尝试将这些链组合在一起,创建有趣的应用。

  • 35
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值