LangChain链功能!

什么是 Chain

如果你想开发更复杂的应用程序,那么就需要通过 Chain 来链接LangChain的各个组件和功能。

模型之间彼此链接,或模型与其他组件链接。

首先LangChain通过设计好的接口,实现一个具体的链的功能。

例如,LLM链(LLMChain)能够接受用户输入,使用 PromptTemplate 对其进行格式化,然后将格式化的响应传递给 LLM。

  • 这就相当于把整个Model I/O的流程封装到链里面。

实现了链的具体功能之后,我们可以通过将多个链组合在一起,或者将链与其他组件组合来构建更复杂的链。

链在内部把一系列的功能进行封装,而链的外部则又可以组合串联。

链其实可以被视为LangChain中的一种基本功能单元。

image-20240815115228093

LLMChain:最简单的链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#----第一步 创建提示
# 导入LangChain中的提示模板
from langchain import PromptTemplate
# 原始字符串模板
template = "{flower}的花语是?"
# 创建LangChain模板
prompt_temp = PromptTemplate.from_template(template)
# 根据模板创建提示
prompt = prompt_temp.format(flower='玫瑰')
# 打印提示的内容
print(prompt)

#----第二步 创建并调用模型
# 导入LangChain中的OpenAI模型接口
from langchain import OpenAI
# 创建模型实例
model = OpenAI(temperature=0)
# 传入提示,调用模型,返回结果
result = model(prompt)
print(result)

此时Model I/O的实现分为两个部分,提示模板的构建和模型的调用独立处理。

如果使用链,代码结构则显得更简洁。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 导入所需的库
from langchain import PromptTemplate, OpenAI, LLMChain
# 原始字符串模板
template = "{flower}的花语是?"
# 创建模型实例
llm = OpenAI(temperature=0)
# 创建LLMChain
llm_chain = LLMChain(
llm=llm,
prompt=PromptTemplate.from_template(template))
# 调用LLMChain,返回结果
result = llm_chain("玫瑰")
print(result)

链的调用方式

直接调用:

如果你的提示模板中包含多个变量,在调用链的时候,可以使用字典一次性输入它们。

1
2
3
4
5
6
7
8
prompt = PromptTemplate(
input_variables=["flower", "season"],
template="{flower}在{season}的花语是?",
)
chain = LLMChain(llm=llm, prompt=prompt)
print(chain({
'flower': "玫瑰",
'season': "夏季" }))

通过run方法:

通过run方法,也等价于直接调用_call_函数。

1
llm_chain("玫瑰")

等价于:

1
llm_chain.run("玫瑰")

Sequential Chain:顺序链

第一步,我们假设大模型是一个植物学家,让他给出某种特定鲜花的知识和介绍。

第二步,我们假设大模型是一个鲜花评论者,让他参考上面植物学家的文字输出,对鲜花进行评论。

第三步,我们假设大模型是易速鲜花的社交媒体运营经理。

  • 让他参考上面植物学家和鲜花评论者的文字输出,来写一篇鲜花运营文案。

导入所有需要的库:

1
2
3
4
5
6
7
8
# 设置OpenAI API密钥
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI API Key'

from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.chains import SequentialChain

添加第一个LLMChain,生成鲜花的知识性说明。

1
2
3
4
5
6
7
8
9
10
# 这是第一个LLMChain,用于生成鲜花的介绍,输入为花的名称和种类
llm = OpenAI(temperature=.7)
template = """
你是一个植物学家。给定花的名称和类型,你需要为这种花写一个200字左右的介绍。

花名: {name}
颜色: {color}
植物学家: 这是关于上述花的介绍:"""
prompt_template = PromptTemplate(input_variables=["name", "color"], template=template)
introduction_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="introduction")

添加第二个LLMChain,根据鲜花的知识性说明生成评论。

1
2
3
4
5
6
7
8
9
10
# 这是第二个LLMChain,用于根据鲜花的介绍写出鲜花的评论
llm = OpenAI(temperature=.7)
template = """
你是一位鲜花评论家。给定一种花的介绍,你需要为这种花写一篇200字左右的评论。

鲜花介绍:
{introduction}
花评人对上述花的评论:"""
prompt_template = PromptTemplate(input_variables=["introduction"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="review")

添加第三个LLMChain,根据鲜花的介绍和评论写出一篇自媒体的文案。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 这是第三个LLMChain,用于根据鲜花的介绍和评论写出一篇自媒体的文案
template = """
你是一家花店的社交媒体经理。给定一种花的介绍和评论,你需要为这种花写一篇社交媒体的帖子,300字左右。

鲜花介绍:
{introduction}
花评人对上述花的评论:
{review}

社交媒体帖子:
"""
prompt_template = PromptTemplate(input_variables=["introduction", "review"], template=template)
social_post_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="social_post_text")

最后,添加SequentialChain,把前面三个链串起来。

1
2
3
4
5
6
7
8
9
10
# 这是总的链,我们按顺序运行这三个链
overall_chain = SequentialChain(
chains=[introduction_chain, review_chain, social_post_chain],
input_variables=["name", "color"],
output_variables=["introduction","review","social_post_text"],
verbose=True)

# 运行链,并打印结果
result = overall_chain({"name":"玫瑰", "color": "黑色"})
print(result)

RouterChain

RouterChain,也叫路由链,能动态选择用于给定输入的下一个链。

我们会根据用户的问题内容,首先使用路由器链确定问题更适合哪个处理模板。

然后将问题发送到该处理模板进行回答。

  • 如果问题不适合任何已定义的处理模板,它会被发送到默认链。

具体步骤如下:

构建处理模板:

  • 为鲜花护理和鲜花装饰分别定义两个字符串模板。

提示信息:

  • 使用一个列表来组织和存储这两个处理模板的关键信息,如模板的键、描述和实际内容。

初始化语言模型:

  • 导入并实例化语言模型。

构建目标链:

  • 根据提示信息中的每个模板构建了对应的LLMChain,并存储在一个字典中。

构建LLM路由链:

  • 这是决策的核心部分。
  • 首先,它根据提示信息构建了一个路由模板,然后使用这个模板创建了一个LLMRouterChain。

构建默认链:

  • 如果输入不适合任何已定义的处理模板,这个默认链会被触发。

构建多提示链:

  • 使用MultiPromptChain将LLM路由链、目标链和默认链组合在一起,形成一个完整的决策系统。

构建提示信息的模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 构建两个场景的模板
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,
}]

初始化语言模型:

1
2
3
4
5
# 初始化语言模型
from langchain.llms import OpenAI
import os
os.environ["OPENAI_API_KEY"] = '你的OpenAI Key'
llm = OpenAI()

构建目标链:

1
2
3
4
5
6
7
8
9
10
# 构建目标链
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"])
print("目标提示:\n",prompt)
chain = LLMChain(llm=llm, prompt=prompt,verbose=True)
chain_map[info["key"]] = chain

目标链提示是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
目标提示:
input_variables=['input']
output_parser=None partial_variables={}
template='你是一个经验丰富的园丁,擅长解答关于养花育花的问题。\n下面是需要你来回答的问题:\n
{input}' template_format='f-string'
validate_template=True

目标提示:
input_variables=['input']
output_parser=None partial_variables={}
template='你是一位网红插花大师,擅长解答关于鲜花装饰的问题。\n 下面是需要你来回答的问题:\n
{input}' template_format='f-string'
validate_template=True

构建路由链:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 构建路由链
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import MULTI_PROMPT_ROUTER_TEMPLATE as RounterTemplate
destinations = [f"{p['key']}: {p['description']}" for p in prompt_infos]
router_template = RounterTemplate.format(destinations="\n".join(destinations))
print("路由模板:\n",router_template)
router_prompt = PromptTemplate(
template=router_template,
input_variables=["input"],
output_parser=RouterOutputParser(),)
print("路由提示:\n",router_prompt)
router_chain = LLMRouterChain.from_llm(llm,
router_prompt,
verbose=True)