【LangChain学习之旅】—(9) 用SequencialChain链接不同的组件

【LangChain学习之旅】—(9)用SequencialChain链接不同的组件

  • 什么是 Chain
  • LLMChain:最简单的链
  • 链的调用方式
    • 直接调用
    • 通过 run 方法
    • 通过 predict 方法
    • 通过 apply 方法
    • 通过 generate 方法
  • Sequential Chain:顺序链
    • 首先,导入所有需要的库。
    • 然后,添加第一个 LLMChain,生成鲜花的知识性说明。
    • 接着,添加第二个 LLMChain,根据鲜花的知识性说明生成评论。
    • 接着,添加第三个 LLMChain,根据鲜花的介绍和评论写出一篇自媒体的文案。
    • 最后,添加 SequentialChain,把前面三个链串起来。
  • 总结

Reference:LangChain 实战课

在这里插入图片描述

什么是 Chain

对于简单的应用程序来说,直接调用 LLM 就已经足够了。因此,在前几节的示例中,我们主要通过 LangChain 中提供的提示模板、模型接口以及输出解析器就实现了想要的功能。

但是,如果你想开发更复杂的应用程序,那么就需要通过 “Chain” 来链接 LangChain 的各个组件和功能——模型之间彼此链接,或模型与其他组件链接。

这种将多个组件相互链接,组合成一个链的想法简单但很强大。它简化了复杂应用程序的实现,并使之更加模块化,能够创建出单一的、连贯的应用程序,从而使调试、维护和改进应用程序变得容易。

链的实现和使用,也简单。

  • 首先 LangChain 通过设计好的接口,实现一个具体的链的功能。例如,LLM 链(LLMChain)能够接受用户输入,使用 PromptTemplate 对其进行格式化,然后将格式化的响应传递给 LLM。这就相当于把整个 Model I/O 的流程封装到链里面。
  • 实现了链的具体功能之后,我们可以通过将多个链组合在一起,或者将链与其他组件组合来构建更复杂的链。

所以,链在内部把一系列的功能进行封装,而链的外部则又可以组合串联。链其实可以被视为 LangChain 中的一种基本功能单元

LangChain 中提供了很多种类型的预置链,目的是使各种各样的任务实现起来更加方便、规范。

我们先使用一下最基础也是最常见的 LLMChain。

LLMChain:最简单的链

LLMChain 围绕着语言模型推理功能又添加了一些功能,整合了 PromptTemplate、语言模型(LLM 或聊天模型)和 Output Parser,相当于把 Model I/O 放在一个链中整体操作。它使用提示模板格式化输入,将格式化的字符串传递给 LLM,并返回 LLM 输出。

举例来说,如果我想让大模型告诉我某种花的花语,如果不使用链,代码如下:

#----第一步 创建提示
# 导入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 的实现分为两个部分,提示模板的构建和模型的调用独立处理。

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

# 导入所需的库
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)

输出:

{'flower': '玫瑰', 'text': '\n\n爱情、浪漫、美丽、永恒、誓言、坚贞不渝。'}

在这里,我们就把提示模板的构建和模型的调用封装在一起了。

链的调用方式

链有很多种调用方式。

直接调用

刚才我们是直接调用的链对象。当我们像函数一样调用一个对象时,它实际上会调用该对象内部实现的__call__方法。

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

prompt = PromptTemplate(
    input_variables=["flower", "season"],
    template="{flower}在{season}的花语是?",
)
llm_chain = LLMChain(llm=llm, prompt=prompt)
print(llm_chain({
    'flower': "玫瑰",
    'season': "夏季" }))

输出:

{'flower': '玫瑰', 'season': '夏季', 'text': '\n\n玫瑰在夏季的花语是爱的誓言,热情,美丽,坚定的爱情。'}

通过 run 方法

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

语句:llm_chain("玫瑰")等价于:llm_chain.run("玫瑰")

通过 predict 方法

predict 方法类似于 run,只是输入键被指定为关键字参数而不是 Python 字典。

result = llm_chain.predict(flower="玫瑰")
print(result)

通过 apply 方法

apply 方法允许我们针对输入列表运行链,一次处理多个输入。

示例如下:

# apply允许您针对输入列表运行链
input_list = [
    {"flower": "玫瑰",'season': "夏季"},
    {"flower": "百合",'season': "春季"},
    {"flower": "郁金香",'season': "秋季"}
]
result = llm_chain.apply(input_list)
print(result)

输出:

'''[{'text': '\n\n玫瑰在夏季的花语是“恋爱”、“热情”和“浪漫”。'}, 
{'text': '\n\n百合在春季的花语是“爱情”和“友谊”。'},
 {'text': '\n\n郁金香在秋季的花语表达的是“热情”、“思念”、“爱恋”、“回忆”和“持久的爱”。'}]'''

通过 generate 方法

generate 方法类似于 apply,只不过它返回一个 LLMResult 对象,而不是字符串。LLMResult 通常包含模型生成文本过程中的一些相关信息,例如令牌数量、模型名称等。

result = llm_chain.generate(input_list)
print(result)

输出:

generations=[[Generation(text='\n\n玫瑰在夏季的花语是“热情”、“爱情”和“幸福”。', 
generation_info={'finish_reason': 'stop', 'logprobs': None})], 
[Generation(text='\n\n春季的花语是爱情、幸福、美满、坚贞不渝。', 
generation_info={'finish_reason': 'stop', 'logprobs': None})], 
[Generation(text='\n\n秋季的花语是“思念”。银色的百合象征着“真爱”,而淡紫色的郁金香则象征着“思念”,因为它们在秋天里绽放的时候,犹如在思念着夏天的温暖。', 
generation_info={'finish_reason': 'stop', 'logprobs': None})]] 
llm_output={'token_usage': {'completion_tokens': 243, 'total_tokens': 301, 'prompt_tokens': 58}, 'model_name': 'gpt-3.5-turbo-instruct'} 
run=[RunInfo(run_id=UUID('13058cca-881d-4b76-b0cf-0f9c831af6c4')), 
RunInfo(run_id=UUID('7f38e33e-bab5-4d03-b77c-f50cd195affb')), 
RunInfo(run_id=UUID('7a1e45fd-77ee-4133-aab0-431147186db8'))]

Sequential Chain:顺序链

到这里,你已经掌握了最基本的 LLMChain 的用法。下面,我要带着你用 Sequential Chain 把几个 LLMChain 串起来,形成一个顺序链。

这个示例中,我们的目标是这样的:

  1. 第一步,我们假设大模型是一个植物学家,让他给出某种特定鲜花的知识和介绍。
  2. 第二步,我们假设大模型是一个鲜花评论者,让他参考上面植物学家的文字输出,对鲜花进行评论。
  3. 第三步,我们假设大模型是易速鲜花的社交媒体运营经理,让他参考上面植物学家和鲜花评论者的文字输出,来写一篇鲜花运营文案。

下面我们就来一步步地实现这个示例。

首先,导入所有需要的库。

# 设置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,生成鲜花的知识性说明。

# 这是第一个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,根据鲜花的知识性说明生成评论。

# 这是第二个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,根据鲜花的介绍和评论写出一篇自媒体的文案。

# 这是第三个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,把前面三个链串起来。

# 这是总的链,我们按顺序运行这三个链
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)

最终的输出如下:

> Entering new  chain...

> Finished chain.
{'name': '玫瑰', 'color': '黑色', 
'introduction': '\n\n黑色玫瑰,这是一种对传统玫瑰花的独特颠覆,它的出现挑战了我们对玫瑰颜色的固有认知。它的花瓣如煤炭般黑亮,反射出独特的微光,而花蕊则是金黄色的,宛如夜空中的一颗星,强烈的颜色对比营造出一种前所未有的视觉效果。在植物学中,黑色玫瑰的出现无疑提供了一种新的研究方向,对于我们理解花朵色彩形成的机制有着重要的科学价值。', 
'review': '\n\n黑色玫瑰,这不仅仅是一种花朵,更是一种完全颠覆传统的艺术表现形式。黑色的花瓣仿佛在诉说一种不可言喻的悲伤与神秘,而黄色的蕊瓣犹如漆黑夜空中的一抹亮色,给人带来无尽的想象。它将悲伤与欢乐,神秘与明亮完美地结合在一起,这是一种全新的视觉享受,也是一种对生活理解的深度表达。', 
'social_post_text': '\n欢迎来到我们的自媒体平台,今天,我们要向您展示的是我们的全新产品——黑色玫瑰。这不仅仅是一种花,这是一种对传统观念的挑战,一种视觉艺术的革新,更是一种生活态度的象征。
这种别样的玫瑰花,其黑色花瓣宛如漆黑夜空中闪烁的繁星,富有神秘的深度感,给人一种前所未有的视觉冲击力。这种黑色,它不是冷酷、不是绝望,而是充满着独特的魅力和力量。而位于黑色花瓣之中的金黄色花蕊,则犹如星星中的灵魂,默默闪烁,给人带来无尽的遐想,充满活力与生机。
黑色玫瑰的存在,不仅挑战了我们对于玫瑰传统颜色的认知,它更是一种生动的生命象征,象征着那些坚韧、独特、勇敢面对生活的人们。黑色的花瓣中透露出一种坚韧的力量,而金黄的花蕊则是生活中的希望,二者的结合恰好象征了生活中的喜怒哀乐,体现了人生的百态。'}

chatglm3-6b输出结果如下:

{'name': '玫瑰', 'color': '黑色',
 'introduction': '玫瑰是一种常见的花卉,通常被人们视为爱情和浪漫的象征。它的
 颜色可以是红色、粉色、白色、黄色或黑色。在黑色玫瑰中,花色深暗、浓郁,给人以神
 秘和华丽的感觉。\n\n玫瑰的叶子呈长圆形,叶脉明显,叶质厚实。花朵形态多样,有重
 瓣和重叶之分,花瓣排列紧密,呈现出美丽的花型。\n\n玫瑰的香气很浓,可以分为浓
 烈、中等和淡雅三个等级。其中,黑色玫瑰的香气更为独特,混合着辛辣和芳香的气息,
 给人以神秘而舒适的感觉。\n\n黑色玫瑰是一种较为特别的花卉,它的花色和香气都很
 独特,适合作为爱情的象征,送给心爱的人。', 
 'review': '玫瑰,这是一种深受人们喜爱的花卉,象征着爱情与浪漫。它的色彩丰
 富,包括红色、粉色、白色、黄色和黑色,每种颜色都有其独特的寓意。其中,黑色玫
 瑰以其深暗、浓郁的花色,给人以神秘和华丽的感觉,让人无法忽视。\n\n玫瑰的叶子
 长圆形,叶脉明显,厚实的叶质给人一种坚韧而不屈服的印象。花朵形态各异,有重瓣
 和重叶之分,花瓣排列紧密,形成美丽的花型,让人欣赏不禁。\n\n玫瑰的香气浓烈而
 独特,可以分为浓烈、中等和淡雅三个等级。黑色玫瑰的香气更为独特,混合着辛辣和
 芳香的气息,给人以神秘而舒适的感觉,让人无法抗拒。\n\n总的来说,黑色玫瑰是一
 种特别的花卉,其花色和香气都独具特色,适合作为爱情的象征,送给心爱的人。每一
 朵玫瑰花都仿佛在诉说着一个浪漫的故事,让人陶醉其中。',
 'social_post_text': '【神秘华丽,爱情象征——黑色玫瑰的惊艳之美】\n\n玫瑰,
 作为花卉界的情话专家,其独特的外形和浓郁的香气总是让人心动不已。而其中,黑色
 玫瑰更是以其神秘的花色和迷人的香气,成为爱情与浪漫的象征。\n\n黑色玫瑰的花色
 深暗、浓郁,花瓣排列紧密,呈现出独特的美感。它的叶子长圆形,叶脉明显,叶质厚
 实,给人以坚韧而不屈服的印象。当这些玫瑰花被送到心爱的人手中,就仿佛是一份神
 秘而华丽的礼物,让人无法忽视。\n\n此外,黑色玫瑰的香气更为独特,混合着辛辣和
 芳香的气息,给人以神秘而舒适的感觉。这种香气让人无法抗拒,让人想要更深入地了
 解和欣赏这种神秘的花卉。\n\n在花语中,玫瑰花总是代表着爱情和浪漫。而黑色玫瑰
 更是以其独特的外形和香气,成为了一种爱情的象征。每一朵玫瑰花都仿佛在诉说着一
 个浪漫的故事,让人陶醉其中。\n\n如果你也想要一份神秘而华丽的浪漫,那么黑色玫
 瑰或许就是你的不二之选。让我们一起送上一束黑色的玫瑰,表达你的爱意吧!'}

至此,我们就通过两个 LLM 链和一个顺序链,生成了一篇完美的文案。

总结

LangChain 为我们提供了好用的“链”,帮助我们把多个组件像链条一样连接起来。这个“链条”其实就是一系列组件的调用顺序,这个顺序里还可以包括其他的“链条”。

我们可以使用多种方法调用链,也可以根据开发时的需求选择各种不同的链。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/345951.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT+Midjourney+闲鱼赚钱方法实战探索

最近天天在朋友群内看到朋友接单(出售提示词,图片),轻轻松松半小时就赚200-300,特意探索了一下相关玩法,总结出一套ChatGPTMidjourney闲鱼赚钱方法,主打的是易上手,有可操作性! 具体…

9.前端--CSS-三大特性

1.层叠性 相同选择器给设置相同的样式,此时一个样式就会覆盖(层叠)另一个冲突的样式。层叠性主要解决样式冲突的问题 层叠性原则: 样式冲突,遵循的原则是就近原则,哪个样式离结构近,就执行哪个样式样式不…

Vulnhub-dc5

靶场下载 https://download.vulnhub.com/dc/DC-5.zip 信息收集 # nmap -sn 192.168.1.0/24 -oN live.port Starting Nmap 7.94 ( https://nmap.org ) at 2024-01-21 20:56 CST Nmap scan report for 192.168.1.1 (192.168.1.1) Host is up (0.00057s latency). MAC Address:…

Java线程池七大参数详解和配置(面试重点!!!)

一、corePoolSize核心线程数 二、maximunPoolSize最大线程数 三、keepAliveTime空闲线程存活时间 四、unit空闲线程存活时间的单位 五、workQueue线程工作队列 1、ArrayBlockingQueue FIFO有界阻塞队列 2、LinkedBlockingQueue FIFO无限队列 3、PriorityBlockingQueue V…

C4.5决策树的基本建模流程

C4.5决策树的基本建模流程 作为ID3算法的升级版,C4.5在三个方面对ID3进行了优化: (1)它引入了信息值(information value)的概念来修正信息熵的计算结果,以抑制ID3更偏向于选择具有更多分类水平…

算法通关村番外篇-面试150题五

大家好我是苏麟 , 今天带来LeetCode面试题的哈希题目 . 哈希表 202. 快乐数 描述 : 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为: 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为…

Selenium + Django + Echarts 实现亚马逊商品数据可视化爬虫项目

最近完成了1个爬虫项目,记录一下自己的心得。 项目功能简介 根据用户输入商品名称、类别名称,使用Selenium, BS4等技术每天定时抓取亚马逊商品数据,使用Pandas进行数据清洗后保存在MySql数据库中. 使用Django提供用户端功能,显…

Unity中URP下获取主灯信息

文章目录 前言一、计算BulinnPhone的函数有两个重载1、 目前最新使用的是该方法(这是我们之后主要分析的函数)2、 被淘汰的老方法,需要传入一堆数据 二、GetMainLight1、Light结构体2、GetMainLight具有4个方法重载3、1号重载干了什么&#x…

GNSS技术与无人机协同:开启未来交通新篇章

随着科技的不断发展,全球导航卫星系统(GNSS)技术与无人机技术的协同应用成为未来交通系统的引人瞩目的新方向。创新微公司在这一领域的技术创新为实现GNSS技术与无人机的紧密协同提供了新的可能性。本文将深入探讨GNSS技术与无人机协同的前景…

Pytorch中Dataset和dadaloader的理解

不同的数据集在形式上千差万别,为了能够统一用于模型的训练,Pytorch框架下定义了一个dataset类和一个dataloader类。 dataset用于获取数据集中的样本,dataloader 用于抽取部分样本用于训练。比如说一个用于分割任务的图像数据集的结构如图1所…

基于springboot+vue的足球青训俱乐部管理系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 研究背景…

美多商城用户注册-展示用户注册页面-补充短信验证码后端逻辑-避免频发发送-pipeline操作redis-7...

补充短信验证码前后端逻辑 1.补充注册短信验证码后端逻辑 在user中的views中添加添加短信验证码的参数 sms_code_client request.POST.get(sms_code) 保存注册数据之前,对比短信验证码,在views中添加校验 redis_conn get_redis_connection(verify_code…

【C++干货铺】C++异常处理机制

个人主页点击直达:小白不是程序媛 C系列专栏:C干货铺 代码仓库:Gitee 目录 C语言传统的处理错误的方式 C处理异常方式 异常的使用 异常的抛出和捕获 异常的重新抛出 异常安全 异常规范 自定义异常体系 C标准库中的异常体系 ​编辑…

防火墙基础1

防火墙简绍 什么是防火墙? 状态防火墙工作原理? 防火墙如何处理双通道协议? 防火墙如何处理nat? 路由交换终归结底是连通性设备。 网络在远古时期没有防火墙大家都是联通的,any to any。 防御对象: 授权用户 非授权用户 防火墙是一种隔离…

Elment UI的el-table-column表头旁边有点击按钮类似的操作

Elment UI的el-table-column表头旁边有点击按钮类似的操作 <el-table-column fixed"right" label"操作" ><!-- 表头 --> {{-- <template slot"header" header"scope">--}} {{-- <span…

3.jmeter接口关联及实战

1.当所传参数包含键值对和json文件时&#xff0c;键值对放在链接后&#xff0c;参数放在消息体数据中 2.当查看结果树返回乱码时&#xff0c;修改请求中内容编码为utf-8 一、jmeter接口关联 1.正则表达式提取器 接口2.3传递的参数中需要用到接口1的返回值 禁用接口2.3&#…

Kafka(二)原理详解

一 、kafka核心总控制器&#xff08;Controller&#xff09; 在Kafka集群中会有一个或者多个broker&#xff0c;其中有一个broker会被选举为控制器&#xff08;Kafka Controller&#xff09;&#xff0c;它负责管理整个集群中所有分区和副本的状态。 作用&#xff1a;leader副…

Jupyter Notebook安装使用教程

Jupyter Notebook 是一个基于网页的交互式计算环境&#xff0c;允许你创建和共享包含代码、文本说明、图表和可视化结果的文档。它支持多种编程语言&#xff0c;包括 Python、R、Julia 等。其应用场景非常广泛&#xff0c;特别适用于数据科学、机器学习和教育领域。它可以用于数…

动态SQL:MyBatis强大的特性之一

一般来说&#xff0c;一个程序的服务器可以部署多个&#xff0c;但是数据库却只能有一个。这么多服务器&#xff0c;如果每天都要给数据库海量的操作数据&#xff0c;数据库的压力就会非常大。 所以为了减轻数据库的压力&#xff0c;我们可以把一些查询数据库的语句简化&#…

Vulnhub靶机:FunBox 5

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;FunBox 5&#xff08;10.0.2.30&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/funb…
最新文章