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

news2024/11/15 23:32:39

【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.coloradmin.cn/o/1410016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

认识数学建模

文章目录 1 什么是数学建模2 数学建模的比赛形式3 参加数学建模的好处4 数学建模的流程5 数学建模成员分工6 数学建模常用软件7 数学建模竞赛7.1 美国大学生数学建模竞赛7.2 MathorCup高校数学建模挑战赛7.3 华中杯大学生数学建模挑战赛7.4 认证杯数学建模网络挑战赛7.5 华东杯…

【投稿优惠|稳定出版】2024年经济、大数据与区块链国际学术会议(ICEBDB 2024)

【投稿优惠|稳定出版】2024年经济、大数据与区块链国际学术会议(ICEBDB 2024) 重要信息 会议官网:http://www.icebdb.com会议地址:成都召开日期:2024/2/29截稿日期:2024/2/20 (先投稿&#xff0…

MWORKS.Syslab 如何统一 Julia、C/C++、Python 乃至 MATLAB —— 解密多语言统一的底层机制

科学世界蓬勃发展,注入了许多时代特有的活力。年轻理科生们的口中逐渐出现了诸如“调参侠”“调包小子”“炼丹师”等新潮的调侃词语,这些来自机器学习/深度学习领域的“梗”在社交网络中逐渐扩散,让人们不禁感叹科学计算已经成为了炙手可热的…

如何安装MeterSphere并实现无公网ip远程访问服务管理界面

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通…

04 经典的OSPF

思维导图的方式回顾OSPF 什么是OSPF?为什么需要OSPF? - 华为 (huawei.com) 1 ospf 领行学习思维导图 1.1 ospf 的工作过程 建立领据表同步数据库计算路由表1.2 ospf 的状态

gitlab runner 安装、注册、配置、使用(Docker部署)

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

vue3项目中用codemirror实现格式化java代码及不太成熟的历程

本期只介绍创作的曲折历程,并不能解决实际问题,现有插件不支持,总结在了最后 一、案例效果 vue3项目使用preitter 搭配prettier-plugin-java 实现codemirror 格式化 java 二、步骤 1. 安装prettier和prettier-plugin-java,可以…

如何快速解决局域网IP冲突问题?连接IP地址冲突如何用代理IP搞定?

随着互联网的普及,局域网已经成为了许多家庭和企业中不可或缺的一部分。然而,局域网中的IP地址冲突问题却时常困扰着用户。一旦出现IP地址冲突,网络连接就会变得不稳定,甚至无法正常上网。那么,如何快速解决局域网IP冲…

2024 高级前端面试题之 HTML 「精选篇」

该内容主要整理关于 HTML 的相关面试题,其他内容面试题请移步至 「最新最全的前端面试题集锦」 查看。 HTML模块精选篇 1. 如何理解HTML语义化2. H5的新特性有哪些3. 说一下 HTML5 Drag API4. iframe有那些缺点5. 如何实现浏览器内多个标签页之间的通信6. 简述一下s…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM平台编程第二天-ARM汇编(物联技术666)

链接:https://pan.baidu.com/s/1bG0tuVaACATvjLwD05j1FQ?pwd1688 提取码:1688 上午:ARM编程模型 下午:常用ARM指令 教学内容: 1、ARM数据类型 字节(Byte):在ARM体系结构及常见的…

掌握大语言模型技术: 推理优化

掌握大语言模型技术_推理优化 堆叠 Transformer 层来创建大型模型可以带来更好的准确性、少样本学习能力,甚至在各种语言任务上具有接近人类的涌现能力。 这些基础模型的训练成本很高,并且在推理过程中可能会占用大量内存和计算资源(经常性成…

数据结构(队列)

一.什么是队列 1.队列定义 队列是一种特殊的线性表,特殊之处在于他只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。和栈一样,队列也是一种操作受限制的线性表。进行插入操作的一端称为队尾,进行删除操作的…

微服务理解篇

一 :架构演变 1 单体架构: 简单理解为一个服务涵盖所有需求功能2 垂直架构: 按照业务功能将单体架构拆分成小模块服务, 如:订单系统,用户系统,商品系统 ##缺点 引入分布式事务,分布式锁等,优点:模块解耦## 垂直拆分:根据业务层级拆分,比如商城的订单系统,用户系统,商品系统…

搭建属于自己本地的网站

1.关闭selinux 1.1 为什么关闭? 如果selinux不关闭的话,修改ssh端口等策略会不生效, 比如向将ssh端口修改为22011,修改后重启sshd服务,端口未修改,此时需要执行setendforce 0 命令,然后再次重…

leetcode hot100组合

在本题中,是要求返回[1,n]这个数组的长度为k的组合。涉及到排列、组合、棋盘、分割等问题的时候,要考虑利用回溯来进行解决。 回溯和递归类似,也分为三步进行分析 确定递归函数的返回值和参数:一般来说返回值都是void&#xff0c…

【前端web入门第一天】02 HTML图片标签 超链接标签

文章目录: 1.HTML图片标签 1.1 图像标签-基本使用1.2 图像标签-属性1.3 路径 1.3.1 相对路径 1.3.2 绝对路径 2.超链接标签 3.音频标签 4.视频标签 1.HTML图片标签 1.1 图像标签-基本使用 作用:在网页中插入图片。 <img src"图片的URL">src用于指定图像…

【2024】新建mysql数据库,如何选择字符集和排序规则

如何使用 Navicat 新建 MySQL 数据库&#xff0c;并选择字符集与排序规则 如何使用 Navicat 新建 MySQL 数据库并选择字符集与排序规则1. 开始之前2. 新建数据库步骤 1: 打开 Navicat步骤 2: 创建新数据库步骤 3: 填写数据库名称 常见的字符集和排序规则及其选择场景1. 字符集&…

使用__missing__方法实现映射表多格式主键

背景介绍 在python中&#xff0c;我们经常使用字典类型实现映射表的功能&#xff0c;通过字典的主键遍历获取对应的值&#xff0c;从而实现从一个值映射到另一个值的功能 但是这种映射是十分硬性的&#xff0c;例如&#xff0c;假如我的映射表为{‘1’&#xff1a;one&#x…

串口控制器

1. 串口通信 1.1 什么是串口 是一种通信方式&#xff08;通信协议&#xff09; 主要通过串行方式完成设备间的数据通信 通信领域中使用最频繁&#xff0c;实现方式最简单的一种通信方式 串口: 全双工串行异步通信协议 串口3线: RX 接收 TX 发送 GND 共地信号 参考地 …

纳斯达克VS路透社MIFI大屏直投-大舍传媒

纳斯达克VS路透社MIFI大屏直投-大舍传媒 引言 在数字时代的今天&#xff0c;大屏投放成为一种广泛应用的营销手段和传媒方式。纳斯达克大屏和路透社MIFI大屏作为两个重要的投放平台&#xff0c;为企业和机构提供了广告和宣传的机会。 纳斯达克大屏的魅力 纳斯达克大屏位于纽…