chain简介
LangChain 中的 Chain 模块在开发大型语言模型(LLM)驱动的应用程序中起着至关重要的作用。Chain是串联LLM能力与实际业务的关键桥梁,通过将多个工具和模块按逻辑串联起来,实现复杂任务的多步骤流程编排。
案例
通过给小黑黑写演讲稿和口号进行演示。
1.通过小黑黑自我介绍,让大模型撰写演讲稿。
2.通过撰写的演讲稿和小黑黑的自我介绍,再让大模型给小黑黑生成一个口号。
不使用chain的方式(通过观察发现,仅仅两步操作,代码却十分冗余,需要不断地对输入和输出进行接收和封装)
# 不使用chain的形式
from langchain.prompts import PromptTemplate, ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
zhipu_key = 'a66dxxxxxbexxxxxxxxxxxxxxxxxxx31xxxxxHQxxxxzWJo'
model = ChatOpenAI(
temperature=0.01,
model="glm-4-flash",
openai_api_key=zhipu_key,
openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)
people_description = '''
我叫小黑黑,我长的非常黑,喜欢跑步骑车。
'''
# 解析器
str_parser = StrOutputParser()
# 撰写演讲稿提示模版
prompt_poster = "你是一个演讲稿撰写专家,可以为单身的男生撰写相亲活动自我介绍演讲稿,根据<desc>标签里的关于某个男生的自我介绍,给他写一段演讲稿。<desc>{people_description}</desc>"
prompt_poster_template = PromptTemplate.from_template(prompt_poster)
prompt_poster_template_res = prompt_poster_template.invoke({'people_description':people_description})
poster_res = model.invoke(prompt_poster_template_res)
# 模型生成自我介绍
poster_res_str = str_parser.invoke(poster_res)
print('************************第一步:大模型撰写演讲稿**************')
print(poster_res_str)
print('************************第二步:大模型通过演讲稿和自我介绍,撰写口号***************')
prompt_slogn = "你是一个口号撰写专家,可以为参加相亲活动的男生做一个口号撰写,根据<desc>标签里的关于某个男生的自我介绍和<poster>标签里的发言内容,给他写一句活动口号。<desc>{people_description}</desc><poster>{poster}</poster>"
prompt_slogn_template = PromptTemplate.from_template(prompt_slogn)
prompt_slogn_template_res = prompt_slogn_template.invoke({'people_description':people_description, 'poster':poster_res_str})
slogn_res = model.invoke(prompt_slogn_template_res)
slogn_res_str = str_parser.invoke(slogn_res)
print(slogn_res_str)
**********第一步:大模型撰写演讲稿
尊敬的各位来宾,大家好!
今天,我站在这里,带着一颗真诚的心,希望能在这里遇到那个特别的你。我的名字叫小黑黑,听起来可能有点特别,但这也正是我个性的体现。是的,我长得非常黑,但这并不是我的全部,它只是我独特魅力的一个标签。
我热爱生活,喜欢挑战自我。跑步和骑车是我生活中不可或缺的一部分。每当我穿上跑鞋,踏上跑道,或是骑上自行车,穿梭在风景如画的道路上,我都能感受到生命的活力和自由。这些运动不仅让我保持了健康的体魄,也让我学会了坚持和毅力。
我性格开朗,乐观向上。我相信,每个人都有自己的闪光点,而我,就是那个愿意用心去发现和欣赏这些闪光点的人。我期待着与一个同样热爱生活、积极向上的你,一起分享生活的点点滴滴。
在这个相亲的舞台上,我希望能够遇到那个能够理解我、支持我的人。我相信,爱情不仅仅是外表的吸引,更是心灵的契合。我愿意用我的真诚和热情,去温暖你的心房,去守护我们的未来。
最后,我想说,小黑黑,虽然名字听起来有点特别,但我的内心充满了阳光。如果你愿意,就让我们一起,在这美好的时光里,寻找那份属于我们的幸福吧!
谢谢大家!
*********第二步:大模型通过演讲稿和自我介绍,撰写口号
口号:阳光小黑黑,活力跑骑者,携手寻真爱!
使用chain的方式(通过观察发现,chain将单一任务串联了起来,进行了很好的流程性封装,不仅大大简化了代码逻辑,也使得整个流程更加直观和易于管理)
# 使用chain
from operator import itemgetter
from langchain.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain.chains import LLMChain, SequentialChain
zhipu_key = 'axxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxJo'
model = ChatOpenAI(
temperature=0.01,
model="glm-4-flash",
openai_api_key=zhipu_key,
openai_api_base="https://open.bigmodel.cn/api/paas/v4/"
)
people_description = '''
我叫小黑黑,我长的非常黑,喜欢跑步骑车。
'''
# 撰写自我介绍提示模版
prompt_poster = "你是一个演讲稿撰写专家,可以为单身的男生撰写相亲活动自我介绍演讲稿,根据<desc>标签里的关于某个男生的自我介绍,给他写一段演讲稿。<desc>{people_description}</desc>"
chain_one = LLMChain(
llm=model,
prompt=PromptTemplate.from_template(prompt_poster),
output_parser=StrOutputParser(),
output_key='poster'
)
print('**************************第一个chain的输出结果,生成演讲稿************************************')
print(chain_one.invoke({'people_description':people_description}))
# 撰写演讲稿提示模版
prompt_slogn = "你是一个口号撰写专家,可以为参加相亲活动的男生做一个口号撰写,根据<desc>标签里的关于某个男生的自我介绍和<poster>标签里的发言内容,给他写一句活动口号。<desc>{people_description}</desc><poster>{poster}</poster>"
chain_two = LLMChain(
llm=model,
prompt=PromptTemplate.from_template(prompt_slogn),
output_parser=StrOutputParser(),
output_key='slogn'
)
print('**************************串联两条链的输出结果,生成口号************************************')
# 串联两条链
sequential_chain = SequentialChain(
chains=[chain_one, chain_two],
input_variables=['people_description'],
output_variables=['slogn', 'people_description', 'poster']
)
print(sequential_chain.invoke({'people_description':people_description}))
第一个chain的输出结果,生成演讲稿**********
{‘people_description’: ‘\n我叫小黑黑,我长的非常黑,喜欢跑步骑车。\n’, ‘poster’: ‘尊敬的各位来宾,大家好!\n\n今天,我站在这里,带着一颗真诚的心,希望能在这里遇到那个特别的你。我的名字叫小黑黑,听起来可能有点特别,但这也正是我个性的体现。是的,我长得非常黑,但这并不是我的全部,它只是我独特魅力的一个标签。\n\n我热爱生活,喜欢挑战自我。跑步和骑车是我生活中不可或缺的一部分。每当我穿上跑鞋,踏上跑道,或是骑上自行车,穿梭在风景如画的道路上,我都能感受到生命的活力和无限可能。这些运动不仅让我保持了健康的体魄,更让我学会了坚持和毅力。\n\n我性格开朗,乐观向上。我相信,每个人都有自己的闪光点,而我,就是那个愿意用心去发现和欣赏这些闪光点的人。我期待着与一个同样热爱生活、积极向上的你,一起分享生活的点点滴滴。\n\n在这个相亲的舞台上,我希望能够遇到那个能够理解我、支持我的人。我相信,爱情不仅仅是外表的吸引,更是心灵的契合。我愿意用我的真诚和热情,去温暖你的心房,去守护我们的未来。\n\n最后,我想说,小黑黑,虽然名字听起来有点特别,但我的内心充满了阳光。如果你愿意,就让我们一起,在这美好的时光里,寻找那份属于我们的幸福吧!\n\n谢谢大家!’}
串联两条链的输出结果,生成口号**********
{‘people_description’: ‘\n我叫小黑黑,我长的非常黑,喜欢跑步骑车。\n’, ‘slogn’: ‘口号:阳光小黑黑,活力跑骑者,携手寻真爱!’, ‘poster’: ‘尊敬的各位来宾,大家好!\n\n今天,我站在这里,带着一颗真诚的心,希望能在这里遇到那个特别的你。我的名字叫小黑黑,听起来可能有点特别,但这也正是我个性的体现。是的,我长得非常黑,但这并不是我的全部,它只是我独特魅力的一个标签。\n\n我热爱生活,喜欢挑战自我。跑步和骑车是我生活中不可或缺的一部分。每当我穿上跑鞋,踏上跑道,或是骑上自行车,穿梭在风景如画的道路上,我都能感受到生命的活力和无限可能。这些运动不仅让我保持了健康的体魄,更让我学会了坚持和毅力。\n\n我性格开朗,乐观向上。我相信,每个人都有自己的闪光点,而我,就是那个愿意用心去发现和欣赏这些闪光点的人。我期待着与一个同样热爱生活、积极向上的你,一起分享生活的点点滴滴。\n\n在这个相亲的舞台上,我希望能够遇到那个能够理解我、支持我的人。我相信,爱情不仅仅是外表的吸引,更是心灵的契合。我愿意用我的真诚和热情,去温暖你的心房,去守护我们的未来。\n\n最后,我想说,小黑黑,虽然名字听起来有点特别,但我的内心充满了阳光。如果你愿意,就让我们一起,在这美好的时光里,寻找那份属于我们的幸福吧!\n\n谢谢大家!’}
采样LCEL表达式,使用chain的方式(让整个链条更加简洁)
# 使用LCEL表达式
chain_one = (
PromptTemplate.from_template(prompt_poster) | model | {'poster':StrOutputParser(), 'people_description':lambda x:people_description}
)
chain_two = (
PromptTemplate.from_template(prompt_slogn) | model | {'poster':StrOutputParser(key_name='poster'), 'people_description':lambda x:people_description, 'slogn':StrOutputParser()}
)
final_chain = chain_one | chain_two
print(final_chain.invoke({'people_description':people_description}))
{‘poster’: ‘口号:阳光小黑黑,活力跑骑者,携手寻真爱!’, ‘people_description’: ‘\n我叫小黑黑,我长的非常黑,喜欢跑步骑车。\n’, ‘slogn’: ‘口号:阳光小黑黑,活力跑骑者,携手寻真爱!’}